blob: 7984de32c9541278e6a207db791c255f8cef9847 [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
sewardj9eecbbb2010-05-03 21:37:12 +000010 Copyright (C) 2000-2010 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"
sewardj6c591e12011-04-11 16:17:51 +000033#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
njnc7561b92005-06-19 01:24:32 +000034#include "pub_core_threadstate.h"
njn68824432009-02-10 06:48:00 +000035#include "pub_core_debuginfo.h" // XXX: circular dependency
njn24a6efb2005-06-20 03:36:51 +000036#include "pub_core_aspacemgr.h" // For VG_(is_addressable)()
njn97405b22005-06-02 03:39:33 +000037#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000038#include "pub_core_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +000039#include "pub_core_libcprint.h"
njnf536bbb2005-06-13 04:21:38 +000040#include "pub_core_machine.h"
njn20242342005-05-16 23:31:24 +000041#include "pub_core_options.h"
sewardj9084de72008-02-11 11:23:12 +000042#include "pub_core_stacks.h" // VG_(stack_limits)
njnd01fef72005-03-25 23:35:48 +000043#include "pub_core_stacktrace.h"
sewardj14c7cc52007-02-25 15:08:24 +000044#include "pub_core_xarray.h"
sewardja672ea32006-04-29 18:03:14 +000045#include "pub_core_clientstate.h" // VG_(client__dl_sysinfo_int80)
njna7598f62005-06-18 03:27:58 +000046#include "pub_core_trampoline.h"
njnd01fef72005-03-25 23:35:48 +000047
sewardj59570ff2010-01-01 11:59:33 +000048
njnd01fef72005-03-25 23:35:48 +000049/*------------------------------------------------------------*/
sewardj59570ff2010-01-01 11:59:33 +000050/*--- ---*/
51/*--- BEGIN platform-dependent unwinder worker functions ---*/
52/*--- ---*/
njnd01fef72005-03-25 23:35:48 +000053/*------------------------------------------------------------*/
54
njn3a4b58f2009-05-07 23:08:10 +000055/* Take a snapshot of the client's stack, putting up to 'max_n_ips'
sewardjacaec5f2005-08-19 16:02:59 +000056 IPs into 'ips'. In order to be thread-safe, we pass in the
57 thread's IP SP, FP if that's meaningful, and LR if that's
58 meaningful. Returns number of IPs put in 'ips'.
sewardjdfbaa222006-01-18 04:25:20 +000059
60 If you know what the thread ID for this stack is, send that as the
61 first parameter, else send zero. This helps generate better stack
62 traces on ppc64-linux and has no effect on other platforms.
sewardjacaec5f2005-08-19 16:02:59 +000063*/
sewardj59570ff2010-01-01 11:59:33 +000064
65/* ------------------------ x86 ------------------------- */
66
67#if defined(VGP_x86_linux) || defined(VGP_x86_darwin)
68
sewardjb8b79ad2008-03-03 01:35:41 +000069UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
njn3a4b58f2009-05-07 23:08:10 +000070 /*OUT*/Addr* ips, UInt max_n_ips,
sewardjb8b79ad2008-03-03 01:35:41 +000071 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
sewardj59570ff2010-01-01 11:59:33 +000072 UnwindStartRegs* startRegs,
73 Addr fp_max_orig )
njnd01fef72005-03-25 23:35:48 +000074{
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
sewardj9365e3f2010-01-01 19:55:17 +000083 D3UnwindRegs uregs;
84 uregs.xip = (Addr)startRegs->r_pc;
85 uregs.xsp = (Addr)startRegs->r_sp;
86 uregs.xbp = startRegs->misc.X86.r_ebp;
87 Addr fp_min = uregs.xsp;
sewardj59570ff2010-01-01 11:59:33 +000088
njn3a4b58f2009-05-07 23:08:10 +000089 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
njnc0ec8e92005-12-25 06:34:04 +000090 stopping when the trail goes cold, which we guess to be
sewardjacaec5f2005-08-19 16:02:59 +000091 when FP is not a reasonable stack location. */
92
njnd01fef72005-03-25 23:35:48 +000093 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
94 // current page, at least. Dunno if it helps.
95 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
sewardj45f4e7c2005-09-27 19:20:21 +000096 fp_max = VG_PGROUNDUP(fp_max_orig);
sewardjd0c0ea62008-03-03 22:20:51 +000097 if (fp_max >= sizeof(Addr))
98 fp_max -= sizeof(Addr);
njnd01fef72005-03-25 23:35:48 +000099
100 if (debug)
njn3a4b58f2009-05-07 23:08:10 +0000101 VG_(printf)("max_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
barta0b6b2c2008-07-07 06:49:24 +0000102 "fp_max=0x%lx ip=0x%lx fp=0x%lx\n",
sewardj9365e3f2010-01-01 19:55:17 +0000103 max_n_ips, fp_min, fp_max_orig, fp_max,
104 uregs.xip, uregs.xbp);
njnd01fef72005-03-25 23:35:48 +0000105
106 /* Assertion broken before main() is reached in pthreaded programs; the
107 * offending stack traces only have one item. --njn, 2002-aug-16 */
108 /* vg_assert(fp_min <= fp_max);*/
njnf76d27a2009-05-28 01:53:07 +0000109 // On Darwin, this kicks in for pthread-related stack traces, so they're
110 // only 1 entry long which is wrong.
sewardj59570ff2010-01-01 11:59:33 +0000111# if !defined(VGO_darwin)
sewardj5bdfbd22007-12-15 22:13:05 +0000112 if (fp_min + 512 >= fp_max) {
113 /* If the stack limits look bogus, don't poke around ... but
114 don't bomb out either. */
sewardj9365e3f2010-01-01 19:55:17 +0000115 if (sps) sps[0] = uregs.xsp;
116 if (fps) fps[0] = uregs.xbp;
117 ips[0] = uregs.xip;
sewardjacaec5f2005-08-19 16:02:59 +0000118 return 1;
119 }
sewardj59570ff2010-01-01 11:59:33 +0000120# endif
sewardj35165532005-04-30 18:47:48 +0000121
sewardj75ea7982005-11-14 15:18:25 +0000122 /* fp is %ebp. sp is %esp. ip is %eip. */
123
sewardj9365e3f2010-01-01 19:55:17 +0000124 if (sps) sps[0] = uregs.xsp;
125 if (fps) fps[0] = uregs.xbp;
126 ips[0] = uregs.xip;
sewardj75ea7982005-11-14 15:18:25 +0000127 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
njn3a4b58f2009-05-07 23:08:10 +0000146 if (i >= max_n_ips)
sewardj75ea7982005-11-14 15:18:25 +0000147 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. */
sewardj9365e3f2010-01-01 19:55:17 +0000159 if (fp_min <= uregs.xbp &&
160 uregs.xbp <= fp_max - 1 * sizeof(UWord)/*see comment below*/)
njn3a4b58f2009-05-07 23:08:10 +0000161 {
sewardj75ea7982005-11-14 15:18:25 +0000162 /* fp looks sane, so use it. */
sewardj9365e3f2010-01-01 19:55:17 +0000163 uregs.xip = (((UWord*)uregs.xbp)[1]);
njn3a4b58f2009-05-07 23:08:10 +0000164 // We stop if we hit a zero (the traditional end-of-stack
165 // marker) or a one -- these correspond to recorded IPs of 0 or -1.
166 // The latter because r8818 (in this file) changes the meaning of
167 // entries [1] and above in a stack trace, by subtracting 1 from
168 // them. Hence stacks that used to end with a zero value now end in
169 // -1 and so we must detect that too.
sewardj9365e3f2010-01-01 19:55:17 +0000170 if (0 == uregs.xip || 1 == uregs.xip) break;
171 uregs.xsp = uregs.xbp + sizeof(Addr) /*saved %ebp*/
172 + sizeof(Addr) /*ra*/;
173 uregs.xbp = (((UWord*)uregs.xbp)[0]);
174 if (sps) sps[i] = uregs.xsp;
175 if (fps) fps[i] = uregs.xbp;
176 ips[i++] = uregs.xip - 1; /* -1: refer to calling insn, not the RA */
sewardj75ea7982005-11-14 15:18:25 +0000177 if (debug)
dirke4067232007-10-04 21:36:40 +0000178 VG_(printf)(" ipsF[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000179 uregs.xip = uregs.xip - 1;
180 /* as per comment at the head of this loop */
sewardj75ea7982005-11-14 15:18:25 +0000181 continue;
182 }
183
sewardj15338c52006-10-17 01:31:58 +0000184 /* That didn't work out, so see if there is any CF info to hand
sewardj75ea7982005-11-14 15:18:25 +0000185 which can be used. */
sewardj9365e3f2010-01-01 19:55:17 +0000186 if ( VG_(use_CF_info)( &uregs, fp_min, fp_max ) ) {
187 if (0 == uregs.xip || 1 == uregs.xip) break;
188 if (sps) sps[i] = uregs.xsp;
189 if (fps) fps[i] = uregs.xbp;
190 ips[i++] = uregs.xip - 1; /* -1: refer to calling insn, not the RA */
sewardj75ea7982005-11-14 15:18:25 +0000191 if (debug)
dirke4067232007-10-04 21:36:40 +0000192 VG_(printf)(" ipsC[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000193 uregs.xip = uregs.xip - 1;
194 /* as per comment at the head of this loop */
sewardj75ea7982005-11-14 15:18:25 +0000195 continue;
196 }
197
sewardjc8259b82009-04-22 22:42:10 +0000198 /* And, similarly, try for MSVC FPO unwind info. */
sewardj9365e3f2010-01-01 19:55:17 +0000199 if ( VG_(use_FPO_info)( &uregs.xip, &uregs.xsp, &uregs.xbp,
200 fp_min, fp_max ) ) {
201 if (0 == uregs.xip || 1 == uregs.xip) break;
202 if (sps) sps[i] = uregs.xsp;
203 if (fps) fps[i] = uregs.xbp;
204 ips[i++] = uregs.xip;
sewardjc8259b82009-04-22 22:42:10 +0000205 if (debug)
206 VG_(printf)(" ipsC[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000207 uregs.xip = uregs.xip - 1;
sewardjc8259b82009-04-22 22:42:10 +0000208 continue;
209 }
210
sewardj75ea7982005-11-14 15:18:25 +0000211 /* No luck. We have to give up. */
212 break;
213 }
214
sewardj59570ff2010-01-01 11:59:33 +0000215 n_found = i;
216 return n_found;
217}
sewardj75ea7982005-11-14 15:18:25 +0000218
sewardj59570ff2010-01-01 11:59:33 +0000219#endif
220
221/* ----------------------- amd64 ------------------------ */
222
223#if defined(VGP_amd64_linux) || defined(VGP_amd64_darwin)
224
225UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
226 /*OUT*/Addr* ips, UInt max_n_ips,
227 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
228 UnwindStartRegs* startRegs,
229 Addr fp_max_orig )
230{
231 Bool debug = False;
232 Int i;
233 Addr fp_max;
234 UInt n_found = 0;
235
236 vg_assert(sizeof(Addr) == sizeof(UWord));
237 vg_assert(sizeof(Addr) == sizeof(void*));
238
sewardj9365e3f2010-01-01 19:55:17 +0000239 D3UnwindRegs uregs;
240 uregs.xip = startRegs->r_pc;
241 uregs.xsp = startRegs->r_sp;
242 uregs.xbp = startRegs->misc.AMD64.r_rbp;
243 Addr fp_min = uregs.xsp;
sewardj59570ff2010-01-01 11:59:33 +0000244
245 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
246 stopping when the trail goes cold, which we guess to be
247 when FP is not a reasonable stack location. */
248
249 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
250 // current page, at least. Dunno if it helps.
251 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
252 fp_max = VG_PGROUNDUP(fp_max_orig);
253 if (fp_max >= sizeof(Addr))
254 fp_max -= sizeof(Addr);
255
256 if (debug)
257 VG_(printf)("max_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
258 "fp_max=0x%lx ip=0x%lx fp=0x%lx\n",
sewardj9365e3f2010-01-01 19:55:17 +0000259 max_n_ips, fp_min, fp_max_orig, fp_max,
260 uregs.xip, uregs.xbp);
sewardj59570ff2010-01-01 11:59:33 +0000261
262 /* Assertion broken before main() is reached in pthreaded programs; the
263 * offending stack traces only have one item. --njn, 2002-aug-16 */
264 /* vg_assert(fp_min <= fp_max);*/
265 // On Darwin, this kicks in for pthread-related stack traces, so they're
266 // only 1 entry long which is wrong.
267# if !defined(VGO_darwin)
sewardjf2522992010-10-06 22:45:18 +0000268 if (fp_min + 256 >= fp_max) {
sewardj59570ff2010-01-01 11:59:33 +0000269 /* If the stack limits look bogus, don't poke around ... but
270 don't bomb out either. */
sewardj9365e3f2010-01-01 19:55:17 +0000271 if (sps) sps[0] = uregs.xsp;
272 if (fps) fps[0] = uregs.xbp;
273 ips[0] = uregs.xip;
sewardj59570ff2010-01-01 11:59:33 +0000274 return 1;
275 }
276# endif
sewardj75ea7982005-11-14 15:18:25 +0000277
278 /* fp is %rbp. sp is %rsp. ip is %rip. */
sewardj35165532005-04-30 18:47:48 +0000279
sewardj9365e3f2010-01-01 19:55:17 +0000280 ips[0] = uregs.xip;
281 if (sps) sps[0] = uregs.xsp;
282 if (fps) fps[0] = uregs.xbp;
sewardjacaec5f2005-08-19 16:02:59 +0000283 i = 1;
sewardj35165532005-04-30 18:47:48 +0000284
tomac35f102005-11-05 00:17:21 +0000285 /* Loop unwinding the stack. Note that the IP value we get on
286 * each pass (whether from CFI info or a stack frame) is a
287 * return address so is actually after the calling instruction
288 * in the calling function.
289 *
290 * Because of this we subtract one from the IP after each pass
291 * of the loop so that we find the right CFI block on the next
292 * pass - otherwise we can find the wrong CFI info if it happens
293 * to change after the calling instruction and that will mean
294 * that we will fail to unwind the next step.
295 *
296 * This most frequently happens at the end of a function when
297 * a tail call occurs and we wind up using the CFI info for the
298 * next function which is completely wrong.
299 */
sewardjacaec5f2005-08-19 16:02:59 +0000300 while (True) {
sewardj35165532005-04-30 18:47:48 +0000301
njn3a4b58f2009-05-07 23:08:10 +0000302 if (i >= max_n_ips)
sewardj35165532005-04-30 18:47:48 +0000303 break;
sewardjacaec5f2005-08-19 16:02:59 +0000304
njn3a4b58f2009-05-07 23:08:10 +0000305 /* Try to derive a new (ip,sp,fp) triple from the current set. */
sewardjacaec5f2005-08-19 16:02:59 +0000306
307 /* First off, see if there is any CFI info to hand which can
308 be used. */
sewardj9365e3f2010-01-01 19:55:17 +0000309 if ( VG_(use_CF_info)( &uregs, fp_min, fp_max ) ) {
310 if (0 == uregs.xip || 1 == uregs.xip) break;
311 if (sps) sps[i] = uregs.xsp;
312 if (fps) fps[i] = uregs.xbp;
313 ips[i++] = uregs.xip - 1; /* -1: refer to calling insn, not the RA */
sewardjacaec5f2005-08-19 16:02:59 +0000314 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000315 VG_(printf)(" ipsC[%d]=%#08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000316 uregs.xip = uregs.xip - 1; /* as per comment at the head of this loop */
sewardjacaec5f2005-08-19 16:02:59 +0000317 continue;
njnd01fef72005-03-25 23:35:48 +0000318 }
sewardj35165532005-04-30 18:47:48 +0000319
sewardjeadcd862006-04-04 15:12:44 +0000320 /* If VG_(use_CF_info) fails, it won't modify ip/sp/fp, so
sewardjacaec5f2005-08-19 16:02:59 +0000321 we can safely try the old-fashioned method. */
322 /* This bit is supposed to deal with frames resulting from
sewardj75ea7982005-11-14 15:18:25 +0000323 functions which begin "pushq %rbp ; movq %rsp, %rbp".
324 Unfortunately, since we can't (easily) look at the insns at
325 the start of the fn, like GDB does, there's no reliable way
326 to tell. Hence the hack of first trying out CFI, and if that
327 fails, then use this as a fallback. */
sewardjf98e1c02008-10-25 16:22:41 +0000328 /* Note: re "- 1 * sizeof(UWord)", need to take account of the
329 fact that we are prodding at & ((UWord*)fp)[1] and so need to
330 adjust the limit check accordingly. Omitting this has been
331 observed to cause segfaults on rare occasions. */
sewardj9365e3f2010-01-01 19:55:17 +0000332 if (fp_min <= uregs.xbp && uregs.xbp <= fp_max - 1 * sizeof(UWord)) {
sewardjacaec5f2005-08-19 16:02:59 +0000333 /* fp looks sane, so use it. */
sewardj9365e3f2010-01-01 19:55:17 +0000334 uregs.xip = (((UWord*)uregs.xbp)[1]);
335 if (0 == uregs.xip || 1 == uregs.xip) break;
336 uregs.xsp = uregs.xbp + sizeof(Addr) /*saved %rbp*/
337 + sizeof(Addr) /*ra*/;
338 uregs.xbp = (((UWord*)uregs.xbp)[0]);
339 if (sps) sps[i] = uregs.xsp;
340 if (fps) fps[i] = uregs.xbp;
341 ips[i++] = uregs.xip - 1; /* -1: refer to calling insn, not the RA */
sewardjacaec5f2005-08-19 16:02:59 +0000342 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000343 VG_(printf)(" ipsF[%d]=%#08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000344 uregs.xip = uregs.xip - 1; /* as per comment at the head of this loop */
sewardjacaec5f2005-08-19 16:02:59 +0000345 continue;
346 }
347
sewardj39f34232007-11-09 23:02:28 +0000348 /* Last-ditch hack (evidently GDB does something similar). We
349 are in the middle of nowhere and we have a nonsense value for
350 the frame pointer. If the stack pointer is still valid,
351 assume that what it points at is a return address. Yes,
352 desperate measures. Could do better here:
353 - check that the supposed return address is in
354 an executable page
355 - check that the supposed return address is just after a call insn
356 - given those two checks, don't just consider *sp as the return
357 address; instead scan a likely section of stack (eg sp .. sp+256)
358 and use suitable values found there.
359 */
sewardj9365e3f2010-01-01 19:55:17 +0000360 if (fp_min <= uregs.xsp && uregs.xsp < fp_max) {
361 uregs.xip = ((UWord*)uregs.xsp)[0];
362 if (0 == uregs.xip || 1 == uregs.xip) break;
363 if (sps) sps[i] = uregs.xsp;
364 if (fps) fps[i] = uregs.xbp;
365 ips[i++] = uregs.xip == 0
sewardjb1ae15d2008-12-12 13:23:03 +0000366 ? 0 /* sp[0] == 0 ==> stuck at the bottom of a
367 thread stack */
sewardj9365e3f2010-01-01 19:55:17 +0000368 : uregs.xip - 1;
369 /* -1: refer to calling insn, not the RA */
sewardj39f34232007-11-09 23:02:28 +0000370 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000371 VG_(printf)(" ipsH[%d]=%#08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000372 uregs.xip = uregs.xip - 1; /* as per comment at the head of this loop */
373 uregs.xsp += 8;
sewardj39f34232007-11-09 23:02:28 +0000374 continue;
375 }
376
377 /* No luck at all. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000378 break;
njnd01fef72005-03-25 23:35:48 +0000379 }
sewardjacaec5f2005-08-19 16:02:59 +0000380
sewardj59570ff2010-01-01 11:59:33 +0000381 n_found = i;
382 return n_found;
383}
sewardjacaec5f2005-08-19 16:02:59 +0000384
sewardj59570ff2010-01-01 11:59:33 +0000385#endif
386
387/* -----------------------ppc32/64 ---------------------- */
388
389#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
390 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
391
392UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
393 /*OUT*/Addr* ips, UInt max_n_ips,
394 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
sewardjf5f1e122010-01-02 13:24:58 +0000395 UnwindStartRegs* startRegs,
396 Addr fp_max_orig )
sewardj59570ff2010-01-01 11:59:33 +0000397{
398 Bool lr_is_first_RA = False;
399# if defined(VG_PLAT_USES_PPCTOC)
400 Word redir_stack_size = 0;
401 Word redirs_used = 0;
402# endif
403
404 Bool debug = False;
405 Int i;
406 Addr fp_max;
407 UInt n_found = 0;
408
409 vg_assert(sizeof(Addr) == sizeof(UWord));
410 vg_assert(sizeof(Addr) == sizeof(void*));
411
sewardjf5f1e122010-01-02 13:24:58 +0000412 Addr ip = (Addr)startRegs->r_pc;
413 Addr sp = (Addr)startRegs->r_sp;
414 Addr fp = sp;
415# if defined(VGP_ppc32_linux) || defined(VGP_ppc32_aix5)
416 Addr lr = startRegs->misc.PPC32.r_lr;
417# elif defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
418 Addr lr = startRegs->misc.PPC64.r_lr;
419# endif
420 Addr fp_min = sp;
421
sewardj59570ff2010-01-01 11:59:33 +0000422 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
423 stopping when the trail goes cold, which we guess to be
424 when FP is not a reasonable stack location. */
425
426 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
427 // current page, at least. Dunno if it helps.
428 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
429 fp_max = VG_PGROUNDUP(fp_max_orig);
430 if (fp_max >= sizeof(Addr))
431 fp_max -= sizeof(Addr);
432
433 if (debug)
434 VG_(printf)("max_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
435 "fp_max=0x%lx ip=0x%lx fp=0x%lx\n",
436 max_n_ips, fp_min, fp_max_orig, fp_max, ip, fp);
437
438 /* Assertion broken before main() is reached in pthreaded programs; the
439 * offending stack traces only have one item. --njn, 2002-aug-16 */
440 /* vg_assert(fp_min <= fp_max);*/
441 if (fp_min + 512 >= fp_max) {
442 /* If the stack limits look bogus, don't poke around ... but
443 don't bomb out either. */
444 if (sps) sps[0] = sp;
445 if (fps) fps[0] = fp;
446 ips[0] = ip;
447 return 1;
448 }
sewardj75ea7982005-11-14 15:18:25 +0000449
sewardjacaec5f2005-08-19 16:02:59 +0000450 /* fp is %r1. ip is %cia. Note, ppc uses r1 as both the stack and
451 frame pointers. */
452
sewardj15338c52006-10-17 01:31:58 +0000453# if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
454 redir_stack_size = VEX_GUEST_PPC64_REDIR_STACK_SIZE;
455 redirs_used = 0;
456# elif defined(VGP_ppc32_aix5)
457 redir_stack_size = VEX_GUEST_PPC32_REDIR_STACK_SIZE;
458 redirs_used = 0;
459# endif
460
461# if defined(VG_PLAT_USES_PPCTOC)
sewardjcfb5e2b2006-01-19 03:47:30 +0000462 /* Deal with bogus LR values caused by function
sewardj15338c52006-10-17 01:31:58 +0000463 interception/wrapping on ppc-TOC platforms; see comment on
464 similar code a few lines further down. */
465 if (ULong_to_Ptr(lr) == (void*)&VG_(ppctoc_magic_redirect_return_stub)
sewardjcfb5e2b2006-01-19 03:47:30 +0000466 && VG_(is_valid_tid)(tid_if_known)) {
sewardj15338c52006-10-17 01:31:58 +0000467 Word hsp = VG_(threads)[tid_if_known].arch.vex.guest_REDIR_SP;
468 redirs_used++;
469 if (hsp >= 1 && hsp < redir_stack_size)
sewardjcfb5e2b2006-01-19 03:47:30 +0000470 lr = VG_(threads)[tid_if_known]
471 .arch.vex.guest_REDIR_STACK[hsp-1];
472 }
473# endif
474
sewardj15338c52006-10-17 01:31:58 +0000475 /* We have to determine whether or not LR currently holds this fn
476 (call it F)'s return address. It might not if F has previously
477 called some other function, hence overwriting LR with a pointer
478 to some part of F. Hence if LR and IP point to the same
479 function then we conclude LR does not hold this function's
480 return address; instead the LR at entry must have been saved in
481 the stack by F's prologue and so we must get it from there
482 instead. Note all this guff only applies to the innermost
483 frame. */
sewardjacaec5f2005-08-19 16:02:59 +0000484 lr_is_first_RA = False;
485 {
486# define M_VG_ERRTXT 1000
487 UChar buf_lr[M_VG_ERRTXT], buf_ip[M_VG_ERRTXT];
sewardjb1ae15d2008-12-12 13:23:03 +0000488 /* The following conditional looks grossly inefficient and
489 surely could be majorly improved, with not much effort. */
njn6b7611b2009-02-11 06:06:10 +0000490 if (VG_(get_fnname_raw) (lr, buf_lr, M_VG_ERRTXT))
491 if (VG_(get_fnname_raw) (ip, buf_ip, M_VG_ERRTXT))
sewardjacaec5f2005-08-19 16:02:59 +0000492 if (VG_(strncmp)(buf_lr, buf_ip, M_VG_ERRTXT))
493 lr_is_first_RA = True;
494# undef M_VG_ERRTXT
495 }
496
sewardjb8b79ad2008-03-03 01:35:41 +0000497 if (sps) sps[0] = fp; /* NB. not sp */
498 if (fps) fps[0] = fp;
sewardjacaec5f2005-08-19 16:02:59 +0000499 ips[0] = ip;
500 i = 1;
sewardjacaec5f2005-08-19 16:02:59 +0000501
sewardjdb2ac812005-12-23 23:33:51 +0000502 if (fp_min <= fp && fp < fp_max-VG_WORDSIZE+1) {
sewardjacaec5f2005-08-19 16:02:59 +0000503
sewardj525e2322005-11-13 02:41:35 +0000504 /* initial FP is sane; keep going */
505 fp = (((UWord*)fp)[0]);
506
507 while (True) {
508
sewardj15338c52006-10-17 01:31:58 +0000509 /* On ppc64-linux (ppc64-elf, really), and on AIX, the lr save
510 slot is 2 words back from sp, whereas on ppc32-elf(?) it's
511 only one word back. */
sewardj59570ff2010-01-01 11:59:33 +0000512# if defined(VG_PLAT_USES_PPCTOC)
sewardjdfbaa222006-01-18 04:25:20 +0000513 const Int lr_offset = 2;
514# else
515 const Int lr_offset = 1;
516# endif
sewardjdb2ac812005-12-23 23:33:51 +0000517
njn3a4b58f2009-05-07 23:08:10 +0000518 if (i >= max_n_ips)
sewardj525e2322005-11-13 02:41:35 +0000519 break;
520
521 /* Try to derive a new (ip,fp) pair from the current set. */
522
sewardjf98e1c02008-10-25 16:22:41 +0000523 if (fp_min <= fp && fp <= fp_max - lr_offset * sizeof(UWord)) {
sewardj525e2322005-11-13 02:41:35 +0000524 /* fp looks sane, so use it. */
525
526 if (i == 1 && lr_is_first_RA)
527 ip = lr;
528 else
sewardjdb2ac812005-12-23 23:33:51 +0000529 ip = (((UWord*)fp)[lr_offset]);
sewardj525e2322005-11-13 02:41:35 +0000530
sewardj15338c52006-10-17 01:31:58 +0000531# if defined(VG_PLAT_USES_PPCTOC)
sewardjdfbaa222006-01-18 04:25:20 +0000532 /* Nasty hack to do with function replacement/wrapping on
sewardj15338c52006-10-17 01:31:58 +0000533 ppc64-linux/ppc64-aix/ppc32-aix. If LR points to our
534 magic return stub, then we are in a wrapped or
535 intercepted function, in which LR has been messed with.
536 The original LR will have been pushed onto the thread's
537 hidden REDIR stack one down from the top (top element
538 is the saved R2) and so we should restore the value
539 from there instead. Since nested redirections can and
540 do happen, we keep track of the number of nested LRs
541 used by the unwinding so far with 'redirs_used'. */
542 if (ip == (Addr)&VG_(ppctoc_magic_redirect_return_stub)
sewardjdfbaa222006-01-18 04:25:20 +0000543 && VG_(is_valid_tid)(tid_if_known)) {
sewardjb8b79ad2008-03-03 01:35:41 +0000544 Word hsp = VG_(threads)[tid_if_known]
545 .arch.vex.guest_REDIR_SP;
sewardj15338c52006-10-17 01:31:58 +0000546 hsp -= 2 * redirs_used;
547 redirs_used ++;
548 if (hsp >= 1 && hsp < redir_stack_size)
sewardjdfbaa222006-01-18 04:25:20 +0000549 ip = VG_(threads)[tid_if_known]
550 .arch.vex.guest_REDIR_STACK[hsp-1];
551 }
552# endif
553
njn3a4b58f2009-05-07 23:08:10 +0000554 if (0 == ip || 1 == ip) break;
sewardjb8b79ad2008-03-03 01:35:41 +0000555 if (sps) sps[i] = fp; /* NB. not sp */
556 if (fps) fps[i] = fp;
tom88053262009-11-12 13:19:41 +0000557 fp = (((UWord*)fp)[0]);
sewardjb1ae15d2008-12-12 13:23:03 +0000558 ips[i++] = ip - 1; /* -1: refer to calling insn, not the RA */
sewardj525e2322005-11-13 02:41:35 +0000559 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000560 VG_(printf)(" ipsF[%d]=%#08lx\n", i-1, ips[i-1]);
sewardjb1ae15d2008-12-12 13:23:03 +0000561 ip = ip - 1; /* ip is probably dead at this point, but
562 play safe, a la x86/amd64 above. See
563 extensive comments above. */
sewardj525e2322005-11-13 02:41:35 +0000564 continue;
565 }
566
567 /* No luck there. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000568 break;
sewardjacaec5f2005-08-19 16:02:59 +0000569 }
sewardjacaec5f2005-08-19 16:02:59 +0000570 }
571
sewardj59570ff2010-01-01 11:59:33 +0000572 n_found = i;
573 return n_found;
574}
575
576#endif
577
578/* ------------------------ arm ------------------------- */
579
580#if defined(VGP_arm_linux)
581
582UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
583 /*OUT*/Addr* ips, UInt max_n_ips,
584 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
585 UnwindStartRegs* startRegs,
586 Addr fp_max_orig )
587{
588 Bool debug = False;
589 Int i;
590 Addr fp_max;
591 UInt n_found = 0;
592
593 vg_assert(sizeof(Addr) == sizeof(UWord));
594 vg_assert(sizeof(Addr) == sizeof(void*));
595
sewardj3026f712010-01-01 18:46:41 +0000596 D3UnwindRegs uregs;
sewardjfa5ce562010-09-23 22:05:59 +0000597 uregs.r15 = startRegs->r_pc & 0xFFFFFFFE;
sewardj3026f712010-01-01 18:46:41 +0000598 uregs.r14 = startRegs->misc.ARM.r14;
599 uregs.r13 = startRegs->r_sp;
600 uregs.r12 = startRegs->misc.ARM.r12;
601 uregs.r11 = startRegs->misc.ARM.r11;
sewardjfa5ce562010-09-23 22:05:59 +0000602 uregs.r7 = startRegs->misc.ARM.r7;
sewardj3026f712010-01-01 18:46:41 +0000603 Addr fp_min = uregs.r13;
sewardj59570ff2010-01-01 11:59:33 +0000604
605 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
606 stopping when the trail goes cold, which we guess to be
607 when FP is not a reasonable stack location. */
608
609 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
610 // current page, at least. Dunno if it helps.
611 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
612 fp_max = VG_PGROUNDUP(fp_max_orig);
613 if (fp_max >= sizeof(Addr))
614 fp_max -= sizeof(Addr);
615
616 if (debug)
sewardjfa5ce562010-09-23 22:05:59 +0000617 VG_(printf)("\nmax_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
sewardj59570ff2010-01-01 11:59:33 +0000618 "fp_max=0x%lx r15=0x%lx r13=0x%lx\n",
sewardj3026f712010-01-01 18:46:41 +0000619 max_n_ips, fp_min, fp_max_orig, fp_max,
620 uregs.r15, uregs.r13);
sewardj59570ff2010-01-01 11:59:33 +0000621
622 /* Assertion broken before main() is reached in pthreaded programs; the
623 * offending stack traces only have one item. --njn, 2002-aug-16 */
624 /* vg_assert(fp_min <= fp_max);*/
625 // On Darwin, this kicks in for pthread-related stack traces, so they're
626 // only 1 entry long which is wrong.
627 if (fp_min + 512 >= fp_max) {
628 /* If the stack limits look bogus, don't poke around ... but
629 don't bomb out either. */
sewardj3026f712010-01-01 18:46:41 +0000630 if (sps) sps[0] = uregs.r13;
sewardj59570ff2010-01-01 11:59:33 +0000631 if (fps) fps[0] = 0;
sewardj3026f712010-01-01 18:46:41 +0000632 ips[0] = uregs.r15;
sewardj59570ff2010-01-01 11:59:33 +0000633 return 1;
634 }
635
636 /* */
637
sewardj3026f712010-01-01 18:46:41 +0000638 if (sps) sps[0] = uregs.r13;
sewardj59570ff2010-01-01 11:59:33 +0000639 if (fps) fps[0] = 0;
sewardj3026f712010-01-01 18:46:41 +0000640 ips[0] = uregs.r15;
sewardj59570ff2010-01-01 11:59:33 +0000641 i = 1;
642
643 /* Loop unwinding the stack. */
644
645 while (True) {
646 if (debug) {
sewardj3026f712010-01-01 18:46:41 +0000647 VG_(printf)("i: %d, r15: 0x%lx, r13: 0x%lx\n",
648 i, uregs.r15, uregs.r13);
sewardj59570ff2010-01-01 11:59:33 +0000649 }
650
651 if (i >= max_n_ips)
652 break;
653
sewardj3026f712010-01-01 18:46:41 +0000654 if (VG_(use_CF_info)( &uregs, fp_min, fp_max )) {
655 if (sps) sps[i] = uregs.r13;
sewardj59570ff2010-01-01 11:59:33 +0000656 if (fps) fps[i] = 0;
sewardjfa5ce562010-09-23 22:05:59 +0000657 ips[i++] = (uregs.r15 & 0xFFFFFFFE) - 1;
sewardj59570ff2010-01-01 11:59:33 +0000658 if (debug)
sewardj3026f712010-01-01 18:46:41 +0000659 VG_(printf)("USING CFI: r15: 0x%lx, r13: 0x%lx\n",
660 uregs.r15, uregs.r13);
sewardjfa5ce562010-09-23 22:05:59 +0000661 uregs.r15 = (uregs.r15 & 0xFFFFFFFE) - 1;
sewardj59570ff2010-01-01 11:59:33 +0000662 continue;
663 }
664 /* No luck. We have to give up. */
665 break;
666 }
sewardjacaec5f2005-08-19 16:02:59 +0000667
njnd01fef72005-03-25 23:35:48 +0000668 n_found = i;
njnd01fef72005-03-25 23:35:48 +0000669 return n_found;
670}
671
sewardj59570ff2010-01-01 11:59:33 +0000672#endif
673
sewardjb5b87402011-03-07 16:05:35 +0000674/* ------------------------ s390x ------------------------- */
675#if defined(VGP_s390x_linux)
676UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
677 /*OUT*/Addr* ips, UInt max_n_ips,
678 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
679 UnwindStartRegs* startRegs,
680 Addr fp_max_orig )
681{
682 Bool debug = False;
683 Int i;
684 Addr fp_max;
685 UInt n_found = 0;
686
687 vg_assert(sizeof(Addr) == sizeof(UWord));
688 vg_assert(sizeof(Addr) == sizeof(void*));
689
690 D3UnwindRegs uregs;
691 uregs.ia = startRegs->r_pc;
692 uregs.sp = startRegs->r_sp;
693 Addr fp_min = uregs.sp;
694 uregs.fp = startRegs->misc.S390X.r_fp;
695 uregs.lr = startRegs->misc.S390X.r_lr;
696
697 fp_max = VG_PGROUNDUP(fp_max_orig);
698 if (fp_max >= sizeof(Addr))
699 fp_max -= sizeof(Addr);
700
701 if (debug)
702 VG_(printf)("max_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
703 "fp_max=0x%lx IA=0x%lx SP=0x%lx FP=0x%lx\n",
704 max_n_ips, fp_min, fp_max_orig, fp_max,
705 uregs.ia, uregs.sp,uregs.fp);
706
707 /* The first frame is pretty obvious */
708 ips[0] = uregs.ia;
709 if (sps) sps[0] = uregs.sp;
710 if (fps) fps[0] = uregs.fp;
711 i = 1;
712
713 /* for everything else we have to rely on the eh_frame. gcc defaults to
714 not create a backchain and all the other tools (like gdb) also have
715 to use the CFI. */
716 while (True) {
717 if (i >= max_n_ips)
718 break;
719
720 if (VG_(use_CF_info)( &uregs, fp_min, fp_max )) {
721 if (sps) sps[i] = uregs.sp;
722 if (fps) fps[i] = uregs.fp;
723 ips[i++] = uregs.ia - 1;
724 uregs.ia = uregs.ia - 1;
725 continue;
726 }
727 /* A problem on the first frame? Lets assume it was a bad jump.
728 We will use the link register and the current stack and frame
729 pointers and see if we can use the CFI in the next round. */
730 if (i == 1) {
731 if (sps) {
732 sps[i] = sps[0];
733 uregs.sp = sps[0];
734 }
735 if (fps) {
736 fps[i] = fps[0];
737 uregs.fp = fps[0];
738 }
739 uregs.ia = uregs.lr - 1;
740 ips[i++] = uregs.lr - 1;
741 continue;
742 }
743
744 /* No luck. We have to give up. */
745 break;
746 }
747
748 n_found = i;
749 return n_found;
750}
751#endif
752
sewardj59570ff2010-01-01 11:59:33 +0000753/*------------------------------------------------------------*/
754/*--- ---*/
755/*--- END platform-dependent unwinder worker functions ---*/
756/*--- ---*/
757/*------------------------------------------------------------*/
758
759/*------------------------------------------------------------*/
760/*--- Exported functions. ---*/
761/*------------------------------------------------------------*/
762
sewardjb8b79ad2008-03-03 01:35:41 +0000763UInt VG_(get_StackTrace) ( ThreadId tid,
njn3a4b58f2009-05-07 23:08:10 +0000764 /*OUT*/StackTrace ips, UInt max_n_ips,
sewardjb8b79ad2008-03-03 01:35:41 +0000765 /*OUT*/StackTrace sps,
766 /*OUT*/StackTrace fps,
sewardj39f34232007-11-09 23:02:28 +0000767 Word first_ip_delta )
njnd01fef72005-03-25 23:35:48 +0000768{
sewardj59570ff2010-01-01 11:59:33 +0000769 /* Get the register values with which to start the unwind. */
770 UnwindStartRegs startRegs;
771 VG_(memset)( &startRegs, 0, sizeof(startRegs) );
772 VG_(get_UnwindStartRegs)( &startRegs, tid );
773
njnf536bbb2005-06-13 04:21:38 +0000774 Addr stack_highest_word = VG_(threads)[tid].client_stack_highest_word;
tom690c3c82008-02-08 15:17:07 +0000775 Addr stack_lowest_word = 0;
njnd01fef72005-03-25 23:35:48 +0000776
sewardjb9bce632005-06-21 01:41:34 +0000777# if defined(VGP_x86_linux)
sewardja672ea32006-04-29 18:03:14 +0000778 /* Nasty little hack to deal with syscalls - if libc is using its
779 _dl_sysinfo_int80 function for syscalls (the TLS version does),
780 then ip will always appear to be in that function when doing a
781 syscall, not the actual libc function doing the syscall. This
782 check sees if IP is within that function, and pops the return
783 address off the stack so that ip is placed within the library
784 function calling the syscall. This makes stack backtraces much
785 more useful.
786
787 The function is assumed to look like this (from glibc-2.3.6 sources):
788 _dl_sysinfo_int80:
789 int $0x80
790 ret
791 That is 3 (2+1) bytes long. We could be more thorough and check
792 the 3 bytes of the function are as expected, but I can't be
793 bothered.
794 */
795 if (VG_(client__dl_sysinfo_int80) != 0 /* we know its address */
sewardj59570ff2010-01-01 11:59:33 +0000796 && startRegs.r_pc >= VG_(client__dl_sysinfo_int80)
797 && startRegs.r_pc < VG_(client__dl_sysinfo_int80)+3
798 && VG_(am_is_valid_for_client)(startRegs.r_pc, sizeof(Addr),
799 VKI_PROT_READ)) {
800 startRegs.r_pc = (ULong) *(Addr*)(UWord)startRegs.r_sp;
801 startRegs.r_sp += (ULong) sizeof(Addr);
njnd01fef72005-03-25 23:35:48 +0000802 }
sewardjb9bce632005-06-21 01:41:34 +0000803# endif
804
tom690c3c82008-02-08 15:17:07 +0000805 /* See if we can get a better idea of the stack limits */
sewardj59570ff2010-01-01 11:59:33 +0000806 VG_(stack_limits)( (Addr)startRegs.r_sp,
807 &stack_lowest_word, &stack_highest_word );
tom690c3c82008-02-08 15:17:07 +0000808
sewardj39f34232007-11-09 23:02:28 +0000809 /* Take into account the first_ip_delta. */
sewardj59570ff2010-01-01 11:59:33 +0000810 startRegs.r_pc += (Long)(Word)first_ip_delta;
sewardj39f34232007-11-09 23:02:28 +0000811
njnd01fef72005-03-25 23:35:48 +0000812 if (0)
sewardj59570ff2010-01-01 11:59:33 +0000813 VG_(printf)("tid %d: stack_highest=0x%08lx ip=0x%010llx "
814 "sp=0x%010llx\n",
815 tid, stack_highest_word,
816 startRegs.r_pc, startRegs.r_sp);
njnd01fef72005-03-25 23:35:48 +0000817
njn3a4b58f2009-05-07 23:08:10 +0000818 return VG_(get_StackTrace_wrk)(tid, ips, max_n_ips,
sewardjb8b79ad2008-03-03 01:35:41 +0000819 sps, fps,
sewardj59570ff2010-01-01 11:59:33 +0000820 &startRegs,
sewardjb8b79ad2008-03-03 01:35:41 +0000821 stack_highest_word);
njnd01fef72005-03-25 23:35:48 +0000822}
823
sewardj588adef2009-08-15 22:41:51 +0000824static void printIpDesc(UInt n, Addr ip, void* uu_opaque)
njnd01fef72005-03-25 23:35:48 +0000825{
njn83f9e792005-06-11 05:04:09 +0000826 #define BUF_LEN 4096
827
828 static UChar buf[BUF_LEN];
njnd01fef72005-03-25 23:35:48 +0000829
njn83f9e792005-06-11 05:04:09 +0000830 VG_(describe_IP)(ip, buf, BUF_LEN);
sewardj71bc3cb2005-05-19 00:25:45 +0000831
832 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +0000833 VG_(printf_xml)(" %s\n", buf);
sewardj71bc3cb2005-05-19 00:25:45 +0000834 } else {
sewardj738856f2009-07-15 14:48:32 +0000835 VG_(message)(Vg_UserMsg, " %s %s\n", ( n == 0 ? "at" : "by" ), buf);
sewardj71bc3cb2005-05-19 00:25:45 +0000836 }
njnd01fef72005-03-25 23:35:48 +0000837}
838
839/* Print a StackTrace. */
840void VG_(pp_StackTrace) ( StackTrace ips, UInt n_ips )
841{
842 vg_assert( n_ips > 0 );
sewardj71bc3cb2005-05-19 00:25:45 +0000843
844 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000845 VG_(printf_xml)(" <stack>\n");
sewardj71bc3cb2005-05-19 00:25:45 +0000846
sewardj588adef2009-08-15 22:41:51 +0000847 VG_(apply_StackTrace)( printIpDesc, NULL, ips, n_ips );
sewardj71bc3cb2005-05-19 00:25:45 +0000848
849 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000850 VG_(printf_xml)(" </stack>\n");
njnd01fef72005-03-25 23:35:48 +0000851}
852
853/* Get and immediately print a StackTrace. */
njn3a4b58f2009-05-07 23:08:10 +0000854void VG_(get_and_pp_StackTrace) ( ThreadId tid, UInt max_n_ips )
njnd01fef72005-03-25 23:35:48 +0000855{
njn3a4b58f2009-05-07 23:08:10 +0000856 Addr ips[max_n_ips];
857 UInt n_ips
858 = VG_(get_StackTrace)(tid, ips, max_n_ips,
sewardjb8b79ad2008-03-03 01:35:41 +0000859 NULL/*array to dump SP values in*/,
860 NULL/*array to dump FP values in*/,
861 0/*first_ip_delta*/);
njn3a4b58f2009-05-07 23:08:10 +0000862 VG_(pp_StackTrace)(ips, n_ips);
njnd01fef72005-03-25 23:35:48 +0000863}
864
sewardj588adef2009-08-15 22:41:51 +0000865void VG_(apply_StackTrace)(
866 void(*action)(UInt n, Addr ip, void* opaque),
867 void* opaque,
868 StackTrace ips, UInt n_ips
869 )
njnd01fef72005-03-25 23:35:48 +0000870{
njnd01fef72005-03-25 23:35:48 +0000871 Bool main_done = False;
njnd01fef72005-03-25 23:35:48 +0000872 Int i = 0;
873
874 vg_assert(n_ips > 0);
875 do {
876 Addr ip = ips[i];
njnd01fef72005-03-25 23:35:48 +0000877
sewardj73cf4c62005-11-17 15:12:34 +0000878 // Stop after the first appearance of "main" or one of the other names
879 // (the appearance of which is a pretty good sign that we've gone past
880 // main without seeing it, for whatever reason)
njn68824432009-02-10 06:48:00 +0000881 if ( ! VG_(clo_show_below_main) ) {
882 Vg_FnNameKind kind = VG_(get_fnname_kind_from_IP)(ip);
883 if (Vg_FnNameMain == kind || Vg_FnNameBelowMain == kind) {
njnd01fef72005-03-25 23:35:48 +0000884 main_done = True;
njn68824432009-02-10 06:48:00 +0000885 }
njnd01fef72005-03-25 23:35:48 +0000886 }
887
888 // Act on the ip
sewardj588adef2009-08-15 22:41:51 +0000889 action(i, ip, opaque);
njnd01fef72005-03-25 23:35:48 +0000890
891 i++;
njn3a4b58f2009-05-07 23:08:10 +0000892 } while (i < n_ips && !main_done);
njnd01fef72005-03-25 23:35:48 +0000893
894 #undef MYBUF_LEN
895}
896
897
898/*--------------------------------------------------------------------*/
njn24a6efb2005-06-20 03:36:51 +0000899/*--- end ---*/
njnd01fef72005-03-25 23:35:48 +0000900/*--------------------------------------------------------------------*/