blob: a0bb6ac7b72c9b6b95f8e1f3ed7662b4936bd1ac [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);*/
sewardj5bdfbd22007-12-15 22:13:05 +0000100 if (fp_min + 512 >= fp_max) {
101 /* If the stack limits look bogus, don't poke around ... but
102 don't bomb out either. */
sewardjacaec5f2005-08-19 16:02:59 +0000103 ips[0] = ip;
sewardjacaec5f2005-08-19 16:02:59 +0000104 return 1;
105 }
sewardj35165532005-04-30 18:47:48 +0000106
sewardjacaec5f2005-08-19 16:02:59 +0000107 /* Otherwise unwind the stack in a platform-specific way. Trying
sewardjdb2ac812005-12-23 23:33:51 +0000108 to merge the x86, amd64, ppc32 and ppc64 logic into a single
109 piece of code is just too confusing and difficult to
110 performance-tune. */
njn88b5a982005-05-16 00:16:56 +0000111
sewardj75ea7982005-11-14 15:18:25 +0000112# if defined(VGP_x86_linux)
sewardj35165532005-04-30 18:47:48 +0000113
sewardj75ea7982005-11-14 15:18:25 +0000114 /*--------------------- x86 ---------------------*/
sewardj35165532005-04-30 18:47:48 +0000115
sewardj75ea7982005-11-14 15:18:25 +0000116 /* fp is %ebp. sp is %esp. ip is %eip. */
117
118 ips[0] = ip;
119 i = 1;
120
121 /* Loop unwinding the stack. Note that the IP value we get on
122 * each pass (whether from CFI info or a stack frame) is a
123 * return address so is actually after the calling instruction
124 * in the calling function.
125 *
126 * Because of this we subtract one from the IP after each pass
127 * of the loop so that we find the right CFI block on the next
128 * pass - otherwise we can find the wrong CFI info if it happens
129 * to change after the calling instruction and that will mean
130 * that we will fail to unwind the next step.
131 *
132 * This most frequently happens at the end of a function when
133 * a tail call occurs and we wind up using the CFI info for the
134 * next function which is completely wrong.
135 */
136 while (True) {
137
138 if (i >= n_ips)
139 break;
140
141 /* Try to derive a new (ip,sp,fp) triple from the current
142 set. */
143
144 /* On x86, first try the old-fashioned method of following the
145 %ebp-chain. Code which doesn't use this (that is, compiled
146 with -fomit-frame-pointer) is not ABI compliant and so
147 relatively rare. Besides, trying the CFI first almost always
148 fails, and is expensive. */
149 /* Deal with frames resulting from functions which begin "pushl%
150 ebp ; movl %esp, %ebp" which is the ABI-mandated preamble. */
151 if (fp_min <= fp && fp <= fp_max) {
152 /* fp looks sane, so use it. */
153 ip = (((UWord*)fp)[1]);
154 sp = fp + sizeof(Addr) /*saved %ebp*/
155 + sizeof(Addr) /*ra*/;
156 fp = (((UWord*)fp)[0]);
157 ips[i++] = ip;
158 if (debug)
dirke4067232007-10-04 21:36:40 +0000159 VG_(printf)(" ipsF[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardj75ea7982005-11-14 15:18:25 +0000160 ip = ip - 1;
161 continue;
162 }
163
sewardj15338c52006-10-17 01:31:58 +0000164 /* That didn't work out, so see if there is any CF info to hand
sewardj75ea7982005-11-14 15:18:25 +0000165 which can be used. */
sewardjeadcd862006-04-04 15:12:44 +0000166 if ( VG_(use_CF_info)( &ip, &sp, &fp, fp_min, fp_max ) ) {
sewardj75ea7982005-11-14 15:18:25 +0000167 ips[i++] = ip;
168 if (debug)
dirke4067232007-10-04 21:36:40 +0000169 VG_(printf)(" ipsC[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardj75ea7982005-11-14 15:18:25 +0000170 ip = ip - 1;
171 continue;
172 }
173
174 /* No luck. We have to give up. */
175 break;
176 }
177
178# elif defined(VGP_amd64_linux)
179
180 /*--------------------- amd64 ---------------------*/
181
182 /* fp is %rbp. sp is %rsp. ip is %rip. */
sewardj35165532005-04-30 18:47:48 +0000183
sewardjacaec5f2005-08-19 16:02:59 +0000184 ips[0] = ip;
185 i = 1;
sewardj35165532005-04-30 18:47:48 +0000186
tomac35f102005-11-05 00:17:21 +0000187 /* Loop unwinding the stack. Note that the IP value we get on
188 * each pass (whether from CFI info or a stack frame) is a
189 * return address so is actually after the calling instruction
190 * in the calling function.
191 *
192 * Because of this we subtract one from the IP after each pass
193 * of the loop so that we find the right CFI block on the next
194 * pass - otherwise we can find the wrong CFI info if it happens
195 * to change after the calling instruction and that will mean
196 * that we will fail to unwind the next step.
197 *
198 * This most frequently happens at the end of a function when
199 * a tail call occurs and we wind up using the CFI info for the
200 * next function which is completely wrong.
201 */
sewardjacaec5f2005-08-19 16:02:59 +0000202 while (True) {
sewardj35165532005-04-30 18:47:48 +0000203
sewardjacaec5f2005-08-19 16:02:59 +0000204 if (i >= n_ips)
sewardj35165532005-04-30 18:47:48 +0000205 break;
sewardjacaec5f2005-08-19 16:02:59 +0000206
207 /* Try to derive a new (ip,sp,fp) triple from the current
208 set. */
209
210 /* First off, see if there is any CFI info to hand which can
211 be used. */
sewardjeadcd862006-04-04 15:12:44 +0000212 if ( VG_(use_CF_info)( &ip, &sp, &fp, fp_min, fp_max ) ) {
sewardjacaec5f2005-08-19 16:02:59 +0000213 ips[i++] = ip;
214 if (debug)
215 VG_(printf)(" ipsC[%d]=%08p\n", i-1, ips[i-1]);
tom121d1d02005-11-04 11:31:33 +0000216 ip = ip - 1;
sewardjacaec5f2005-08-19 16:02:59 +0000217 continue;
njnd01fef72005-03-25 23:35:48 +0000218 }
sewardj35165532005-04-30 18:47:48 +0000219
sewardjeadcd862006-04-04 15:12:44 +0000220 /* If VG_(use_CF_info) fails, it won't modify ip/sp/fp, so
sewardjacaec5f2005-08-19 16:02:59 +0000221 we can safely try the old-fashioned method. */
222 /* This bit is supposed to deal with frames resulting from
sewardj75ea7982005-11-14 15:18:25 +0000223 functions which begin "pushq %rbp ; movq %rsp, %rbp".
224 Unfortunately, since we can't (easily) look at the insns at
225 the start of the fn, like GDB does, there's no reliable way
226 to tell. Hence the hack of first trying out CFI, and if that
227 fails, then use this as a fallback. */
sewardjacaec5f2005-08-19 16:02:59 +0000228 if (fp_min <= fp && fp <= fp_max) {
229 /* fp looks sane, so use it. */
230 ip = (((UWord*)fp)[1]);
sewardj75ea7982005-11-14 15:18:25 +0000231 sp = fp + sizeof(Addr) /*saved %rbp*/
sewardjacaec5f2005-08-19 16:02:59 +0000232 + sizeof(Addr) /*ra*/;
233 fp = (((UWord*)fp)[0]);
234 ips[i++] = ip;
235 if (debug)
236 VG_(printf)(" ipsF[%d]=%08p\n", i-1, ips[i-1]);
tom121d1d02005-11-04 11:31:33 +0000237 ip = ip - 1;
sewardjacaec5f2005-08-19 16:02:59 +0000238 continue;
239 }
240
sewardj39f34232007-11-09 23:02:28 +0000241 /* Last-ditch hack (evidently GDB does something similar). We
242 are in the middle of nowhere and we have a nonsense value for
243 the frame pointer. If the stack pointer is still valid,
244 assume that what it points at is a return address. Yes,
245 desperate measures. Could do better here:
246 - check that the supposed return address is in
247 an executable page
248 - check that the supposed return address is just after a call insn
249 - given those two checks, don't just consider *sp as the return
250 address; instead scan a likely section of stack (eg sp .. sp+256)
251 and use suitable values found there.
252 */
253 if (fp_min <= sp && sp < fp_max) {
254 ip = ((UWord*)sp)[0];
255 ips[i++] = ip;
256 if (debug)
257 VG_(printf)(" ipsH[%d]=%08p\n", i-1, ips[i-1]);
258 ip = ip - 1;
259 sp += 8;
260 continue;
261 }
262
263 /* No luck at all. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000264 break;
njnd01fef72005-03-25 23:35:48 +0000265 }
sewardjacaec5f2005-08-19 16:02:59 +0000266
sewardj15338c52006-10-17 01:31:58 +0000267# elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
268 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
sewardjacaec5f2005-08-19 16:02:59 +0000269
sewardjdfbaa222006-01-18 04:25:20 +0000270 /*--------------------- ppc32/64 ---------------------*/
sewardj75ea7982005-11-14 15:18:25 +0000271
sewardjacaec5f2005-08-19 16:02:59 +0000272 /* fp is %r1. ip is %cia. Note, ppc uses r1 as both the stack and
273 frame pointers. */
274
sewardj15338c52006-10-17 01:31:58 +0000275# if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
276 redir_stack_size = VEX_GUEST_PPC64_REDIR_STACK_SIZE;
277 redirs_used = 0;
278# elif defined(VGP_ppc32_aix5)
279 redir_stack_size = VEX_GUEST_PPC32_REDIR_STACK_SIZE;
280 redirs_used = 0;
281# endif
282
283# if defined(VG_PLAT_USES_PPCTOC)
sewardjcfb5e2b2006-01-19 03:47:30 +0000284 /* Deal with bogus LR values caused by function
sewardj15338c52006-10-17 01:31:58 +0000285 interception/wrapping on ppc-TOC platforms; see comment on
286 similar code a few lines further down. */
287 if (ULong_to_Ptr(lr) == (void*)&VG_(ppctoc_magic_redirect_return_stub)
sewardjcfb5e2b2006-01-19 03:47:30 +0000288 && VG_(is_valid_tid)(tid_if_known)) {
sewardj15338c52006-10-17 01:31:58 +0000289 Word hsp = VG_(threads)[tid_if_known].arch.vex.guest_REDIR_SP;
290 redirs_used++;
291 if (hsp >= 1 && hsp < redir_stack_size)
sewardjcfb5e2b2006-01-19 03:47:30 +0000292 lr = VG_(threads)[tid_if_known]
293 .arch.vex.guest_REDIR_STACK[hsp-1];
294 }
295# endif
296
sewardj15338c52006-10-17 01:31:58 +0000297 /* We have to determine whether or not LR currently holds this fn
298 (call it F)'s return address. It might not if F has previously
299 called some other function, hence overwriting LR with a pointer
300 to some part of F. Hence if LR and IP point to the same
301 function then we conclude LR does not hold this function's
302 return address; instead the LR at entry must have been saved in
303 the stack by F's prologue and so we must get it from there
304 instead. Note all this guff only applies to the innermost
305 frame. */
sewardjacaec5f2005-08-19 16:02:59 +0000306 lr_is_first_RA = False;
307 {
308# define M_VG_ERRTXT 1000
309 UChar buf_lr[M_VG_ERRTXT], buf_ip[M_VG_ERRTXT];
310 if (VG_(get_fnname_nodemangle) (lr, buf_lr, M_VG_ERRTXT))
311 if (VG_(get_fnname_nodemangle) (ip, buf_ip, M_VG_ERRTXT))
312 if (VG_(strncmp)(buf_lr, buf_ip, M_VG_ERRTXT))
313 lr_is_first_RA = True;
314# undef M_VG_ERRTXT
315 }
316
317 ips[0] = ip;
318 i = 1;
sewardjacaec5f2005-08-19 16:02:59 +0000319
sewardjdb2ac812005-12-23 23:33:51 +0000320 if (fp_min <= fp && fp < fp_max-VG_WORDSIZE+1) {
sewardjacaec5f2005-08-19 16:02:59 +0000321
sewardj525e2322005-11-13 02:41:35 +0000322 /* initial FP is sane; keep going */
323 fp = (((UWord*)fp)[0]);
324
325 while (True) {
326
sewardj15338c52006-10-17 01:31:58 +0000327 /* On ppc64-linux (ppc64-elf, really), and on AIX, the lr save
328 slot is 2 words back from sp, whereas on ppc32-elf(?) it's
329 only one word back. */
330# if defined(VGP_ppc64_linux) \
331 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
sewardjdfbaa222006-01-18 04:25:20 +0000332 const Int lr_offset = 2;
333# else
334 const Int lr_offset = 1;
335# endif
sewardjdb2ac812005-12-23 23:33:51 +0000336
sewardj525e2322005-11-13 02:41:35 +0000337 if (i >= n_ips)
338 break;
339
340 /* Try to derive a new (ip,fp) pair from the current set. */
341
342 if (fp_min <= fp && fp <= fp_max) {
343 /* fp looks sane, so use it. */
344
345 if (i == 1 && lr_is_first_RA)
346 ip = lr;
347 else
sewardjdb2ac812005-12-23 23:33:51 +0000348 ip = (((UWord*)fp)[lr_offset]);
sewardj525e2322005-11-13 02:41:35 +0000349
sewardj15338c52006-10-17 01:31:58 +0000350# if defined(VG_PLAT_USES_PPCTOC)
sewardjdfbaa222006-01-18 04:25:20 +0000351 /* Nasty hack to do with function replacement/wrapping on
sewardj15338c52006-10-17 01:31:58 +0000352 ppc64-linux/ppc64-aix/ppc32-aix. If LR points to our
353 magic return stub, then we are in a wrapped or
354 intercepted function, in which LR has been messed with.
355 The original LR will have been pushed onto the thread's
356 hidden REDIR stack one down from the top (top element
357 is the saved R2) and so we should restore the value
358 from there instead. Since nested redirections can and
359 do happen, we keep track of the number of nested LRs
360 used by the unwinding so far with 'redirs_used'. */
361 if (ip == (Addr)&VG_(ppctoc_magic_redirect_return_stub)
sewardjdfbaa222006-01-18 04:25:20 +0000362 && VG_(is_valid_tid)(tid_if_known)) {
sewardj15338c52006-10-17 01:31:58 +0000363 Word hsp = VG_(threads)[tid_if_known].arch.vex.guest_REDIR_SP;
364 hsp -= 2 * redirs_used;
365 redirs_used ++;
366 if (hsp >= 1 && hsp < redir_stack_size)
sewardjdfbaa222006-01-18 04:25:20 +0000367 ip = VG_(threads)[tid_if_known]
368 .arch.vex.guest_REDIR_STACK[hsp-1];
369 }
370# endif
371
sewardj525e2322005-11-13 02:41:35 +0000372 fp = (((UWord*)fp)[0]);
373 ips[i++] = ip;
374 if (debug)
375 VG_(printf)(" ipsF[%d]=%08p\n", i-1, ips[i-1]);
376 continue;
377 }
378
379 /* No luck there. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000380 break;
sewardjacaec5f2005-08-19 16:02:59 +0000381 }
sewardjacaec5f2005-08-19 16:02:59 +0000382 }
383
384# else
385# error "Unknown platform"
386# endif
387
njnd01fef72005-03-25 23:35:48 +0000388 n_found = i;
njnd01fef72005-03-25 23:35:48 +0000389 return n_found;
390}
391
sewardj39f34232007-11-09 23:02:28 +0000392UInt VG_(get_StackTrace) ( ThreadId tid, StackTrace ips, UInt n_ips,
393 Word first_ip_delta )
njnd01fef72005-03-25 23:35:48 +0000394{
395 /* thread in thread table */
njnf536bbb2005-06-13 04:21:38 +0000396 Addr ip = VG_(get_IP)(tid);
397 Addr fp = VG_(get_FP)(tid);
398 Addr sp = VG_(get_SP)(tid);
sewardjacaec5f2005-08-19 16:02:59 +0000399 Addr lr = VG_(get_LR)(tid);
njnf536bbb2005-06-13 04:21:38 +0000400 Addr stack_highest_word = VG_(threads)[tid].client_stack_highest_word;
tom690c3c82008-02-08 15:17:07 +0000401 Addr stack_lowest_word = 0;
njnd01fef72005-03-25 23:35:48 +0000402
sewardjb9bce632005-06-21 01:41:34 +0000403# if defined(VGP_x86_linux)
sewardja672ea32006-04-29 18:03:14 +0000404 /* Nasty little hack to deal with syscalls - if libc is using its
405 _dl_sysinfo_int80 function for syscalls (the TLS version does),
406 then ip will always appear to be in that function when doing a
407 syscall, not the actual libc function doing the syscall. This
408 check sees if IP is within that function, and pops the return
409 address off the stack so that ip is placed within the library
410 function calling the syscall. This makes stack backtraces much
411 more useful.
412
413 The function is assumed to look like this (from glibc-2.3.6 sources):
414 _dl_sysinfo_int80:
415 int $0x80
416 ret
417 That is 3 (2+1) bytes long. We could be more thorough and check
418 the 3 bytes of the function are as expected, but I can't be
419 bothered.
420 */
421 if (VG_(client__dl_sysinfo_int80) != 0 /* we know its address */
422 && ip >= VG_(client__dl_sysinfo_int80)
423 && ip < VG_(client__dl_sysinfo_int80)+3
sewardj45f4e7c2005-09-27 19:20:21 +0000424 && VG_(am_is_valid_for_client)(sp, sizeof(Addr), VKI_PROT_READ)) {
njnd01fef72005-03-25 23:35:48 +0000425 ip = *(Addr *)sp;
426 sp += sizeof(Addr);
427 }
sewardjb9bce632005-06-21 01:41:34 +0000428# endif
429
tom690c3c82008-02-08 15:17:07 +0000430 /* See if we can get a better idea of the stack limits */
431 VG_(stack_limits)(sp, &stack_lowest_word, &stack_highest_word);
432
sewardj39f34232007-11-09 23:02:28 +0000433 /* Take into account the first_ip_delta. */
434 vg_assert( sizeof(Addr) == sizeof(Word) );
435 ip += first_ip_delta;
436
njnd01fef72005-03-25 23:35:48 +0000437 if (0)
dirk61780382007-10-01 10:33:41 +0000438 VG_(printf)("tid %d: stack_highest=0x%08lx ip=0x%08lx sp=0x%08lx fp=0x%08lx\n",
njnd01fef72005-03-25 23:35:48 +0000439 tid, stack_highest_word, ip, sp, fp);
440
sewardjdfbaa222006-01-18 04:25:20 +0000441 return VG_(get_StackTrace2)(tid, ips, n_ips, ip, sp, fp, lr, sp,
442 stack_highest_word);
njnd01fef72005-03-25 23:35:48 +0000443}
444
445static void printIpDesc(UInt n, Addr ip)
446{
njn83f9e792005-06-11 05:04:09 +0000447 #define BUF_LEN 4096
448
449 static UChar buf[BUF_LEN];
njnd01fef72005-03-25 23:35:48 +0000450
njn83f9e792005-06-11 05:04:09 +0000451 VG_(describe_IP)(ip, buf, BUF_LEN);
sewardj71bc3cb2005-05-19 00:25:45 +0000452
453 if (VG_(clo_xml)) {
454 VG_(message)(Vg_UserMsg, " %s", buf);
455 } else {
456 VG_(message)(Vg_UserMsg, " %s %s", ( n == 0 ? "at" : "by" ), buf);
457 }
njnd01fef72005-03-25 23:35:48 +0000458}
459
460/* Print a StackTrace. */
461void VG_(pp_StackTrace) ( StackTrace ips, UInt n_ips )
462{
463 vg_assert( n_ips > 0 );
sewardj71bc3cb2005-05-19 00:25:45 +0000464
465 if (VG_(clo_xml))
466 VG_(message)(Vg_UserMsg, " <stack>");
467
njnd01fef72005-03-25 23:35:48 +0000468 VG_(apply_StackTrace)( printIpDesc, ips, n_ips );
sewardj71bc3cb2005-05-19 00:25:45 +0000469
470 if (VG_(clo_xml))
471 VG_(message)(Vg_UserMsg, " </stack>");
njnd01fef72005-03-25 23:35:48 +0000472}
473
474/* Get and immediately print a StackTrace. */
475void VG_(get_and_pp_StackTrace) ( ThreadId tid, UInt n_ips )
476{
477 Addr ips[n_ips];
sewardj39f34232007-11-09 23:02:28 +0000478 UInt n_ips_obtained = VG_(get_StackTrace)(tid, ips, n_ips,
479 0/*first_ip_delta*/);
njn88d3ba82006-08-13 04:48:25 +0000480 VG_(pp_StackTrace)(ips, n_ips_obtained);
njnd01fef72005-03-25 23:35:48 +0000481}
482
483
484void VG_(apply_StackTrace)( void(*action)(UInt n, Addr ip),
485 StackTrace ips, UInt n_ips )
486{
sewardj73cf4c62005-11-17 15:12:34 +0000487 #define MYBUF_LEN 50 // only needs to be long enough for
488 // the names specially tested for
njnd01fef72005-03-25 23:35:48 +0000489
490 Bool main_done = False;
491 Char mybuf[MYBUF_LEN]; // ok to stack allocate mybuf[] -- it's tiny
492 Int i = 0;
493
494 vg_assert(n_ips > 0);
495 do {
496 Addr ip = ips[i];
497 if (i > 0)
njnaf839f52005-06-23 03:27:57 +0000498 ip -= VG_MIN_INSTR_SZB; // point to calling line
njnd01fef72005-03-25 23:35:48 +0000499
sewardj73cf4c62005-11-17 15:12:34 +0000500 // Stop after the first appearance of "main" or one of the other names
501 // (the appearance of which is a pretty good sign that we've gone past
502 // main without seeing it, for whatever reason)
njnd01fef72005-03-25 23:35:48 +0000503 if ( ! VG_(clo_show_below_main)) {
504 VG_(get_fnname_nodemangle)( ip, mybuf, MYBUF_LEN );
sewardj73cf4c62005-11-17 15:12:34 +0000505 mybuf[MYBUF_LEN-1] = 0; // paranoia
506 if ( VG_STREQ("main", mybuf)
507# if defined(VGO_linux)
sewardj1a85f4f2006-01-12 21:15:35 +0000508 || VG_STREQ("__libc_start_main", mybuf) // glibc glibness
509 || VG_STREQ("generic_start_main", mybuf) // Yellow Dog doggedness
sewardj73cf4c62005-11-17 15:12:34 +0000510# endif
511 )
njnd01fef72005-03-25 23:35:48 +0000512 main_done = True;
njnd01fef72005-03-25 23:35:48 +0000513 }
514
515 // Act on the ip
516 action(i, ip);
517
518 i++;
sewardj73cf4c62005-11-17 15:12:34 +0000519 } while (i < n_ips && ips[i] != 0 && !main_done);
njnd01fef72005-03-25 23:35:48 +0000520
521 #undef MYBUF_LEN
522}
523
524
525/*--------------------------------------------------------------------*/
njn24a6efb2005-06-20 03:36:51 +0000526/*--- end ---*/
njnd01fef72005-03-25 23:35:48 +0000527/*--------------------------------------------------------------------*/