blob: 2f5bb097e800c3ed7dbab9b7872f6fcb39f68ac0 [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
sewardj4d474d02008-02-11 11:34:59 +000010 Copyright (C) 2000-2008 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"
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)
sewardjb8b79ad2008-03-03 01:35:41 +000097 VG_(printf)("n_ips=%d fp_min=%p fp_max_orig=%p, "
98 "fp_max=%p ip=%p fp=%p\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. */
sewardjacaec5f2005-08-19 16:02:59 +0000107 ips[0] = ip;
sewardjacaec5f2005-08-19 16:02:59 +0000108 return 1;
109 }
sewardj35165532005-04-30 18:47:48 +0000110
sewardjacaec5f2005-08-19 16:02:59 +0000111 /* Otherwise unwind the stack in a platform-specific way. Trying
sewardjdb2ac812005-12-23 23:33:51 +0000112 to merge the x86, amd64, ppc32 and ppc64 logic into a single
113 piece of code is just too confusing and difficult to
114 performance-tune. */
njn88b5a982005-05-16 00:16:56 +0000115
sewardj75ea7982005-11-14 15:18:25 +0000116# if defined(VGP_x86_linux)
sewardj35165532005-04-30 18:47:48 +0000117
sewardj75ea7982005-11-14 15:18:25 +0000118 /*--------------------- x86 ---------------------*/
sewardj35165532005-04-30 18:47:48 +0000119
sewardj75ea7982005-11-14 15:18:25 +0000120 /* fp is %ebp. sp is %esp. ip is %eip. */
121
sewardjb8b79ad2008-03-03 01:35:41 +0000122 if (sps) sps[0] = sp;
123 if (fps) fps[0] = fp;
sewardj75ea7982005-11-14 15:18:25 +0000124 ips[0] = ip;
125 i = 1;
126
127 /* Loop unwinding the stack. Note that the IP value we get on
128 * each pass (whether from CFI info or a stack frame) is a
129 * return address so is actually after the calling instruction
130 * in the calling function.
131 *
132 * Because of this we subtract one from the IP after each pass
133 * of the loop so that we find the right CFI block on the next
134 * pass - otherwise we can find the wrong CFI info if it happens
135 * to change after the calling instruction and that will mean
136 * that we will fail to unwind the next step.
137 *
138 * This most frequently happens at the end of a function when
139 * a tail call occurs and we wind up using the CFI info for the
140 * next function which is completely wrong.
sewardjb8b79ad2008-03-03 01:35:41 +0000141 *
142 * Note that VG_(get_data_description) (in m_debuginfo) has to take
143 * this same problem into account when unwinding the stack to
144 * examine local variable descriptions (as documented therein in
145 * comments).
sewardj75ea7982005-11-14 15:18:25 +0000146 */
147 while (True) {
148
149 if (i >= n_ips)
150 break;
151
152 /* Try to derive a new (ip,sp,fp) triple from the current
153 set. */
154
155 /* On x86, first try the old-fashioned method of following the
156 %ebp-chain. Code which doesn't use this (that is, compiled
157 with -fomit-frame-pointer) is not ABI compliant and so
158 relatively rare. Besides, trying the CFI first almost always
159 fails, and is expensive. */
160 /* Deal with frames resulting from functions which begin "pushl%
161 ebp ; movl %esp, %ebp" which is the ABI-mandated preamble. */
162 if (fp_min <= fp && fp <= fp_max) {
163 /* fp looks sane, so use it. */
164 ip = (((UWord*)fp)[1]);
165 sp = fp + sizeof(Addr) /*saved %ebp*/
166 + sizeof(Addr) /*ra*/;
167 fp = (((UWord*)fp)[0]);
sewardjb8b79ad2008-03-03 01:35:41 +0000168 if (sps) sps[i] = sp;
169 if (fps) fps[i] = fp;
sewardj75ea7982005-11-14 15:18:25 +0000170 ips[i++] = ip;
171 if (debug)
dirke4067232007-10-04 21:36:40 +0000172 VG_(printf)(" ipsF[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardj75ea7982005-11-14 15:18:25 +0000173 ip = ip - 1;
174 continue;
175 }
176
sewardj15338c52006-10-17 01:31:58 +0000177 /* That didn't work out, so see if there is any CF info to hand
sewardj75ea7982005-11-14 15:18:25 +0000178 which can be used. */
sewardjeadcd862006-04-04 15:12:44 +0000179 if ( VG_(use_CF_info)( &ip, &sp, &fp, fp_min, fp_max ) ) {
sewardjb8b79ad2008-03-03 01:35:41 +0000180 if (sps) sps[i] = sp;
181 if (fps) fps[i] = fp;
sewardj75ea7982005-11-14 15:18:25 +0000182 ips[i++] = ip;
183 if (debug)
dirke4067232007-10-04 21:36:40 +0000184 VG_(printf)(" ipsC[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardj75ea7982005-11-14 15:18:25 +0000185 ip = ip - 1;
186 continue;
187 }
188
189 /* No luck. We have to give up. */
190 break;
191 }
192
193# elif defined(VGP_amd64_linux)
194
195 /*--------------------- amd64 ---------------------*/
196
197 /* fp is %rbp. sp is %rsp. ip is %rip. */
sewardj35165532005-04-30 18:47:48 +0000198
sewardjacaec5f2005-08-19 16:02:59 +0000199 ips[0] = ip;
sewardjb8b79ad2008-03-03 01:35:41 +0000200 if (sps) sps[0] = sp;
201 if (fps) fps[0] = fp;
sewardjacaec5f2005-08-19 16:02:59 +0000202 i = 1;
sewardj35165532005-04-30 18:47:48 +0000203
tomac35f102005-11-05 00:17:21 +0000204 /* Loop unwinding the stack. Note that the IP value we get on
205 * each pass (whether from CFI info or a stack frame) is a
206 * return address so is actually after the calling instruction
207 * in the calling function.
208 *
209 * Because of this we subtract one from the IP after each pass
210 * of the loop so that we find the right CFI block on the next
211 * pass - otherwise we can find the wrong CFI info if it happens
212 * to change after the calling instruction and that will mean
213 * that we will fail to unwind the next step.
214 *
215 * This most frequently happens at the end of a function when
216 * a tail call occurs and we wind up using the CFI info for the
217 * next function which is completely wrong.
sewardjb8b79ad2008-03-03 01:35:41 +0000218 *
219 * Note that VG_(get_data_description) (in m_debuginfo) has to take
220 * this same problem into account when unwinding the stack to
221 * examine local variable descriptions (as documented therein in
222 * comments).
tomac35f102005-11-05 00:17:21 +0000223 */
sewardjacaec5f2005-08-19 16:02:59 +0000224 while (True) {
sewardj35165532005-04-30 18:47:48 +0000225
sewardjacaec5f2005-08-19 16:02:59 +0000226 if (i >= n_ips)
sewardj35165532005-04-30 18:47:48 +0000227 break;
sewardjacaec5f2005-08-19 16:02:59 +0000228
229 /* Try to derive a new (ip,sp,fp) triple from the current
230 set. */
231
232 /* First off, see if there is any CFI info to hand which can
233 be used. */
sewardjeadcd862006-04-04 15:12:44 +0000234 if ( VG_(use_CF_info)( &ip, &sp, &fp, fp_min, fp_max ) ) {
sewardjb8b79ad2008-03-03 01:35:41 +0000235 if (sps) sps[i] = sp;
236 if (fps) fps[i] = fp;
sewardjacaec5f2005-08-19 16:02:59 +0000237 ips[i++] = ip;
238 if (debug)
239 VG_(printf)(" ipsC[%d]=%08p\n", i-1, ips[i-1]);
tom121d1d02005-11-04 11:31:33 +0000240 ip = ip - 1;
sewardjacaec5f2005-08-19 16:02:59 +0000241 continue;
njnd01fef72005-03-25 23:35:48 +0000242 }
sewardj35165532005-04-30 18:47:48 +0000243
sewardjeadcd862006-04-04 15:12:44 +0000244 /* If VG_(use_CF_info) fails, it won't modify ip/sp/fp, so
sewardjacaec5f2005-08-19 16:02:59 +0000245 we can safely try the old-fashioned method. */
246 /* This bit is supposed to deal with frames resulting from
sewardj75ea7982005-11-14 15:18:25 +0000247 functions which begin "pushq %rbp ; movq %rsp, %rbp".
248 Unfortunately, since we can't (easily) look at the insns at
249 the start of the fn, like GDB does, there's no reliable way
250 to tell. Hence the hack of first trying out CFI, and if that
251 fails, then use this as a fallback. */
sewardjacaec5f2005-08-19 16:02:59 +0000252 if (fp_min <= fp && fp <= fp_max) {
253 /* fp looks sane, so use it. */
254 ip = (((UWord*)fp)[1]);
sewardj75ea7982005-11-14 15:18:25 +0000255 sp = fp + sizeof(Addr) /*saved %rbp*/
sewardjacaec5f2005-08-19 16:02:59 +0000256 + sizeof(Addr) /*ra*/;
257 fp = (((UWord*)fp)[0]);
sewardjb8b79ad2008-03-03 01:35:41 +0000258 if (sps) sps[i] = sp;
259 if (fps) fps[i] = fp;
sewardjacaec5f2005-08-19 16:02:59 +0000260 ips[i++] = ip;
261 if (debug)
262 VG_(printf)(" ipsF[%d]=%08p\n", i-1, ips[i-1]);
tom121d1d02005-11-04 11:31:33 +0000263 ip = ip - 1;
sewardjacaec5f2005-08-19 16:02:59 +0000264 continue;
265 }
266
sewardj39f34232007-11-09 23:02:28 +0000267 /* Last-ditch hack (evidently GDB does something similar). We
268 are in the middle of nowhere and we have a nonsense value for
269 the frame pointer. If the stack pointer is still valid,
270 assume that what it points at is a return address. Yes,
271 desperate measures. Could do better here:
272 - check that the supposed return address is in
273 an executable page
274 - check that the supposed return address is just after a call insn
275 - given those two checks, don't just consider *sp as the return
276 address; instead scan a likely section of stack (eg sp .. sp+256)
277 and use suitable values found there.
278 */
279 if (fp_min <= sp && sp < fp_max) {
280 ip = ((UWord*)sp)[0];
sewardjb8b79ad2008-03-03 01:35:41 +0000281 if (sps) sps[i] = sp;
282 if (fps) fps[i] = fp;
sewardj39f34232007-11-09 23:02:28 +0000283 ips[i++] = ip;
284 if (debug)
285 VG_(printf)(" ipsH[%d]=%08p\n", i-1, ips[i-1]);
286 ip = ip - 1;
287 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];
338 if (VG_(get_fnname_nodemangle) (lr, buf_lr, M_VG_ERRTXT))
339 if (VG_(get_fnname_nodemangle) (ip, buf_ip, M_VG_ERRTXT))
340 if (VG_(strncmp)(buf_lr, buf_ip, M_VG_ERRTXT))
341 lr_is_first_RA = True;
342# undef M_VG_ERRTXT
343 }
344
sewardjb8b79ad2008-03-03 01:35:41 +0000345 if (sps) sps[0] = fp; /* NB. not sp */
346 if (fps) fps[0] = fp;
sewardjacaec5f2005-08-19 16:02:59 +0000347 ips[0] = ip;
348 i = 1;
sewardjacaec5f2005-08-19 16:02:59 +0000349
sewardjdb2ac812005-12-23 23:33:51 +0000350 if (fp_min <= fp && fp < fp_max-VG_WORDSIZE+1) {
sewardjacaec5f2005-08-19 16:02:59 +0000351
sewardj525e2322005-11-13 02:41:35 +0000352 /* initial FP is sane; keep going */
353 fp = (((UWord*)fp)[0]);
354
355 while (True) {
356
sewardj15338c52006-10-17 01:31:58 +0000357 /* On ppc64-linux (ppc64-elf, really), and on AIX, the lr save
358 slot is 2 words back from sp, whereas on ppc32-elf(?) it's
359 only one word back. */
360# if defined(VGP_ppc64_linux) \
361 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
sewardjdfbaa222006-01-18 04:25:20 +0000362 const Int lr_offset = 2;
363# else
364 const Int lr_offset = 1;
365# endif
sewardjdb2ac812005-12-23 23:33:51 +0000366
sewardj525e2322005-11-13 02:41:35 +0000367 if (i >= n_ips)
368 break;
369
370 /* Try to derive a new (ip,fp) pair from the current set. */
371
372 if (fp_min <= fp && fp <= fp_max) {
373 /* fp looks sane, so use it. */
374
375 if (i == 1 && lr_is_first_RA)
376 ip = lr;
377 else
sewardjdb2ac812005-12-23 23:33:51 +0000378 ip = (((UWord*)fp)[lr_offset]);
sewardj525e2322005-11-13 02:41:35 +0000379
sewardj15338c52006-10-17 01:31:58 +0000380# if defined(VG_PLAT_USES_PPCTOC)
sewardjdfbaa222006-01-18 04:25:20 +0000381 /* Nasty hack to do with function replacement/wrapping on
sewardj15338c52006-10-17 01:31:58 +0000382 ppc64-linux/ppc64-aix/ppc32-aix. If LR points to our
383 magic return stub, then we are in a wrapped or
384 intercepted function, in which LR has been messed with.
385 The original LR will have been pushed onto the thread's
386 hidden REDIR stack one down from the top (top element
387 is the saved R2) and so we should restore the value
388 from there instead. Since nested redirections can and
389 do happen, we keep track of the number of nested LRs
390 used by the unwinding so far with 'redirs_used'. */
391 if (ip == (Addr)&VG_(ppctoc_magic_redirect_return_stub)
sewardjdfbaa222006-01-18 04:25:20 +0000392 && VG_(is_valid_tid)(tid_if_known)) {
sewardjb8b79ad2008-03-03 01:35:41 +0000393 Word hsp = VG_(threads)[tid_if_known]
394 .arch.vex.guest_REDIR_SP;
sewardj15338c52006-10-17 01:31:58 +0000395 hsp -= 2 * redirs_used;
396 redirs_used ++;
397 if (hsp >= 1 && hsp < redir_stack_size)
sewardjdfbaa222006-01-18 04:25:20 +0000398 ip = VG_(threads)[tid_if_known]
399 .arch.vex.guest_REDIR_STACK[hsp-1];
400 }
401# endif
402
sewardj525e2322005-11-13 02:41:35 +0000403 fp = (((UWord*)fp)[0]);
sewardjb8b79ad2008-03-03 01:35:41 +0000404 if (sps) sps[i] = fp; /* NB. not sp */
405 if (fps) fps[i] = fp;
sewardj525e2322005-11-13 02:41:35 +0000406 ips[i++] = ip;
407 if (debug)
408 VG_(printf)(" ipsF[%d]=%08p\n", i-1, ips[i-1]);
409 continue;
410 }
411
412 /* No luck there. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000413 break;
sewardjacaec5f2005-08-19 16:02:59 +0000414 }
sewardjacaec5f2005-08-19 16:02:59 +0000415 }
416
417# else
418# error "Unknown platform"
419# endif
420
njnd01fef72005-03-25 23:35:48 +0000421 n_found = i;
njnd01fef72005-03-25 23:35:48 +0000422 return n_found;
423}
424
sewardjb8b79ad2008-03-03 01:35:41 +0000425UInt VG_(get_StackTrace) ( ThreadId tid,
426 /*OUT*/StackTrace ips, UInt n_ips,
427 /*OUT*/StackTrace sps,
428 /*OUT*/StackTrace fps,
sewardj39f34232007-11-09 23:02:28 +0000429 Word first_ip_delta )
njnd01fef72005-03-25 23:35:48 +0000430{
431 /* thread in thread table */
njnf536bbb2005-06-13 04:21:38 +0000432 Addr ip = VG_(get_IP)(tid);
433 Addr fp = VG_(get_FP)(tid);
434 Addr sp = VG_(get_SP)(tid);
sewardjacaec5f2005-08-19 16:02:59 +0000435 Addr lr = VG_(get_LR)(tid);
njnf536bbb2005-06-13 04:21:38 +0000436 Addr stack_highest_word = VG_(threads)[tid].client_stack_highest_word;
tom690c3c82008-02-08 15:17:07 +0000437 Addr stack_lowest_word = 0;
njnd01fef72005-03-25 23:35:48 +0000438
sewardjb9bce632005-06-21 01:41:34 +0000439# if defined(VGP_x86_linux)
sewardja672ea32006-04-29 18:03:14 +0000440 /* Nasty little hack to deal with syscalls - if libc is using its
441 _dl_sysinfo_int80 function for syscalls (the TLS version does),
442 then ip will always appear to be in that function when doing a
443 syscall, not the actual libc function doing the syscall. This
444 check sees if IP is within that function, and pops the return
445 address off the stack so that ip is placed within the library
446 function calling the syscall. This makes stack backtraces much
447 more useful.
448
449 The function is assumed to look like this (from glibc-2.3.6 sources):
450 _dl_sysinfo_int80:
451 int $0x80
452 ret
453 That is 3 (2+1) bytes long. We could be more thorough and check
454 the 3 bytes of the function are as expected, but I can't be
455 bothered.
456 */
457 if (VG_(client__dl_sysinfo_int80) != 0 /* we know its address */
458 && ip >= VG_(client__dl_sysinfo_int80)
459 && ip < VG_(client__dl_sysinfo_int80)+3
sewardj45f4e7c2005-09-27 19:20:21 +0000460 && VG_(am_is_valid_for_client)(sp, sizeof(Addr), VKI_PROT_READ)) {
njnd01fef72005-03-25 23:35:48 +0000461 ip = *(Addr *)sp;
462 sp += sizeof(Addr);
463 }
sewardjb9bce632005-06-21 01:41:34 +0000464# endif
465
tom690c3c82008-02-08 15:17:07 +0000466 /* See if we can get a better idea of the stack limits */
467 VG_(stack_limits)(sp, &stack_lowest_word, &stack_highest_word);
468
sewardj39f34232007-11-09 23:02:28 +0000469 /* Take into account the first_ip_delta. */
470 vg_assert( sizeof(Addr) == sizeof(Word) );
471 ip += first_ip_delta;
472
njnd01fef72005-03-25 23:35:48 +0000473 if (0)
sewardjb8b79ad2008-03-03 01:35:41 +0000474 VG_(printf)("tid %d: stack_highest=0x%08lx ip=0x%08lx "
475 "sp=0x%08lx fp=0x%08lx\n",
njnd01fef72005-03-25 23:35:48 +0000476 tid, stack_highest_word, ip, sp, fp);
477
sewardjb8b79ad2008-03-03 01:35:41 +0000478 return VG_(get_StackTrace_wrk)(tid, ips, n_ips,
479 sps, fps,
480 ip, sp, fp, lr, sp,
481 stack_highest_word);
njnd01fef72005-03-25 23:35:48 +0000482}
483
484static void printIpDesc(UInt n, Addr ip)
485{
njn83f9e792005-06-11 05:04:09 +0000486 #define BUF_LEN 4096
487
488 static UChar buf[BUF_LEN];
njnd01fef72005-03-25 23:35:48 +0000489
njn83f9e792005-06-11 05:04:09 +0000490 VG_(describe_IP)(ip, buf, BUF_LEN);
sewardj71bc3cb2005-05-19 00:25:45 +0000491
492 if (VG_(clo_xml)) {
493 VG_(message)(Vg_UserMsg, " %s", buf);
494 } else {
495 VG_(message)(Vg_UserMsg, " %s %s", ( n == 0 ? "at" : "by" ), buf);
496 }
njnd01fef72005-03-25 23:35:48 +0000497}
498
499/* Print a StackTrace. */
500void VG_(pp_StackTrace) ( StackTrace ips, UInt n_ips )
501{
502 vg_assert( n_ips > 0 );
sewardj71bc3cb2005-05-19 00:25:45 +0000503
504 if (VG_(clo_xml))
505 VG_(message)(Vg_UserMsg, " <stack>");
506
njnd01fef72005-03-25 23:35:48 +0000507 VG_(apply_StackTrace)( printIpDesc, ips, n_ips );
sewardj71bc3cb2005-05-19 00:25:45 +0000508
509 if (VG_(clo_xml))
510 VG_(message)(Vg_UserMsg, " </stack>");
njnd01fef72005-03-25 23:35:48 +0000511}
512
513/* Get and immediately print a StackTrace. */
514void VG_(get_and_pp_StackTrace) ( ThreadId tid, UInt n_ips )
515{
516 Addr ips[n_ips];
sewardjb8b79ad2008-03-03 01:35:41 +0000517 UInt n_ips_obtained
518 = VG_(get_StackTrace)(tid, ips, n_ips,
519 NULL/*array to dump SP values in*/,
520 NULL/*array to dump FP values in*/,
521 0/*first_ip_delta*/);
njn88d3ba82006-08-13 04:48:25 +0000522 VG_(pp_StackTrace)(ips, n_ips_obtained);
njnd01fef72005-03-25 23:35:48 +0000523}
524
525
526void VG_(apply_StackTrace)( void(*action)(UInt n, Addr ip),
527 StackTrace ips, UInt n_ips )
528{
sewardj73cf4c62005-11-17 15:12:34 +0000529 #define MYBUF_LEN 50 // only needs to be long enough for
530 // the names specially tested for
njnd01fef72005-03-25 23:35:48 +0000531
532 Bool main_done = False;
533 Char mybuf[MYBUF_LEN]; // ok to stack allocate mybuf[] -- it's tiny
534 Int i = 0;
535
536 vg_assert(n_ips > 0);
537 do {
538 Addr ip = ips[i];
539 if (i > 0)
njnaf839f52005-06-23 03:27:57 +0000540 ip -= VG_MIN_INSTR_SZB; // point to calling line
njnd01fef72005-03-25 23:35:48 +0000541
sewardj73cf4c62005-11-17 15:12:34 +0000542 // Stop after the first appearance of "main" or one of the other names
543 // (the appearance of which is a pretty good sign that we've gone past
544 // main without seeing it, for whatever reason)
njnd01fef72005-03-25 23:35:48 +0000545 if ( ! VG_(clo_show_below_main)) {
546 VG_(get_fnname_nodemangle)( ip, mybuf, MYBUF_LEN );
sewardj73cf4c62005-11-17 15:12:34 +0000547 mybuf[MYBUF_LEN-1] = 0; // paranoia
548 if ( VG_STREQ("main", mybuf)
549# if defined(VGO_linux)
sewardj1a85f4f2006-01-12 21:15:35 +0000550 || VG_STREQ("__libc_start_main", mybuf) // glibc glibness
551 || VG_STREQ("generic_start_main", mybuf) // Yellow Dog doggedness
sewardj73cf4c62005-11-17 15:12:34 +0000552# endif
553 )
njnd01fef72005-03-25 23:35:48 +0000554 main_done = True;
njnd01fef72005-03-25 23:35:48 +0000555 }
556
557 // Act on the ip
558 action(i, ip);
559
560 i++;
sewardj73cf4c62005-11-17 15:12:34 +0000561 } while (i < n_ips && ips[i] != 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/*--------------------------------------------------------------------*/