blob: 86decb5c57f67cfc0617bc5dba4097994106ee9a [file] [log] [blame]
sewardj267100d2005-04-24 12:33:12 +00001
njnd01fef72005-03-25 23:35:48 +00002/*--------------------------------------------------------------------*/
sewardj267100d2005-04-24 12:33:12 +00003/*--- Take snapshots of client stacks. m_stacktrace.c ---*/
njnd01fef72005-03-25 23:35:48 +00004/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
njn9f207462009-03-10 22:02:09 +000010 Copyright (C) 2000-2009 Julian Seward
njnd01fef72005-03-25 23:35:48 +000011 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000032#include "pub_core_vki.h"
njnc7561b92005-06-19 01:24:32 +000033#include "pub_core_threadstate.h"
njn68824432009-02-10 06:48:00 +000034#include "pub_core_debuginfo.h" // XXX: circular dependency
njn24a6efb2005-06-20 03:36:51 +000035#include "pub_core_aspacemgr.h" // For VG_(is_addressable)()
njn97405b22005-06-02 03:39:33 +000036#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000037#include "pub_core_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +000038#include "pub_core_libcprint.h"
njnf536bbb2005-06-13 04:21:38 +000039#include "pub_core_machine.h"
njn20242342005-05-16 23:31:24 +000040#include "pub_core_options.h"
sewardj9084de72008-02-11 11:23:12 +000041#include "pub_core_stacks.h" // VG_(stack_limits)
njnd01fef72005-03-25 23:35:48 +000042#include "pub_core_stacktrace.h"
sewardj14c7cc52007-02-25 15:08:24 +000043#include "pub_core_xarray.h"
sewardja672ea32006-04-29 18:03:14 +000044#include "pub_core_clientstate.h" // VG_(client__dl_sysinfo_int80)
njna7598f62005-06-18 03:27:58 +000045#include "pub_core_trampoline.h"
njnd01fef72005-03-25 23:35:48 +000046
47/*------------------------------------------------------------*/
48/*--- Exported functions. ---*/
49/*------------------------------------------------------------*/
50
sewardjacaec5f2005-08-19 16:02:59 +000051/* Take a snapshot of the client's stack, putting the up to 'n_ips'
52 IPs into 'ips'. In order to be thread-safe, we pass in the
53 thread's IP SP, FP if that's meaningful, and LR if that's
54 meaningful. Returns number of IPs put in 'ips'.
sewardjdfbaa222006-01-18 04:25:20 +000055
56 If you know what the thread ID for this stack is, send that as the
57 first parameter, else send zero. This helps generate better stack
58 traces on ppc64-linux and has no effect on other platforms.
sewardjacaec5f2005-08-19 16:02:59 +000059*/
sewardjb8b79ad2008-03-03 01:35:41 +000060UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
61 /*OUT*/Addr* ips, UInt n_ips,
62 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
63 Addr ip, Addr sp, Addr fp, Addr lr,
64 Addr fp_min, Addr fp_max_orig )
njnd01fef72005-03-25 23:35:48 +000065{
sewardj15338c52006-10-17 01:31:58 +000066# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
67 || defined(VGP_ppc32_aix5) \
68 || defined(VGP_ppc64_aix5)
69 Bool lr_is_first_RA = False;
70# endif
71# if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5) \
72 || defined(VGP_ppc32_aix5)
73 Word redir_stack_size = 0;
74 Word redirs_used = 0;
75# endif
76
sewardjacaec5f2005-08-19 16:02:59 +000077 Bool debug = False;
78 Int i;
79 Addr fp_max;
80 UInt n_found = 0;
njnd01fef72005-03-25 23:35:48 +000081
sewardjacaec5f2005-08-19 16:02:59 +000082 vg_assert(sizeof(Addr) == sizeof(UWord));
83 vg_assert(sizeof(Addr) == sizeof(void*));
njnd01fef72005-03-25 23:35:48 +000084
sewardjacaec5f2005-08-19 16:02:59 +000085 /* Snaffle IPs from the client's stack into ips[0 .. n_ips-1],
njnc0ec8e92005-12-25 06:34:04 +000086 stopping when the trail goes cold, which we guess to be
sewardjacaec5f2005-08-19 16:02:59 +000087 when FP is not a reasonable stack location. */
88
njnd01fef72005-03-25 23:35:48 +000089 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
90 // current page, at least. Dunno if it helps.
91 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
sewardj45f4e7c2005-09-27 19:20:21 +000092 fp_max = VG_PGROUNDUP(fp_max_orig);
sewardjd0c0ea62008-03-03 22:20:51 +000093 if (fp_max >= sizeof(Addr))
94 fp_max -= sizeof(Addr);
njnd01fef72005-03-25 23:35:48 +000095
96 if (debug)
barta0b6b2c2008-07-07 06:49:24 +000097 VG_(printf)("n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
98 "fp_max=0x%lx ip=0x%lx fp=0x%lx\n",
njnd01fef72005-03-25 23:35:48 +000099 n_ips, fp_min, fp_max_orig, fp_max, ip, fp);
100
101 /* Assertion broken before main() is reached in pthreaded programs; the
102 * offending stack traces only have one item. --njn, 2002-aug-16 */
103 /* vg_assert(fp_min <= fp_max);*/
sewardj5bdfbd22007-12-15 22:13:05 +0000104 if (fp_min + 512 >= fp_max) {
105 /* If the stack limits look bogus, don't poke around ... but
106 don't bomb out either. */
sewardj5fa87802008-05-02 22:27:07 +0000107 if (sps) sps[0] = sp;
108 if (fps) fps[0] = fp;
sewardjacaec5f2005-08-19 16:02:59 +0000109 ips[0] = ip;
sewardjacaec5f2005-08-19 16:02:59 +0000110 return 1;
111 }
sewardj35165532005-04-30 18:47:48 +0000112
sewardjacaec5f2005-08-19 16:02:59 +0000113 /* Otherwise unwind the stack in a platform-specific way. Trying
sewardjdb2ac812005-12-23 23:33:51 +0000114 to merge the x86, amd64, ppc32 and ppc64 logic into a single
115 piece of code is just too confusing and difficult to
116 performance-tune. */
njn88b5a982005-05-16 00:16:56 +0000117
sewardj75ea7982005-11-14 15:18:25 +0000118# if defined(VGP_x86_linux)
sewardj35165532005-04-30 18:47:48 +0000119
sewardj75ea7982005-11-14 15:18:25 +0000120 /*--------------------- x86 ---------------------*/
sewardj35165532005-04-30 18:47:48 +0000121
sewardj75ea7982005-11-14 15:18:25 +0000122 /* fp is %ebp. sp is %esp. ip is %eip. */
123
sewardjb8b79ad2008-03-03 01:35:41 +0000124 if (sps) sps[0] = sp;
125 if (fps) fps[0] = fp;
sewardj75ea7982005-11-14 15:18:25 +0000126 ips[0] = ip;
127 i = 1;
128
129 /* Loop unwinding the stack. Note that the IP value we get on
130 * each pass (whether from CFI info or a stack frame) is a
131 * return address so is actually after the calling instruction
132 * in the calling function.
133 *
134 * Because of this we subtract one from the IP after each pass
135 * of the loop so that we find the right CFI block on the next
136 * pass - otherwise we can find the wrong CFI info if it happens
137 * to change after the calling instruction and that will mean
138 * that we will fail to unwind the next step.
139 *
140 * This most frequently happens at the end of a function when
141 * a tail call occurs and we wind up using the CFI info for the
142 * next function which is completely wrong.
143 */
144 while (True) {
145
146 if (i >= n_ips)
147 break;
148
149 /* Try to derive a new (ip,sp,fp) triple from the current
150 set. */
151
152 /* On x86, first try the old-fashioned method of following the
153 %ebp-chain. Code which doesn't use this (that is, compiled
154 with -fomit-frame-pointer) is not ABI compliant and so
155 relatively rare. Besides, trying the CFI first almost always
156 fails, and is expensive. */
157 /* Deal with frames resulting from functions which begin "pushl%
158 ebp ; movl %esp, %ebp" which is the ABI-mandated preamble. */
sewardjf98e1c02008-10-25 16:22:41 +0000159 if (fp_min <= fp && fp <= fp_max
160 - 1 * sizeof(UWord)/*see comment below*/) {
sewardj75ea7982005-11-14 15:18:25 +0000161 /* fp looks sane, so use it. */
162 ip = (((UWord*)fp)[1]);
163 sp = fp + sizeof(Addr) /*saved %ebp*/
164 + sizeof(Addr) /*ra*/;
165 fp = (((UWord*)fp)[0]);
sewardjb8b79ad2008-03-03 01:35:41 +0000166 if (sps) sps[i] = sp;
167 if (fps) fps[i] = fp;
sewardjb1ae15d2008-12-12 13:23:03 +0000168 ips[i++] = ip - 1; /* -1: refer to calling insn, not the RA */
sewardj75ea7982005-11-14 15:18:25 +0000169 if (debug)
dirke4067232007-10-04 21:36:40 +0000170 VG_(printf)(" ipsF[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardjb1ae15d2008-12-12 13:23:03 +0000171 ip = ip - 1; /* as per comment at the head of this loop */
sewardj75ea7982005-11-14 15:18:25 +0000172 continue;
173 }
174
sewardj15338c52006-10-17 01:31:58 +0000175 /* That didn't work out, so see if there is any CF info to hand
sewardj75ea7982005-11-14 15:18:25 +0000176 which can be used. */
sewardjeadcd862006-04-04 15:12:44 +0000177 if ( VG_(use_CF_info)( &ip, &sp, &fp, fp_min, fp_max ) ) {
sewardjb8b79ad2008-03-03 01:35:41 +0000178 if (sps) sps[i] = sp;
179 if (fps) fps[i] = fp;
sewardjb1ae15d2008-12-12 13:23:03 +0000180 ips[i++] = ip - 1; /* -1: refer to calling insn, not the RA */
sewardj75ea7982005-11-14 15:18:25 +0000181 if (debug)
dirke4067232007-10-04 21:36:40 +0000182 VG_(printf)(" ipsC[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardjb1ae15d2008-12-12 13:23:03 +0000183 ip = ip - 1; /* as per comment at the head of this loop */
sewardj75ea7982005-11-14 15:18:25 +0000184 continue;
185 }
186
187 /* No luck. We have to give up. */
188 break;
189 }
190
191# elif defined(VGP_amd64_linux)
192
193 /*--------------------- amd64 ---------------------*/
194
195 /* fp is %rbp. sp is %rsp. ip is %rip. */
sewardj35165532005-04-30 18:47:48 +0000196
sewardjacaec5f2005-08-19 16:02:59 +0000197 ips[0] = ip;
sewardjb8b79ad2008-03-03 01:35:41 +0000198 if (sps) sps[0] = sp;
199 if (fps) fps[0] = fp;
sewardjacaec5f2005-08-19 16:02:59 +0000200 i = 1;
sewardj35165532005-04-30 18:47:48 +0000201
tomac35f102005-11-05 00:17:21 +0000202 /* Loop unwinding the stack. Note that the IP value we get on
203 * each pass (whether from CFI info or a stack frame) is a
204 * return address so is actually after the calling instruction
205 * in the calling function.
206 *
207 * Because of this we subtract one from the IP after each pass
208 * of the loop so that we find the right CFI block on the next
209 * pass - otherwise we can find the wrong CFI info if it happens
210 * to change after the calling instruction and that will mean
211 * that we will fail to unwind the next step.
212 *
213 * This most frequently happens at the end of a function when
214 * a tail call occurs and we wind up using the CFI info for the
215 * next function which is completely wrong.
216 */
sewardjacaec5f2005-08-19 16:02:59 +0000217 while (True) {
sewardj35165532005-04-30 18:47:48 +0000218
sewardjacaec5f2005-08-19 16:02:59 +0000219 if (i >= n_ips)
sewardj35165532005-04-30 18:47:48 +0000220 break;
sewardjacaec5f2005-08-19 16:02:59 +0000221
222 /* Try to derive a new (ip,sp,fp) triple from the current
223 set. */
224
225 /* First off, see if there is any CFI info to hand which can
226 be used. */
sewardjeadcd862006-04-04 15:12:44 +0000227 if ( VG_(use_CF_info)( &ip, &sp, &fp, fp_min, fp_max ) ) {
sewardjb8b79ad2008-03-03 01:35:41 +0000228 if (sps) sps[i] = sp;
229 if (fps) fps[i] = fp;
sewardjb1ae15d2008-12-12 13:23:03 +0000230 ips[i++] = ip - 1; /* -1: refer to calling insn, not the RA */
sewardjacaec5f2005-08-19 16:02:59 +0000231 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000232 VG_(printf)(" ipsC[%d]=%#08lx\n", i-1, ips[i-1]);
sewardjb1ae15d2008-12-12 13:23:03 +0000233 ip = ip - 1; /* as per comment at the head of this loop */
sewardjacaec5f2005-08-19 16:02:59 +0000234 continue;
njnd01fef72005-03-25 23:35:48 +0000235 }
sewardj35165532005-04-30 18:47:48 +0000236
sewardjeadcd862006-04-04 15:12:44 +0000237 /* If VG_(use_CF_info) fails, it won't modify ip/sp/fp, so
sewardjacaec5f2005-08-19 16:02:59 +0000238 we can safely try the old-fashioned method. */
239 /* This bit is supposed to deal with frames resulting from
sewardj75ea7982005-11-14 15:18:25 +0000240 functions which begin "pushq %rbp ; movq %rsp, %rbp".
241 Unfortunately, since we can't (easily) look at the insns at
242 the start of the fn, like GDB does, there's no reliable way
243 to tell. Hence the hack of first trying out CFI, and if that
244 fails, then use this as a fallback. */
sewardjf98e1c02008-10-25 16:22:41 +0000245 /* Note: re "- 1 * sizeof(UWord)", need to take account of the
246 fact that we are prodding at & ((UWord*)fp)[1] and so need to
247 adjust the limit check accordingly. Omitting this has been
248 observed to cause segfaults on rare occasions. */
249 if (fp_min <= fp && fp <= fp_max - 1 * sizeof(UWord)) {
sewardjacaec5f2005-08-19 16:02:59 +0000250 /* fp looks sane, so use it. */
251 ip = (((UWord*)fp)[1]);
sewardj75ea7982005-11-14 15:18:25 +0000252 sp = fp + sizeof(Addr) /*saved %rbp*/
sewardjacaec5f2005-08-19 16:02:59 +0000253 + sizeof(Addr) /*ra*/;
254 fp = (((UWord*)fp)[0]);
sewardjb8b79ad2008-03-03 01:35:41 +0000255 if (sps) sps[i] = sp;
256 if (fps) fps[i] = fp;
sewardjb1ae15d2008-12-12 13:23:03 +0000257 ips[i++] = ip - 1; /* -1: refer to calling insn, not the RA */
sewardjacaec5f2005-08-19 16:02:59 +0000258 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000259 VG_(printf)(" ipsF[%d]=%#08lx\n", i-1, ips[i-1]);
sewardjb1ae15d2008-12-12 13:23:03 +0000260 ip = ip - 1; /* as per comment at the head of this loop */
sewardjacaec5f2005-08-19 16:02:59 +0000261 continue;
262 }
263
sewardj39f34232007-11-09 23:02:28 +0000264 /* Last-ditch hack (evidently GDB does something similar). We
265 are in the middle of nowhere and we have a nonsense value for
266 the frame pointer. If the stack pointer is still valid,
267 assume that what it points at is a return address. Yes,
268 desperate measures. Could do better here:
269 - check that the supposed return address is in
270 an executable page
271 - check that the supposed return address is just after a call insn
272 - given those two checks, don't just consider *sp as the return
273 address; instead scan a likely section of stack (eg sp .. sp+256)
274 and use suitable values found there.
275 */
276 if (fp_min <= sp && sp < fp_max) {
277 ip = ((UWord*)sp)[0];
sewardjb8b79ad2008-03-03 01:35:41 +0000278 if (sps) sps[i] = sp;
279 if (fps) fps[i] = fp;
sewardjb1ae15d2008-12-12 13:23:03 +0000280 ips[i++] = ip == 0
281 ? 0 /* sp[0] == 0 ==> stuck at the bottom of a
282 thread stack */
283 : ip - 1; /* -1: refer to calling insn, not the RA */
sewardj39f34232007-11-09 23:02:28 +0000284 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000285 VG_(printf)(" ipsH[%d]=%#08lx\n", i-1, ips[i-1]);
sewardjb1ae15d2008-12-12 13:23:03 +0000286 ip = ip - 1; /* as per comment at the head of this loop */
sewardj39f34232007-11-09 23:02:28 +0000287 sp += 8;
288 continue;
289 }
290
291 /* No luck at all. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000292 break;
njnd01fef72005-03-25 23:35:48 +0000293 }
sewardjacaec5f2005-08-19 16:02:59 +0000294
sewardj15338c52006-10-17 01:31:58 +0000295# elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
296 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
sewardjacaec5f2005-08-19 16:02:59 +0000297
sewardjdfbaa222006-01-18 04:25:20 +0000298 /*--------------------- ppc32/64 ---------------------*/
sewardj75ea7982005-11-14 15:18:25 +0000299
sewardjacaec5f2005-08-19 16:02:59 +0000300 /* fp is %r1. ip is %cia. Note, ppc uses r1 as both the stack and
301 frame pointers. */
302
sewardj15338c52006-10-17 01:31:58 +0000303# if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
304 redir_stack_size = VEX_GUEST_PPC64_REDIR_STACK_SIZE;
305 redirs_used = 0;
306# elif defined(VGP_ppc32_aix5)
307 redir_stack_size = VEX_GUEST_PPC32_REDIR_STACK_SIZE;
308 redirs_used = 0;
309# endif
310
311# if defined(VG_PLAT_USES_PPCTOC)
sewardjcfb5e2b2006-01-19 03:47:30 +0000312 /* Deal with bogus LR values caused by function
sewardj15338c52006-10-17 01:31:58 +0000313 interception/wrapping on ppc-TOC platforms; see comment on
314 similar code a few lines further down. */
315 if (ULong_to_Ptr(lr) == (void*)&VG_(ppctoc_magic_redirect_return_stub)
sewardjcfb5e2b2006-01-19 03:47:30 +0000316 && VG_(is_valid_tid)(tid_if_known)) {
sewardj15338c52006-10-17 01:31:58 +0000317 Word hsp = VG_(threads)[tid_if_known].arch.vex.guest_REDIR_SP;
318 redirs_used++;
319 if (hsp >= 1 && hsp < redir_stack_size)
sewardjcfb5e2b2006-01-19 03:47:30 +0000320 lr = VG_(threads)[tid_if_known]
321 .arch.vex.guest_REDIR_STACK[hsp-1];
322 }
323# endif
324
sewardj15338c52006-10-17 01:31:58 +0000325 /* We have to determine whether or not LR currently holds this fn
326 (call it F)'s return address. It might not if F has previously
327 called some other function, hence overwriting LR with a pointer
328 to some part of F. Hence if LR and IP point to the same
329 function then we conclude LR does not hold this function's
330 return address; instead the LR at entry must have been saved in
331 the stack by F's prologue and so we must get it from there
332 instead. Note all this guff only applies to the innermost
333 frame. */
sewardjacaec5f2005-08-19 16:02:59 +0000334 lr_is_first_RA = False;
335 {
336# define M_VG_ERRTXT 1000
337 UChar buf_lr[M_VG_ERRTXT], buf_ip[M_VG_ERRTXT];
sewardjb1ae15d2008-12-12 13:23:03 +0000338 /* The following conditional looks grossly inefficient and
339 surely could be majorly improved, with not much effort. */
njn6b7611b2009-02-11 06:06:10 +0000340 if (VG_(get_fnname_raw) (lr, buf_lr, M_VG_ERRTXT))
341 if (VG_(get_fnname_raw) (ip, buf_ip, M_VG_ERRTXT))
sewardjacaec5f2005-08-19 16:02:59 +0000342 if (VG_(strncmp)(buf_lr, buf_ip, M_VG_ERRTXT))
343 lr_is_first_RA = True;
344# undef M_VG_ERRTXT
345 }
346
sewardjb8b79ad2008-03-03 01:35:41 +0000347 if (sps) sps[0] = fp; /* NB. not sp */
348 if (fps) fps[0] = fp;
sewardjacaec5f2005-08-19 16:02:59 +0000349 ips[0] = ip;
350 i = 1;
sewardjacaec5f2005-08-19 16:02:59 +0000351
sewardjdb2ac812005-12-23 23:33:51 +0000352 if (fp_min <= fp && fp < fp_max-VG_WORDSIZE+1) {
sewardjacaec5f2005-08-19 16:02:59 +0000353
sewardj525e2322005-11-13 02:41:35 +0000354 /* initial FP is sane; keep going */
355 fp = (((UWord*)fp)[0]);
356
357 while (True) {
358
sewardj15338c52006-10-17 01:31:58 +0000359 /* On ppc64-linux (ppc64-elf, really), and on AIX, the lr save
360 slot is 2 words back from sp, whereas on ppc32-elf(?) it's
361 only one word back. */
362# if defined(VGP_ppc64_linux) \
363 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
sewardjdfbaa222006-01-18 04:25:20 +0000364 const Int lr_offset = 2;
365# else
366 const Int lr_offset = 1;
367# endif
sewardjdb2ac812005-12-23 23:33:51 +0000368
sewardj525e2322005-11-13 02:41:35 +0000369 if (i >= n_ips)
370 break;
371
372 /* Try to derive a new (ip,fp) pair from the current set. */
373
sewardjf98e1c02008-10-25 16:22:41 +0000374 if (fp_min <= fp && fp <= fp_max - lr_offset * sizeof(UWord)) {
sewardj525e2322005-11-13 02:41:35 +0000375 /* fp looks sane, so use it. */
376
377 if (i == 1 && lr_is_first_RA)
378 ip = lr;
379 else
sewardjdb2ac812005-12-23 23:33:51 +0000380 ip = (((UWord*)fp)[lr_offset]);
sewardj525e2322005-11-13 02:41:35 +0000381
sewardj15338c52006-10-17 01:31:58 +0000382# if defined(VG_PLAT_USES_PPCTOC)
sewardjdfbaa222006-01-18 04:25:20 +0000383 /* Nasty hack to do with function replacement/wrapping on
sewardj15338c52006-10-17 01:31:58 +0000384 ppc64-linux/ppc64-aix/ppc32-aix. If LR points to our
385 magic return stub, then we are in a wrapped or
386 intercepted function, in which LR has been messed with.
387 The original LR will have been pushed onto the thread's
388 hidden REDIR stack one down from the top (top element
389 is the saved R2) and so we should restore the value
390 from there instead. Since nested redirections can and
391 do happen, we keep track of the number of nested LRs
392 used by the unwinding so far with 'redirs_used'. */
393 if (ip == (Addr)&VG_(ppctoc_magic_redirect_return_stub)
sewardjdfbaa222006-01-18 04:25:20 +0000394 && VG_(is_valid_tid)(tid_if_known)) {
sewardjb8b79ad2008-03-03 01:35:41 +0000395 Word hsp = VG_(threads)[tid_if_known]
396 .arch.vex.guest_REDIR_SP;
sewardj15338c52006-10-17 01:31:58 +0000397 hsp -= 2 * redirs_used;
398 redirs_used ++;
399 if (hsp >= 1 && hsp < redir_stack_size)
sewardjdfbaa222006-01-18 04:25:20 +0000400 ip = VG_(threads)[tid_if_known]
401 .arch.vex.guest_REDIR_STACK[hsp-1];
402 }
403# endif
404
sewardj525e2322005-11-13 02:41:35 +0000405 fp = (((UWord*)fp)[0]);
sewardjb8b79ad2008-03-03 01:35:41 +0000406 if (sps) sps[i] = fp; /* NB. not sp */
407 if (fps) fps[i] = fp;
sewardjb1ae15d2008-12-12 13:23:03 +0000408 ips[i++] = ip - 1; /* -1: refer to calling insn, not the RA */
sewardj525e2322005-11-13 02:41:35 +0000409 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000410 VG_(printf)(" ipsF[%d]=%#08lx\n", i-1, ips[i-1]);
sewardjb1ae15d2008-12-12 13:23:03 +0000411 ip = ip - 1; /* ip is probably dead at this point, but
412 play safe, a la x86/amd64 above. See
413 extensive comments above. */
sewardj525e2322005-11-13 02:41:35 +0000414 continue;
415 }
416
417 /* No luck there. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000418 break;
sewardjacaec5f2005-08-19 16:02:59 +0000419 }
sewardjacaec5f2005-08-19 16:02:59 +0000420 }
421
422# else
423# error "Unknown platform"
424# endif
425
njnd01fef72005-03-25 23:35:48 +0000426 n_found = i;
njnd01fef72005-03-25 23:35:48 +0000427 return n_found;
428}
429
sewardjb8b79ad2008-03-03 01:35:41 +0000430UInt VG_(get_StackTrace) ( ThreadId tid,
431 /*OUT*/StackTrace ips, UInt n_ips,
432 /*OUT*/StackTrace sps,
433 /*OUT*/StackTrace fps,
sewardj39f34232007-11-09 23:02:28 +0000434 Word first_ip_delta )
njnd01fef72005-03-25 23:35:48 +0000435{
436 /* thread in thread table */
njnf536bbb2005-06-13 04:21:38 +0000437 Addr ip = VG_(get_IP)(tid);
438 Addr fp = VG_(get_FP)(tid);
439 Addr sp = VG_(get_SP)(tid);
sewardjacaec5f2005-08-19 16:02:59 +0000440 Addr lr = VG_(get_LR)(tid);
njnf536bbb2005-06-13 04:21:38 +0000441 Addr stack_highest_word = VG_(threads)[tid].client_stack_highest_word;
tom690c3c82008-02-08 15:17:07 +0000442 Addr stack_lowest_word = 0;
njnd01fef72005-03-25 23:35:48 +0000443
sewardjb9bce632005-06-21 01:41:34 +0000444# if defined(VGP_x86_linux)
sewardja672ea32006-04-29 18:03:14 +0000445 /* Nasty little hack to deal with syscalls - if libc is using its
446 _dl_sysinfo_int80 function for syscalls (the TLS version does),
447 then ip will always appear to be in that function when doing a
448 syscall, not the actual libc function doing the syscall. This
449 check sees if IP is within that function, and pops the return
450 address off the stack so that ip is placed within the library
451 function calling the syscall. This makes stack backtraces much
452 more useful.
453
454 The function is assumed to look like this (from glibc-2.3.6 sources):
455 _dl_sysinfo_int80:
456 int $0x80
457 ret
458 That is 3 (2+1) bytes long. We could be more thorough and check
459 the 3 bytes of the function are as expected, but I can't be
460 bothered.
461 */
462 if (VG_(client__dl_sysinfo_int80) != 0 /* we know its address */
463 && ip >= VG_(client__dl_sysinfo_int80)
464 && ip < VG_(client__dl_sysinfo_int80)+3
sewardj45f4e7c2005-09-27 19:20:21 +0000465 && VG_(am_is_valid_for_client)(sp, sizeof(Addr), VKI_PROT_READ)) {
njnd01fef72005-03-25 23:35:48 +0000466 ip = *(Addr *)sp;
467 sp += sizeof(Addr);
468 }
sewardjb9bce632005-06-21 01:41:34 +0000469# endif
470
tom690c3c82008-02-08 15:17:07 +0000471 /* See if we can get a better idea of the stack limits */
472 VG_(stack_limits)(sp, &stack_lowest_word, &stack_highest_word);
473
sewardj39f34232007-11-09 23:02:28 +0000474 /* Take into account the first_ip_delta. */
475 vg_assert( sizeof(Addr) == sizeof(Word) );
476 ip += first_ip_delta;
477
njnd01fef72005-03-25 23:35:48 +0000478 if (0)
sewardjb8b79ad2008-03-03 01:35:41 +0000479 VG_(printf)("tid %d: stack_highest=0x%08lx ip=0x%08lx "
480 "sp=0x%08lx fp=0x%08lx\n",
njnd01fef72005-03-25 23:35:48 +0000481 tid, stack_highest_word, ip, sp, fp);
482
sewardjb8b79ad2008-03-03 01:35:41 +0000483 return VG_(get_StackTrace_wrk)(tid, ips, n_ips,
484 sps, fps,
485 ip, sp, fp, lr, sp,
486 stack_highest_word);
njnd01fef72005-03-25 23:35:48 +0000487}
488
489static void printIpDesc(UInt n, Addr ip)
490{
njn83f9e792005-06-11 05:04:09 +0000491 #define BUF_LEN 4096
492
493 static UChar buf[BUF_LEN];
njnd01fef72005-03-25 23:35:48 +0000494
njn83f9e792005-06-11 05:04:09 +0000495 VG_(describe_IP)(ip, buf, BUF_LEN);
sewardj71bc3cb2005-05-19 00:25:45 +0000496
497 if (VG_(clo_xml)) {
498 VG_(message)(Vg_UserMsg, " %s", buf);
499 } else {
500 VG_(message)(Vg_UserMsg, " %s %s", ( n == 0 ? "at" : "by" ), buf);
501 }
njnd01fef72005-03-25 23:35:48 +0000502}
503
504/* Print a StackTrace. */
505void VG_(pp_StackTrace) ( StackTrace ips, UInt n_ips )
506{
507 vg_assert( n_ips > 0 );
sewardj71bc3cb2005-05-19 00:25:45 +0000508
509 if (VG_(clo_xml))
510 VG_(message)(Vg_UserMsg, " <stack>");
511
njnd01fef72005-03-25 23:35:48 +0000512 VG_(apply_StackTrace)( printIpDesc, ips, n_ips );
sewardj71bc3cb2005-05-19 00:25:45 +0000513
514 if (VG_(clo_xml))
515 VG_(message)(Vg_UserMsg, " </stack>");
njnd01fef72005-03-25 23:35:48 +0000516}
517
518/* Get and immediately print a StackTrace. */
519void VG_(get_and_pp_StackTrace) ( ThreadId tid, UInt n_ips )
520{
521 Addr ips[n_ips];
sewardjb8b79ad2008-03-03 01:35:41 +0000522 UInt n_ips_obtained
523 = VG_(get_StackTrace)(tid, ips, n_ips,
524 NULL/*array to dump SP values in*/,
525 NULL/*array to dump FP values in*/,
526 0/*first_ip_delta*/);
njn88d3ba82006-08-13 04:48:25 +0000527 VG_(pp_StackTrace)(ips, n_ips_obtained);
njnd01fef72005-03-25 23:35:48 +0000528}
529
530
531void VG_(apply_StackTrace)( void(*action)(UInt n, Addr ip),
532 StackTrace ips, UInt n_ips )
533{
njnd01fef72005-03-25 23:35:48 +0000534 Bool main_done = False;
njnd01fef72005-03-25 23:35:48 +0000535 Int i = 0;
536
537 vg_assert(n_ips > 0);
538 do {
539 Addr ip = ips[i];
njnd01fef72005-03-25 23:35:48 +0000540
sewardj73cf4c62005-11-17 15:12:34 +0000541 // Stop after the first appearance of "main" or one of the other names
542 // (the appearance of which is a pretty good sign that we've gone past
543 // main without seeing it, for whatever reason)
njn68824432009-02-10 06:48:00 +0000544 if ( ! VG_(clo_show_below_main) ) {
545 Vg_FnNameKind kind = VG_(get_fnname_kind_from_IP)(ip);
546 if (Vg_FnNameMain == kind || Vg_FnNameBelowMain == kind) {
njnd01fef72005-03-25 23:35:48 +0000547 main_done = True;
njn68824432009-02-10 06:48:00 +0000548 }
njnd01fef72005-03-25 23:35:48 +0000549 }
550
551 // Act on the ip
552 action(i, ip);
553
554 i++;
sewardjd68d3cf2009-01-24 00:07:53 +0000555 // re 'while' condition: stop if we hit a zero value (the traditional
556 // end-of-stack marker) or a ~0 value. The latter because r8818
557 // (in this file) changes the meaning of entries [1] and above in a
558 // stack trace, by subtracting 1 from them. Hence stacks that used
559 // to end with a zero value now end in -1 and so we must detect
560 // that too.
561 } while (i < n_ips && ips[i] != 0 && ips[i] != ~(Addr)0 && !main_done);
njnd01fef72005-03-25 23:35:48 +0000562
563 #undef MYBUF_LEN
564}
565
566
567/*--------------------------------------------------------------------*/
njn24a6efb2005-06-20 03:36:51 +0000568/*--- end ---*/
njnd01fef72005-03-25 23:35:48 +0000569/*--------------------------------------------------------------------*/