From: Tom Hughes Date: Fri, 8 Feb 2008 15:17:07 +0000 (+0000) Subject: Make the clone system call wrappers call VG_(register_stack) to record X-Git-Tag: svn/VALGRIND_3_4_0~1085 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2e55cfac698ed9b16c309219c147161cee11dfd5;p=thirdparty%2Fvalgrind.git 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. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7383 --- diff --git a/coregrind/m_stacks.c b/coregrind/m_stacks.c index 90646595ac..14adead9ca 100644 --- a/coregrind/m_stacks.c +++ b/coregrind/m_stacks.c @@ -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. diff --git a/coregrind/m_stacktrace.c b/coregrind/m_stacktrace.c index 3831a700f6..a0bb6ac7b7 100644 --- a/coregrind/m_stacktrace.c +++ b/coregrind/m_stacktrace.c @@ -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; diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index f44dfa6159..7f96e0fcea 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -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)); diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index 41c3612144..a166f15e45 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -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)); diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index 8a05659a34..3754b14d99 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -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)); diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 6dd5d4b8fb..27a9a5d318 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -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)); diff --git a/coregrind/pub_core_stacks.h b/coregrind/pub_core_stacks.h index a0083a8626..f7ce29b90c 100644 --- a/coregrind/pub_core_stacks.h +++ b/coregrind/pub_core_stacks.h @@ -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 );