|
From: <sv...@va...> - 2006-01-18 04:25:26
|
Author: sewardj
Date: 2006-01-18 04:25:20 +0000 (Wed, 18 Jan 2006)
New Revision: 5549
Log:
Make VG_(get_StackTrace2) aware of bogus LR values in
replacement/wrapper functions on ppc64-linux, which otherwise mess up
the backtraces.
Modified:
trunk/coregrind/m_libcassert.c
trunk/coregrind/m_stacktrace.c
trunk/coregrind/m_translate.c
trunk/coregrind/pub_core_stacktrace.h
Modified: trunk/coregrind/m_libcassert.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_libcassert.c 2006-01-18 04:23:10 UTC (rev 5548)
+++ trunk/coregrind/m_libcassert.c 2006-01-18 04:25:20 UTC (rev 5549)
@@ -138,7 +138,8 @@
=20
stacktop =3D tst->os_state.valgrind_stack_init_SP;
=20
- VG_(get_StackTrace2)(ips, BACKTRACE_DEPTH, ip, sp, fp, lr, sp, stackt=
op);
+ VG_(get_StackTrace2)(0/*tid is unknown*/,=20
+ ips, BACKTRACE_DEPTH, ip, sp, fp, lr, sp, stackt=
op);
VG_(pp_StackTrace) (ips, BACKTRACE_DEPTH);
=20
// Don't print this, as it's not terribly interesting and avoids a
Modified: trunk/coregrind/m_stacktrace.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_stacktrace.c 2006-01-18 04:23:10 UTC (rev 5548)
+++ trunk/coregrind/m_stacktrace.c 2006-01-18 04:25:20 UTC (rev 5549)
@@ -48,8 +48,13 @@
IPs into 'ips'. In order to be thread-safe, we pass in the
thread's IP SP, FP if that's meaningful, and LR if that's
meaningful. Returns number of IPs put in 'ips'.
+
+ If you know what the thread ID for this stack is, send that as the
+ first parameter, else send zero. This helps generate better stack
+ traces on ppc64-linux and has no effect on other platforms.
*/
-UInt VG_(get_StackTrace2) ( Addr* ips, UInt n_ips,=20
+UInt VG_(get_StackTrace2) ( ThreadId tid_if_known,
+ Addr* ips, UInt n_ips,=20
Addr ip, Addr sp, Addr fp, Addr lr,
Addr fp_min, Addr fp_max_orig )
{
@@ -230,7 +235,7 @@
=20
# elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
=20
- /*--------------------- ppc32 ---------------------*/
+ /*--------------------- ppc32/64 ---------------------*/
=20
/* fp is %r1. ip is %cia. Note, ppc uses r1 as both the stack and
frame pointers. */
@@ -259,7 +264,11 @@
/* on ppc64-linux (ppc64-elf, really), the lr save slot is 2
words back from sp, whereas on ppc32-elf(?) it's only one
word back. */
- const Int lr_offset =3D VG_WORDSIZE=3D=3D8 ? 2 : 1;
+# if defined(VGP_ppc64_linux)
+ const Int lr_offset =3D 2;
+# else
+ const Int lr_offset =3D 1;
+# endif
=20
if (i >=3D n_ips)
break;
@@ -274,6 +283,24 @@
else
ip =3D (((UWord*)fp)[lr_offset]);
=20
+# if defined(VGP_ppc64_linux)
+ /* Nasty hack to do with function replacement/wrapping on
+ ppc64-linux. If LR points to our magic return stub,
+ then we are in a wrapped or intercepted function, in
+ which LR has been messed with. The original LR will
+ have been pushed onto the thread's hidden REDIR stack
+ one down from the top (top element is the saved R2) and
+ so we should restore the value from there instead. */
+ if (i =3D=3D 1=20
+ && ip =3D=3D (Addr)&VG_(ppc64_linux_magic_redirect_retur=
n_stub)
+ && VG_(is_valid_tid)(tid_if_known)) {
+ Long hsp =3D VG_(threads)[tid_if_known].arch.vex.guest_RE=
DIR_SP;
+ if (hsp >=3D 1 && hsp < VEX_GUEST_PPC64_REDIR_STACK_SIZE)
+ ip =3D VG_(threads)[tid_if_known]
+ .arch.vex.guest_REDIR_STACK[hsp-1];
+ }
+# endif
+
fp =3D (((UWord*)fp)[0]);
ips[i++] =3D ip;
if (debug)
@@ -324,7 +351,8 @@
VG_(printf)("tid %d: stack_highest=3D%p ip=3D%p sp=3D%p fp=3D%p\n"=
,
tid, stack_highest_word, ip, sp, fp);
=20
- return VG_(get_StackTrace2)(ips, n_ips, ip, sp, fp, lr, sp, stack_hig=
hest_word);
+ return VG_(get_StackTrace2)(tid, ips, n_ips, ip, sp, fp, lr, sp,=20
+ stack_highest_word);
}
=20
static void printIpDesc(UInt n, Addr ip)
Modified: trunk/coregrind/m_translate.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_translate.c 2006-01-18 04:23:10 UTC (rev 5548)
+++ trunk/coregrind/m_translate.c 2006-01-18 04:25:20 UTC (rev 5549)
@@ -566,6 +566,8 @@
}
=20
=20
+/* --------------- ppc64-linux specific helpers --------------- */
+
#if defined(VGP_ppc64_linux)
static IRExpr* mkU64 ( ULong n )
{
@@ -681,6 +683,7 @@
}
#endif
=20
+/* --------------- END ppc64-linux specific helpers --------------- */
=20
/* This is an the IR preamble generators used for replacement
functions. It adds code to set the guest_NRADDR to zero
@@ -692,7 +695,11 @@
replacement function, and sets LR to point at the magic return-stub
address. Setting LR causes the return of the wrapped/redirected
function to lead to our magic return stub, which restores LR and R2
- from said stack and returns for real. */
+ from said stack and returns for real.
+
+ VG_(get_StackTrace2) understands that the LR value may point to the
+ return stub address, and that in that case it can get the real LR
+ value from the hidden stack instead. */
static=20
Bool mk_preamble__set_NRADDR_to_zero ( void* closureV, IRBB* bb )
{
Modified: trunk/coregrind/pub_core_stacktrace.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/pub_core_stacktrace.h 2006-01-18 04:23:10 UTC (rev 55=
48)
+++ trunk/coregrind/pub_core_stacktrace.h 2006-01-18 04:25:20 UTC (rev 55=
49)
@@ -39,7 +39,12 @@
#include "pub_tool_stacktrace.h"
=20
// Variant that gives a little more control over the stack-walking.
-extern UInt VG_(get_StackTrace2) ( StackTrace ips, UInt n_ips,=20
+// If you know what the thread ID for this stack is, send that
+// as the first parameter, else send zero. This helps generate
+// better stack traces on ppc64-linux and has no effect on other
+// platforms.
+extern UInt VG_(get_StackTrace2) ( ThreadId tid_if_known,
+ StackTrace ips, UInt n_ips,=20
Addr ip, Addr sp, Addr fp, Addr lr,
Addr fp_min, Addr fp_max );
=20
|