From: Florian Krohm Date: Tue, 14 Apr 2015 19:59:21 +0000 (+0000) Subject: Followup to r14974. That revision oversimplified a condition, part X-Git-Tag: svn/VALGRIND_3_11_0~505 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fce9b1644b65076423a1e0b45e95ac9571b0c6db;p=thirdparty%2Fvalgrind.git Followup to r14974. That revision oversimplified a condition, part of which was presumed to be redundant but wasn't. This caused code to hang due to an infinite signal-delivery loop. Observed and tracked down by Austin English. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15091 --- diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c index e27a61bbf9..484c9ae27c 100644 --- a/coregrind/m_signals.c +++ b/coregrind/m_signals.c @@ -2427,7 +2427,7 @@ static Bool extend_stack_if_appropriate(ThreadId tid, vki_siginfo_t* info) { Addr fault; Addr esp; - NSegment const* seg; + NSegment const *seg, *seg_next; if (info->si_signo != VKI_SIGSEGV) return False; @@ -2435,6 +2435,8 @@ static Bool extend_stack_if_appropriate(ThreadId tid, vki_siginfo_t* info) fault = (Addr)info->VKI_SIGINFO_si_addr; esp = VG_(get_SP)(tid); seg = VG_(am_find_nsegment)(fault); + seg_next = seg ? VG_(am_next_nsegment)( seg, True/*fwds*/ ) + : NULL; if (VG_(clo_trace_signals)) { if (seg == NULL) @@ -2449,6 +2451,10 @@ static Bool extend_stack_if_appropriate(ThreadId tid, vki_siginfo_t* info) if (info->si_code == VKI_SEGV_MAPERR && seg + && seg->kind == SkResvn + && seg->smode == SmUpper + && seg_next + && seg_next->kind == SkAnonC && fault >= fault_mask(esp - VG_STACK_REDZONE_SZB)) { /* If the fault address is above esp but below the current known stack segment base, and it was a fault because there was diff --git a/none/tests/x86-linux/Makefile.am b/none/tests/x86-linux/Makefile.am index 22b15c50f9..8592f1d72a 100644 --- a/none/tests/x86-linux/Makefile.am +++ b/none/tests/x86-linux/Makefile.am @@ -5,10 +5,12 @@ dist_noinst_SCRIPTS = \ filter_stderr EXTRA_DIST = \ + hang.stderr.exp hang.vgtest \ seg_override.stderr.exp seg_override.stdout.exp seg_override.vgtest \ sigcontext.stdout.exp sigcontext.stderr.exp sigcontext.vgtest check_PROGRAMS = \ + hang \ seg_override \ sigcontext diff --git a/none/tests/x86-linux/hang.c b/none/tests/x86-linux/hang.c new file mode 100644 index 0000000000..2d0ff79c2d --- /dev/null +++ b/none/tests/x86-linux/hang.c @@ -0,0 +1,5 @@ +int main ( void ) +{ + *(volatile char *)0xDEADBEEF = 'x'; + return 0; +} diff --git a/none/tests/x86-linux/hang.stderr.exp b/none/tests/x86-linux/hang.stderr.exp new file mode 100644 index 0000000000..3fafbc97ba --- /dev/null +++ b/none/tests/x86-linux/hang.stderr.exp @@ -0,0 +1,9 @@ + +Process terminating with default action of signal 11 (SIGSEGV) + Access not within mapped region at address 0x........ + at 0x........: main (hang.c:3) + If you believe this happened as a result of a stack + overflow in your program's main thread (unlikely but + possible), you can try to increase the size of the + main thread stack using the --main-stacksize= flag. + The main thread stack size used in this run was .... diff --git a/none/tests/x86-linux/hang.vgtest b/none/tests/x86-linux/hang.vgtest new file mode 100644 index 0000000000..c3678bbf5e --- /dev/null +++ b/none/tests/x86-linux/hang.vgtest @@ -0,0 +1,5 @@ +# r14974 introduced a bug which cause code to hang due to +# an infinite signal-delivery loop. +# Can only be reproduced on an x86 box running a 32-bit kernel. +prog: hang +vgopts: -q