]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Make the clone system call wrappers call VG_(register_stack) to record
authorTom Hughes <tom@compton.nu>
Fri, 8 Feb 2008 15:17:07 +0000 (15:17 +0000)
committerTom Hughes <tom@compton.nu>
Fri, 8 Feb 2008 15:17:07 +0000 (15:17 +0000)
the new thread's stack, then make the stack unwinder use that information
to make a better guess at the stack bounds.

This helps avoid crashes trying to unwind the stack under wine when
the starting point is a routine without a proper stack frame.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7383

coregrind/m_stacks.c
coregrind/m_stacktrace.c
coregrind/m_syswrap/syswrap-amd64-linux.c
coregrind/m_syswrap/syswrap-ppc32-linux.c
coregrind/m_syswrap/syswrap-ppc64-linux.c
coregrind/m_syswrap/syswrap-x86-linux.c
coregrind/pub_core_stacks.h

index 90646595ac036fcff66f6937b03e6b86a17089f5..14adead9ca992f168e0f7b8bf19b1701ae2f601a 100644 (file)
@@ -195,6 +195,20 @@ void VG_(change_stack)(UWord id, Addr start, Addr end)
    }
 }
 
+/*
+ * Find the bounds of the stack (if any) which includes the
+ * specified stack pointer.
+ */
+void VG_(stack_limits)(Addr SP, Addr *start, Addr *end )
+{
+   Stack* stack = find_stack_by_addr(SP);
+
+   if (stack) {
+      *start = stack->start;
+      *end = stack->end;
+   }
+}
+
 /* This function gets called if new_mem_stack and/or die_mem_stack are
    tracked by the tool, and one of the specialised cases
    (eg. new_mem_stack_4) isn't used in preference.  
index 3831a700f67f0c738232a38522b5582123142d32..a0bb6ac7b72c9b6b95f8e1f3ed7662b4936bd1ac 100644 (file)
@@ -398,6 +398,7 @@ UInt VG_(get_StackTrace) ( ThreadId tid, StackTrace ips, UInt n_ips,
    Addr sp                 = VG_(get_SP)(tid);
    Addr lr                 = VG_(get_LR)(tid);
    Addr stack_highest_word = VG_(threads)[tid].client_stack_highest_word;
+   Addr stack_lowest_word  = 0;
 
 #  if defined(VGP_x86_linux)
    /* Nasty little hack to deal with syscalls - if libc is using its
@@ -426,6 +427,9 @@ UInt VG_(get_StackTrace) ( ThreadId tid, StackTrace ips, UInt n_ips,
    }
 #  endif
 
+   /* See if we can get a better idea of the stack limits */
+   VG_(stack_limits)(sp, &stack_lowest_word, &stack_highest_word);
+
    /* Take into account the first_ip_delta. */
    vg_assert( sizeof(Addr) == sizeof(Word) );
    ip += first_ip_delta;
index f44dfa615912b12c76a19a35369394c36c069e48..7f96e0fceaacc6262841d923b53f429ec1806adb 100644 (file)
@@ -258,6 +258,8 @@ static SysRes do_clone ( ThreadId ptid,
       ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(rsp);
       ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
 
+      VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
+
       if (debug)
         VG_(printf)("tid %d: guessed client stack range %p-%p\n",
                     ctid, seg->start, VG_PGROUNDUP(rsp));
index 41c3612144e503edff64fdb27d792c843d4a55f4..a166f15e45c6a372c8b81c69eaa69e76d536882c 100644 (file)
@@ -304,6 +304,8 @@ static SysRes do_clone ( ThreadId ptid,
       ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
       ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
 
+      VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
+
       if (debug)
         VG_(printf)("\ntid %d: guessed client stack range %p-%p\n",
                     ctid, seg->start, VG_PGROUNDUP(sp));
index 8a05659a34a7e74253c613de7a387cf4ac4e9db5..3754b14d9960179d82e123d9e706222855199473 100644 (file)
@@ -332,6 +332,8 @@ static SysRes do_clone ( ThreadId ptid,
       ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
       ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
 
+      VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
+
       if (debug)
         VG_(printf)("\ntid %d: guessed client stack range %p-%p\n",
                     ctid, seg->start, VG_PGROUNDUP(sp));
index 6dd5d4b8fb1dabd69735efdf48d9359e6df71ccf..27a9a5d318896e5f51eab05c26b7d5d10f3d1709 100644 (file)
@@ -270,6 +270,8 @@ static SysRes do_clone ( ThreadId ptid,
       ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(esp);
       ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
 
+      VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
+
       if (debug)
         VG_(printf)("tid %d: guessed client stack range %p-%p\n",
                     ctid, seg->start, VG_PGROUNDUP(esp));
index a0083a8626c91f184f2a448ab8542526df3884fb..f7ce29b90c8fccab74301e2950bf58b957798dcb 100644 (file)
@@ -39,6 +39,7 @@
 extern UWord VG_(register_stack)   ( Addr start, Addr end );
 extern void  VG_(deregister_stack) ( UWord id );
 extern void  VG_(change_stack)     ( UWord id, Addr start, Addr end );
+extern void  VG_(stack_limits)     ( Addr SP, Addr *start, Addr *end );
 
 extern VG_REGPARM(2)
        void  VG_(unknown_SP_update) ( Addr old_SP, Addr new_SP );