]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Followup to r14974. That revision oversimplified a condition, part
authorFlorian Krohm <florian@eich-krohm.de>
Tue, 14 Apr 2015 19:59:21 +0000 (19:59 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Tue, 14 Apr 2015 19:59:21 +0000 (19:59 +0000)
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

coregrind/m_signals.c
none/tests/x86-linux/Makefile.am
none/tests/x86-linux/hang.c [new file with mode: 0644]
none/tests/x86-linux/hang.stderr.exp [new file with mode: 0644]
none/tests/x86-linux/hang.vgtest [new file with mode: 0644]

index e27a61bbf90889542f269c076309f10ba941876d..484c9ae27cb17c1571ad857ed8b2bda1605889b1 100644 (file)
@@ -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
index 22b15c50f9106a9a00d8642ccf7d62e048fd5f1b..8592f1d72a86d45354be4c1861dd9476d43e3a8b 100644 (file)
@@ -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 (file)
index 0000000..2d0ff79
--- /dev/null
@@ -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 (file)
index 0000000..3fafbc9
--- /dev/null
@@ -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 (file)
index 0000000..c3678bb
--- /dev/null
@@ -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