blob: 1c474a5d330d3f76781408f9ca803bdb20e2b2fe [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
sewardj9ebd6e02007-01-08 06:01:59 +000010 Copyright (C) 2000-2007 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"
njn88c51482005-06-25 20:49:33 +000034#include "pub_core_debuginfo.h"
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"
njnd01fef72005-03-25 23:35:48 +000041#include "pub_core_stacktrace.h"
sewardj14c7cc52007-02-25 15:08:24 +000042#include "pub_core_xarray.h"
sewardja672ea32006-04-29 18:03:14 +000043#include "pub_core_clientstate.h" // VG_(client__dl_sysinfo_int80)
njna7598f62005-06-18 03:27:58 +000044#include "pub_core_trampoline.h"
njnd01fef72005-03-25 23:35:48 +000045
46/*------------------------------------------------------------*/
47/*--- Exported functions. ---*/
48/*------------------------------------------------------------*/
49
sewardjacaec5f2005-08-19 16:02:59 +000050/* Take a snapshot of the client's stack, putting the up to 'n_ips'
51 IPs into 'ips'. In order to be thread-safe, we pass in the
52 thread's IP SP, FP if that's meaningful, and LR if that's
53 meaningful. Returns number of IPs put in 'ips'.
sewardjdfbaa222006-01-18 04:25:20 +000054
55 If you know what the thread ID for this stack is, send that as the
56 first parameter, else send zero. This helps generate better stack
57 traces on ppc64-linux and has no effect on other platforms.
sewardjacaec5f2005-08-19 16:02:59 +000058*/
sewardjdfbaa222006-01-18 04:25:20 +000059UInt VG_(get_StackTrace2) ( ThreadId tid_if_known,
60 Addr* ips, UInt n_ips,
sewardjacaec5f2005-08-19 16:02:59 +000061 Addr ip, Addr sp, Addr fp, Addr lr,
njnd01fef72005-03-25 23:35:48 +000062 Addr fp_min, Addr fp_max_orig )
63{
sewardj15338c52006-10-17 01:31:58 +000064# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
65 || defined(VGP_ppc32_aix5) \
66 || defined(VGP_ppc64_aix5)
67 Bool lr_is_first_RA = False;
68# endif
69# if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5) \
70 || defined(VGP_ppc32_aix5)
71 Word redir_stack_size = 0;
72 Word redirs_used = 0;
73# endif
74
sewardjacaec5f2005-08-19 16:02:59 +000075 Bool debug = False;
76 Int i;
77 Addr fp_max;
78 UInt n_found = 0;
njnd01fef72005-03-25 23:35:48 +000079
sewardjacaec5f2005-08-19 16:02:59 +000080 vg_assert(sizeof(Addr) == sizeof(UWord));
81 vg_assert(sizeof(Addr) == sizeof(void*));
njnd01fef72005-03-25 23:35:48 +000082
sewardjacaec5f2005-08-19 16:02:59 +000083 /* Snaffle IPs from the client's stack into ips[0 .. n_ips-1],
njnc0ec8e92005-12-25 06:34:04 +000084 stopping when the trail goes cold, which we guess to be
sewardjacaec5f2005-08-19 16:02:59 +000085 when FP is not a reasonable stack location. */
86
njnd01fef72005-03-25 23:35:48 +000087 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
88 // current page, at least. Dunno if it helps.
89 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
sewardj45f4e7c2005-09-27 19:20:21 +000090 fp_max = VG_PGROUNDUP(fp_max_orig);
njnd01fef72005-03-25 23:35:48 +000091 fp_max -= sizeof(Addr);
92
93 if (debug)
94 VG_(printf)("n_ips=%d fp_min=%p fp_max_orig=%p, fp_max=%p ip=%p fp=%p\n",
95 n_ips, fp_min, fp_max_orig, fp_max, ip, fp);
96
97 /* Assertion broken before main() is reached in pthreaded programs; the
98 * offending stack traces only have one item. --njn, 2002-aug-16 */
99 /* vg_assert(fp_min <= fp_max);*/
100
sewardj35165532005-04-30 18:47:48 +0000101 if (fp_min + VG_(clo_max_stackframe) <= fp_max) {
njnd01fef72005-03-25 23:35:48 +0000102 /* If the stack is ridiculously big, don't poke around ... but
103 don't bomb out either. Needed to make John Regehr's
104 user-space threads package work. JRS 20021001 */
sewardjacaec5f2005-08-19 16:02:59 +0000105 ips[0] = ip;
sewardjacaec5f2005-08-19 16:02:59 +0000106 return 1;
107 }
sewardj35165532005-04-30 18:47:48 +0000108
sewardjacaec5f2005-08-19 16:02:59 +0000109 /* Otherwise unwind the stack in a platform-specific way. Trying
sewardjdb2ac812005-12-23 23:33:51 +0000110 to merge the x86, amd64, ppc32 and ppc64 logic into a single
111 piece of code is just too confusing and difficult to
112 performance-tune. */
njn88b5a982005-05-16 00:16:56 +0000113
sewardj75ea7982005-11-14 15:18:25 +0000114# if defined(VGP_x86_linux)
sewardj35165532005-04-30 18:47:48 +0000115
sewardj75ea7982005-11-14 15:18:25 +0000116 /*--------------------- x86 ---------------------*/
sewardj35165532005-04-30 18:47:48 +0000117
sewardj75ea7982005-11-14 15:18:25 +0000118 /* fp is %ebp. sp is %esp. ip is %eip. */
119
120 ips[0] = ip;
121 i = 1;
122
123 /* Loop unwinding the stack. Note that the IP value we get on
124 * each pass (whether from CFI info or a stack frame) is a
125 * return address so is actually after the calling instruction
126 * in the calling function.
127 *
128 * Because of this we subtract one from the IP after each pass
129 * of the loop so that we find the right CFI block on the next
130 * pass - otherwise we can find the wrong CFI info if it happens
131 * to change after the calling instruction and that will mean
132 * that we will fail to unwind the next step.
133 *
134 * This most frequently happens at the end of a function when
135 * a tail call occurs and we wind up using the CFI info for the
136 * next function which is completely wrong.
137 */
138 while (True) {
139
140 if (i >= n_ips)
141 break;
142
143 /* Try to derive a new (ip,sp,fp) triple from the current
144 set. */
145
146 /* On x86, first try the old-fashioned method of following the
147 %ebp-chain. Code which doesn't use this (that is, compiled
148 with -fomit-frame-pointer) is not ABI compliant and so
149 relatively rare. Besides, trying the CFI first almost always
150 fails, and is expensive. */
151 /* Deal with frames resulting from functions which begin "pushl%
152 ebp ; movl %esp, %ebp" which is the ABI-mandated preamble. */
153 if (fp_min <= fp && fp <= fp_max) {
154 /* fp looks sane, so use it. */
155 ip = (((UWord*)fp)[1]);
156 sp = fp + sizeof(Addr) /*saved %ebp*/
157 + sizeof(Addr) /*ra*/;
158 fp = (((UWord*)fp)[0]);
159 ips[i++] = ip;
160 if (debug)
dirke4067232007-10-04 21:36:40 +0000161 VG_(printf)(" ipsF[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardj75ea7982005-11-14 15:18:25 +0000162 ip = ip - 1;
163 continue;
164 }
165
sewardj15338c52006-10-17 01:31:58 +0000166 /* That didn't work out, so see if there is any CF info to hand
sewardj75ea7982005-11-14 15:18:25 +0000167 which can be used. */
sewardjeadcd862006-04-04 15:12:44 +0000168 if ( VG_(use_CF_info)( &ip, &sp, &fp, fp_min, fp_max ) ) {
sewardj75ea7982005-11-14 15:18:25 +0000169 ips[i++] = ip;
170 if (debug)
dirke4067232007-10-04 21:36:40 +0000171 VG_(printf)(" ipsC[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardj75ea7982005-11-14 15:18:25 +0000172 ip = ip - 1;
173 continue;
174 }
175
176 /* No luck. We have to give up. */
177 break;
178 }
179
180# elif defined(VGP_amd64_linux)
181
182 /*--------------------- amd64 ---------------------*/
183
184 /* fp is %rbp. sp is %rsp. ip is %rip. */
sewardj35165532005-04-30 18:47:48 +0000185
sewardjacaec5f2005-08-19 16:02:59 +0000186 ips[0] = ip;
187 i = 1;
sewardj35165532005-04-30 18:47:48 +0000188
tomac35f102005-11-05 00:17:21 +0000189 /* Loop unwinding the stack. Note that the IP value we get on
190 * each pass (whether from CFI info or a stack frame) is a
191 * return address so is actually after the calling instruction
192 * in the calling function.
193 *
194 * Because of this we subtract one from the IP after each pass
195 * of the loop so that we find the right CFI block on the next
196 * pass - otherwise we can find the wrong CFI info if it happens
197 * to change after the calling instruction and that will mean
198 * that we will fail to unwind the next step.
199 *
200 * This most frequently happens at the end of a function when
201 * a tail call occurs and we wind up using the CFI info for the
202 * next function which is completely wrong.
203 */
sewardjacaec5f2005-08-19 16:02:59 +0000204 while (True) {
sewardj35165532005-04-30 18:47:48 +0000205
sewardjacaec5f2005-08-19 16:02:59 +0000206 if (i >= n_ips)
sewardj35165532005-04-30 18:47:48 +0000207 break;
sewardjacaec5f2005-08-19 16:02:59 +0000208
209 /* Try to derive a new (ip,sp,fp) triple from the current
210 set. */
211
212 /* First off, see if there is any CFI info to hand which can
213 be used. */
sewardjeadcd862006-04-04 15:12:44 +0000214 if ( VG_(use_CF_info)( &ip, &sp, &fp, fp_min, fp_max ) ) {
sewardjacaec5f2005-08-19 16:02:59 +0000215 ips[i++] = ip;
216 if (debug)
217 VG_(printf)(" ipsC[%d]=%08p\n", i-1, ips[i-1]);
tom121d1d02005-11-04 11:31:33 +0000218 ip = ip - 1;
sewardjacaec5f2005-08-19 16:02:59 +0000219 continue;
njnd01fef72005-03-25 23:35:48 +0000220 }
sewardj35165532005-04-30 18:47:48 +0000221
sewardjeadcd862006-04-04 15:12:44 +0000222 /* If VG_(use_CF_info) fails, it won't modify ip/sp/fp, so
sewardjacaec5f2005-08-19 16:02:59 +0000223 we can safely try the old-fashioned method. */
224 /* This bit is supposed to deal with frames resulting from
sewardj75ea7982005-11-14 15:18:25 +0000225 functions which begin "pushq %rbp ; movq %rsp, %rbp".
226 Unfortunately, since we can't (easily) look at the insns at
227 the start of the fn, like GDB does, there's no reliable way
228 to tell. Hence the hack of first trying out CFI, and if that
229 fails, then use this as a fallback. */
sewardjacaec5f2005-08-19 16:02:59 +0000230 if (fp_min <= fp && fp <= fp_max) {
231 /* fp looks sane, so use it. */
232 ip = (((UWord*)fp)[1]);
sewardj75ea7982005-11-14 15:18:25 +0000233 sp = fp + sizeof(Addr) /*saved %rbp*/
sewardjacaec5f2005-08-19 16:02:59 +0000234 + sizeof(Addr) /*ra*/;
235 fp = (((UWord*)fp)[0]);
236 ips[i++] = ip;
237 if (debug)
238 VG_(printf)(" ipsF[%d]=%08p\n", i-1, ips[i-1]);
tom121d1d02005-11-04 11:31:33 +0000239 ip = ip - 1;
sewardjacaec5f2005-08-19 16:02:59 +0000240 continue;
241 }
242
sewardj39f34232007-11-09 23:02:28 +0000243 /* Last-ditch hack (evidently GDB does something similar). We
244 are in the middle of nowhere and we have a nonsense value for
245 the frame pointer. If the stack pointer is still valid,
246 assume that what it points at is a return address. Yes,
247 desperate measures. Could do better here:
248 - check that the supposed return address is in
249 an executable page
250 - check that the supposed return address is just after a call insn
251 - given those two checks, don't just consider *sp as the return
252 address; instead scan a likely section of stack (eg sp .. sp+256)
253 and use suitable values found there.
254 */
255 if (fp_min <= sp && sp < fp_max) {
256 ip = ((UWord*)sp)[0];
257 ips[i++] = ip;
258 if (debug)
259 VG_(printf)(" ipsH[%d]=%08p\n", i-1, ips[i-1]);
260 ip = ip - 1;
261 sp += 8;
262 continue;
263 }
264
265 /* No luck at all. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000266 break;
njnd01fef72005-03-25 23:35:48 +0000267 }
sewardjacaec5f2005-08-19 16:02:59 +0000268
sewardj15338c52006-10-17 01:31:58 +0000269# elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
270 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
sewardjacaec5f2005-08-19 16:02:59 +0000271
sewardjdfbaa222006-01-18 04:25:20 +0000272 /*--------------------- ppc32/64 ---------------------*/
sewardj75ea7982005-11-14 15:18:25 +0000273
sewardjacaec5f2005-08-19 16:02:59 +0000274 /* fp is %r1. ip is %cia. Note, ppc uses r1 as both the stack and
275 frame pointers. */
276
sewardj15338c52006-10-17 01:31:58 +0000277# if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
278 redir_stack_size = VEX_GUEST_PPC64_REDIR_STACK_SIZE;
279 redirs_used = 0;
280# elif defined(VGP_ppc32_aix5)
281 redir_stack_size = VEX_GUEST_PPC32_REDIR_STACK_SIZE;
282 redirs_used = 0;
283# endif
284
285# if defined(VG_PLAT_USES_PPCTOC)
sewardjcfb5e2b2006-01-19 03:47:30 +0000286 /* Deal with bogus LR values caused by function
sewardj15338c52006-10-17 01:31:58 +0000287 interception/wrapping on ppc-TOC platforms; see comment on
288 similar code a few lines further down. */
289 if (ULong_to_Ptr(lr) == (void*)&VG_(ppctoc_magic_redirect_return_stub)
sewardjcfb5e2b2006-01-19 03:47:30 +0000290 && VG_(is_valid_tid)(tid_if_known)) {
sewardj15338c52006-10-17 01:31:58 +0000291 Word hsp = VG_(threads)[tid_if_known].arch.vex.guest_REDIR_SP;
292 redirs_used++;
293 if (hsp >= 1 && hsp < redir_stack_size)
sewardjcfb5e2b2006-01-19 03:47:30 +0000294 lr = VG_(threads)[tid_if_known]
295 .arch.vex.guest_REDIR_STACK[hsp-1];
296 }
297# endif
298
sewardj15338c52006-10-17 01:31:58 +0000299 /* We have to determine whether or not LR currently holds this fn
300 (call it F)'s return address. It might not if F has previously
301 called some other function, hence overwriting LR with a pointer
302 to some part of F. Hence if LR and IP point to the same
303 function then we conclude LR does not hold this function's
304 return address; instead the LR at entry must have been saved in
305 the stack by F's prologue and so we must get it from there
306 instead. Note all this guff only applies to the innermost
307 frame. */
sewardjacaec5f2005-08-19 16:02:59 +0000308 lr_is_first_RA = False;
309 {
310# define M_VG_ERRTXT 1000
311 UChar buf_lr[M_VG_ERRTXT], buf_ip[M_VG_ERRTXT];
312 if (VG_(get_fnname_nodemangle) (lr, buf_lr, M_VG_ERRTXT))
313 if (VG_(get_fnname_nodemangle) (ip, buf_ip, M_VG_ERRTXT))
314 if (VG_(strncmp)(buf_lr, buf_ip, M_VG_ERRTXT))
315 lr_is_first_RA = True;
316# undef M_VG_ERRTXT
317 }
318
319 ips[0] = ip;
320 i = 1;
sewardjacaec5f2005-08-19 16:02:59 +0000321
sewardjdb2ac812005-12-23 23:33:51 +0000322 if (fp_min <= fp && fp < fp_max-VG_WORDSIZE+1) {
sewardjacaec5f2005-08-19 16:02:59 +0000323
sewardj525e2322005-11-13 02:41:35 +0000324 /* initial FP is sane; keep going */
325 fp = (((UWord*)fp)[0]);
326
327 while (True) {
328
sewardj15338c52006-10-17 01:31:58 +0000329 /* On ppc64-linux (ppc64-elf, really), and on AIX, the lr save
330 slot is 2 words back from sp, whereas on ppc32-elf(?) it's
331 only one word back. */
332# if defined(VGP_ppc64_linux) \
333 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
sewardjdfbaa222006-01-18 04:25:20 +0000334 const Int lr_offset = 2;
335# else
336 const Int lr_offset = 1;
337# endif
sewardjdb2ac812005-12-23 23:33:51 +0000338
sewardj525e2322005-11-13 02:41:35 +0000339 if (i >= n_ips)
340 break;
341
342 /* Try to derive a new (ip,fp) pair from the current set. */
343
344 if (fp_min <= fp && fp <= fp_max) {
345 /* fp looks sane, so use it. */
346
347 if (i == 1 && lr_is_first_RA)
348 ip = lr;
349 else
sewardjdb2ac812005-12-23 23:33:51 +0000350 ip = (((UWord*)fp)[lr_offset]);
sewardj525e2322005-11-13 02:41:35 +0000351
sewardj15338c52006-10-17 01:31:58 +0000352# if defined(VG_PLAT_USES_PPCTOC)
sewardjdfbaa222006-01-18 04:25:20 +0000353 /* Nasty hack to do with function replacement/wrapping on
sewardj15338c52006-10-17 01:31:58 +0000354 ppc64-linux/ppc64-aix/ppc32-aix. If LR points to our
355 magic return stub, then we are in a wrapped or
356 intercepted function, in which LR has been messed with.
357 The original LR will have been pushed onto the thread's
358 hidden REDIR stack one down from the top (top element
359 is the saved R2) and so we should restore the value
360 from there instead. Since nested redirections can and
361 do happen, we keep track of the number of nested LRs
362 used by the unwinding so far with 'redirs_used'. */
363 if (ip == (Addr)&VG_(ppctoc_magic_redirect_return_stub)
sewardjdfbaa222006-01-18 04:25:20 +0000364 && VG_(is_valid_tid)(tid_if_known)) {
sewardj15338c52006-10-17 01:31:58 +0000365 Word hsp = VG_(threads)[tid_if_known].arch.vex.guest_REDIR_SP;
366 hsp -= 2 * redirs_used;
367 redirs_used ++;
368 if (hsp >= 1 && hsp < redir_stack_size)
sewardjdfbaa222006-01-18 04:25:20 +0000369 ip = VG_(threads)[tid_if_known]
370 .arch.vex.guest_REDIR_STACK[hsp-1];
371 }
372# endif
373
sewardj525e2322005-11-13 02:41:35 +0000374 fp = (((UWord*)fp)[0]);
375 ips[i++] = ip;
376 if (debug)
377 VG_(printf)(" ipsF[%d]=%08p\n", i-1, ips[i-1]);
378 continue;
379 }
380
381 /* No luck there. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000382 break;
sewardjacaec5f2005-08-19 16:02:59 +0000383 }
sewardjacaec5f2005-08-19 16:02:59 +0000384 }
385
386# else
387# error "Unknown platform"
388# endif
389
njnd01fef72005-03-25 23:35:48 +0000390 n_found = i;
njnd01fef72005-03-25 23:35:48 +0000391 return n_found;
392}
393
sewardj39f34232007-11-09 23:02:28 +0000394UInt VG_(get_StackTrace) ( ThreadId tid, StackTrace ips, UInt n_ips,
395 Word first_ip_delta )
njnd01fef72005-03-25 23:35:48 +0000396{
397 /* thread in thread table */
njnf536bbb2005-06-13 04:21:38 +0000398 Addr ip = VG_(get_IP)(tid);
399 Addr fp = VG_(get_FP)(tid);
400 Addr sp = VG_(get_SP)(tid);
sewardjacaec5f2005-08-19 16:02:59 +0000401 Addr lr = VG_(get_LR)(tid);
njnf536bbb2005-06-13 04:21:38 +0000402 Addr stack_highest_word = VG_(threads)[tid].client_stack_highest_word;
njnd01fef72005-03-25 23:35:48 +0000403
sewardjb9bce632005-06-21 01:41:34 +0000404# if defined(VGP_x86_linux)
sewardja672ea32006-04-29 18:03:14 +0000405 /* Nasty little hack to deal with syscalls - if libc is using its
406 _dl_sysinfo_int80 function for syscalls (the TLS version does),
407 then ip will always appear to be in that function when doing a
408 syscall, not the actual libc function doing the syscall. This
409 check sees if IP is within that function, and pops the return
410 address off the stack so that ip is placed within the library
411 function calling the syscall. This makes stack backtraces much
412 more useful.
413
414 The function is assumed to look like this (from glibc-2.3.6 sources):
415 _dl_sysinfo_int80:
416 int $0x80
417 ret
418 That is 3 (2+1) bytes long. We could be more thorough and check
419 the 3 bytes of the function are as expected, but I can't be
420 bothered.
421 */
422 if (VG_(client__dl_sysinfo_int80) != 0 /* we know its address */
423 && ip >= VG_(client__dl_sysinfo_int80)
424 && ip < VG_(client__dl_sysinfo_int80)+3
sewardj45f4e7c2005-09-27 19:20:21 +0000425 && VG_(am_is_valid_for_client)(sp, sizeof(Addr), VKI_PROT_READ)) {
njnd01fef72005-03-25 23:35:48 +0000426 ip = *(Addr *)sp;
427 sp += sizeof(Addr);
428 }
sewardjb9bce632005-06-21 01:41:34 +0000429# endif
430
sewardj39f34232007-11-09 23:02:28 +0000431 /* Take into account the first_ip_delta. */
432 vg_assert( sizeof(Addr) == sizeof(Word) );
433 ip += first_ip_delta;
434
njnd01fef72005-03-25 23:35:48 +0000435 if (0)
dirk61780382007-10-01 10:33:41 +0000436 VG_(printf)("tid %d: stack_highest=0x%08lx ip=0x%08lx sp=0x%08lx fp=0x%08lx\n",
njnd01fef72005-03-25 23:35:48 +0000437 tid, stack_highest_word, ip, sp, fp);
438
sewardjdfbaa222006-01-18 04:25:20 +0000439 return VG_(get_StackTrace2)(tid, ips, n_ips, ip, sp, fp, lr, sp,
440 stack_highest_word);
njnd01fef72005-03-25 23:35:48 +0000441}
442
443static void printIpDesc(UInt n, Addr ip)
444{
njn83f9e792005-06-11 05:04:09 +0000445 #define BUF_LEN 4096
446
447 static UChar buf[BUF_LEN];
njnd01fef72005-03-25 23:35:48 +0000448
njn83f9e792005-06-11 05:04:09 +0000449 VG_(describe_IP)(ip, buf, BUF_LEN);
sewardj71bc3cb2005-05-19 00:25:45 +0000450
451 if (VG_(clo_xml)) {
452 VG_(message)(Vg_UserMsg, " %s", buf);
453 } else {
454 VG_(message)(Vg_UserMsg, " %s %s", ( n == 0 ? "at" : "by" ), buf);
455 }
njnd01fef72005-03-25 23:35:48 +0000456}
457
458/* Print a StackTrace. */
459void VG_(pp_StackTrace) ( StackTrace ips, UInt n_ips )
460{
461 vg_assert( n_ips > 0 );
sewardj71bc3cb2005-05-19 00:25:45 +0000462
463 if (VG_(clo_xml))
464 VG_(message)(Vg_UserMsg, " <stack>");
465
njnd01fef72005-03-25 23:35:48 +0000466 VG_(apply_StackTrace)( printIpDesc, ips, n_ips );
sewardj71bc3cb2005-05-19 00:25:45 +0000467
468 if (VG_(clo_xml))
469 VG_(message)(Vg_UserMsg, " </stack>");
njnd01fef72005-03-25 23:35:48 +0000470}
471
472/* Get and immediately print a StackTrace. */
473void VG_(get_and_pp_StackTrace) ( ThreadId tid, UInt n_ips )
474{
475 Addr ips[n_ips];
sewardj39f34232007-11-09 23:02:28 +0000476 UInt n_ips_obtained = VG_(get_StackTrace)(tid, ips, n_ips,
477 0/*first_ip_delta*/);
njn88d3ba82006-08-13 04:48:25 +0000478 VG_(pp_StackTrace)(ips, n_ips_obtained);
njnd01fef72005-03-25 23:35:48 +0000479}
480
481
482void VG_(apply_StackTrace)( void(*action)(UInt n, Addr ip),
483 StackTrace ips, UInt n_ips )
484{
sewardj73cf4c62005-11-17 15:12:34 +0000485 #define MYBUF_LEN 50 // only needs to be long enough for
486 // the names specially tested for
njnd01fef72005-03-25 23:35:48 +0000487
488 Bool main_done = False;
489 Char mybuf[MYBUF_LEN]; // ok to stack allocate mybuf[] -- it's tiny
490 Int i = 0;
491
492 vg_assert(n_ips > 0);
493 do {
494 Addr ip = ips[i];
495 if (i > 0)
njnaf839f52005-06-23 03:27:57 +0000496 ip -= VG_MIN_INSTR_SZB; // point to calling line
njnd01fef72005-03-25 23:35:48 +0000497
sewardj73cf4c62005-11-17 15:12:34 +0000498 // Stop after the first appearance of "main" or one of the other names
499 // (the appearance of which is a pretty good sign that we've gone past
500 // main without seeing it, for whatever reason)
njnd01fef72005-03-25 23:35:48 +0000501 if ( ! VG_(clo_show_below_main)) {
502 VG_(get_fnname_nodemangle)( ip, mybuf, MYBUF_LEN );
sewardj73cf4c62005-11-17 15:12:34 +0000503 mybuf[MYBUF_LEN-1] = 0; // paranoia
504 if ( VG_STREQ("main", mybuf)
505# if defined(VGO_linux)
sewardj1a85f4f2006-01-12 21:15:35 +0000506 || VG_STREQ("__libc_start_main", mybuf) // glibc glibness
507 || VG_STREQ("generic_start_main", mybuf) // Yellow Dog doggedness
sewardj73cf4c62005-11-17 15:12:34 +0000508# endif
509 )
njnd01fef72005-03-25 23:35:48 +0000510 main_done = True;
njnd01fef72005-03-25 23:35:48 +0000511 }
512
513 // Act on the ip
514 action(i, ip);
515
516 i++;
sewardj73cf4c62005-11-17 15:12:34 +0000517 } while (i < n_ips && ips[i] != 0 && !main_done);
njnd01fef72005-03-25 23:35:48 +0000518
519 #undef MYBUF_LEN
520}
521
522
523/*--------------------------------------------------------------------*/
njn24a6efb2005-06-20 03:36:51 +0000524/*--- end ---*/
njnd01fef72005-03-25 23:35:48 +0000525/*--------------------------------------------------------------------*/