|
From: <sv...@va...> - 2008-02-08 15:17:20
|
Author: tom
Date: 2008-02-08 15:17:07 +0000 (Fri, 08 Feb 2008)
New Revision: 7383
Log:
Make the clone system call wrappers call VG_(register_stack) to record
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.
Modified:
trunk/coregrind/m_stacks.c
trunk/coregrind/m_stacktrace.c
trunk/coregrind/m_syswrap/syswrap-amd64-linux.c
trunk/coregrind/m_syswrap/syswrap-ppc32-linux.c
trunk/coregrind/m_syswrap/syswrap-ppc64-linux.c
trunk/coregrind/m_syswrap/syswrap-x86-linux.c
trunk/coregrind/pub_core_stacks.h
Modified: trunk/coregrind/m_stacks.c
===================================================================
--- trunk/coregrind/m_stacks.c 2008-02-08 00:37:18 UTC (rev 7382)
+++ trunk/coregrind/m_stacks.c 2008-02-08 15:17:07 UTC (rev 7383)
@@ -195,6 +195,20 @@
}
}
+/*
+ * 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.
Modified: trunk/coregrind/m_stacktrace.c
===================================================================
--- trunk/coregrind/m_stacktrace.c 2008-02-08 00:37:18 UTC (rev 7382)
+++ trunk/coregrind/m_stacktrace.c 2008-02-08 15:17:07 UTC (rev 7383)
@@ -398,6 +398,7 @@
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 @@
}
# 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;
Modified: trunk/coregrind/m_syswrap/syswrap-amd64-linux.c
===================================================================
--- trunk/coregrind/m_syswrap/syswrap-amd64-linux.c 2008-02-08 00:37:18 UTC (rev 7382)
+++ trunk/coregrind/m_syswrap/syswrap-amd64-linux.c 2008-02-08 15:17:07 UTC (rev 7383)
@@ -258,6 +258,8 @@
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));
Modified: trunk/coregrind/m_syswrap/syswrap-ppc32-linux.c
===================================================================
--- trunk/coregrind/m_syswrap/syswrap-ppc32-linux.c 2008-02-08 00:37:18 UTC (rev 7382)
+++ trunk/coregrind/m_syswrap/syswrap-ppc32-linux.c 2008-02-08 15:17:07 UTC (rev 7383)
@@ -304,6 +304,8 @@
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));
Modified: trunk/coregrind/m_syswrap/syswrap-ppc64-linux.c
===================================================================
--- trunk/coregrind/m_syswrap/syswrap-ppc64-linux.c 2008-02-08 00:37:18 UTC (rev 7382)
+++ trunk/coregrind/m_syswrap/syswrap-ppc64-linux.c 2008-02-08 15:17:07 UTC (rev 7383)
@@ -332,6 +332,8 @@
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));
Modified: trunk/coregrind/m_syswrap/syswrap-x86-linux.c
===================================================================
--- trunk/coregrind/m_syswrap/syswrap-x86-linux.c 2008-02-08 00:37:18 UTC (rev 7382)
+++ trunk/coregrind/m_syswrap/syswrap-x86-linux.c 2008-02-08 15:17:07 UTC (rev 7383)
@@ -270,6 +270,8 @@
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));
Modified: trunk/coregrind/pub_core_stacks.h
===================================================================
--- trunk/coregrind/pub_core_stacks.h 2008-02-08 00:37:18 UTC (rev 7382)
+++ trunk/coregrind/pub_core_stacks.h 2008-02-08 15:17:07 UTC (rev 7383)
@@ -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 );
|