blob: f0ddd4426c2bddf58816a78473650d506b8a9f14 [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
sewardjb3a1e4b2015-08-21 11:32:26 +000010 Copyright (C) 2000-2015 Julian Seward
njnd01fef72005-03-25 23:35:48 +000011 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000032#include "pub_core_vki.h"
njnc7561b92005-06-19 01:24:32 +000033#include "pub_core_threadstate.h"
njn68824432009-02-10 06:48:00 +000034#include "pub_core_debuginfo.h" // XXX: circular dependency
njn24a6efb2005-06-20 03:36:51 +000035#include "pub_core_aspacemgr.h" // For VG_(is_addressable)()
njn97405b22005-06-02 03:39:33 +000036#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000037#include "pub_core_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +000038#include "pub_core_libcprint.h"
njnf536bbb2005-06-13 04:21:38 +000039#include "pub_core_machine.h"
njn20242342005-05-16 23:31:24 +000040#include "pub_core_options.h"
sewardj9084de72008-02-11 11:23:12 +000041#include "pub_core_stacks.h" // VG_(stack_limits)
njnd01fef72005-03-25 23:35:48 +000042#include "pub_core_stacktrace.h"
rhyskidd8695a652015-06-06 03:57:34 +000043#include "pub_core_syswrap.h" // VG_(is_in_syscall)
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
philippe46207652013-01-20 17:11:58 +000065/* Do frame merging in the _i frames in _ips array of recursive cycles
66 of up to _nframes. The merge is done during stack unwinding
67 (i.e. in platform specific unwinders) to collect as many
68 "interesting" stack traces as possible. */
69#define RECURSIVE_MERGE(_nframes,_ips,_i){ \
70 Int dist; \
71 for (dist = 1; dist <= _nframes && dist < (Int)_i; dist++) { \
72 if (_ips[_i-1] == _ips[_i-1-dist]) { \
73 _i = _i - dist; \
74 break; \
75 } \
76 } \
77}
78
philippe01c353e2015-06-04 19:44:47 +000079/* Note about calculation of fp_min : fp_min is the lowest address
80 which can be accessed during unwinding. This is SP - VG_STACK_REDZONE_SZB.
81 On most platforms, this will be equal to SP (as VG_STACK_REDZONE_SZB
82 is 0). However, on some platforms (e.g. amd64), there is an accessible
83 redzone below the SP. Some CFI unwind info are generated, taking this
84 into account. As an example, the following is a CFI unwind info on
85 amd64 found for a 'retq' instruction:
86[0x400f7e .. 0x400f7e]: let cfa=oldSP+8 in RA=*(cfa+-8) SP=cfa+0 BP=*(cfa+-16)
87 0x400f7e: retq
88 As you can see, the previous BP is found 16 bytes below the cfa, which
89 is the oldSP+8. So, effectively, the BP is found 8 bytes below the SP.
90 The fp_min must take this into account, otherwise, VG_(use_CF_info) will
91 not unwind the BP. */
92
sewardj59570ff2010-01-01 11:59:33 +000093/* ------------------------ x86 ------------------------- */
94
sewardj8eb8bab2015-07-21 14:44:28 +000095#if defined(VGP_x86_linux) || defined(VGP_x86_darwin) \
96 || defined(VGP_x86_solaris)
sewardj59570ff2010-01-01 11:59:33 +000097
philippe20ede3a2013-01-30 23:18:11 +000098#define N_FP_CF_VERIF 1021
99// prime number so that size of fp_CF_verif is just below 4K or 8K
100// Note that this prime nr differs from the one chosen in
101// m_debuginfo/debuginfo.c for the cfsi cache : in case we have
102// a collision here between two IPs, we expect to not (often) have the
103// same collision in the cfsi cache (and vice-versa).
104
105// unwinding with fp chain is ok:
106#define FPUNWIND 0
107// there is no CFI info for this IP:
108#define NOINFO 1
109// Unwind with FP is not ok, must use CF unwind:
110#define CFUNWIND 2
111
112static Addr fp_CF_verif_cache [N_FP_CF_VERIF];
113
114/* An unwind done by following the fp chain technique can be incorrect
115 as not all frames are respecting the standard bp/sp ABI.
116 The CF information is now generated by default by gcc
117 (as part of the dwarf info). However, unwinding using CF information
118 is significantly slower : a slowdown of 20% has been observed
119 on an helgrind test case.
120 So, by default, the unwinding will be done using the fp chain.
121 But before accepting to unwind an IP with fp_chain, the result
122 of the unwind will be checked with the CF information.
123 This check can give 3 results:
124 FPUNWIND (0): there is CF info, and it gives the same result as fp unwind.
125 => it is assumed that future unwind for this IP can be done
126 with the fast fp chain, without further CF checking
127 NOINFO (1): there is no CF info (so, fp unwind is the only do-able thing)
128 CFUNWIND (2): there is CF info, but unwind result differs.
129 => it is assumed that future unwind for this IP must be done
130 with the CF info.
131 Of course, if each fp unwind implies a check done with a CF unwind,
132 it would just be slower => we cache the check result in an
133 array of checked Addr.
134 The check for an IP will be stored at
135 fp_CF_verif_cache[IP % N_FP_CF_VERIF] as one of:
136 IP ^ FPUNWIND
137 IP ^ NOINFO
138 IP ^ CFUNWIND
139
140 Note: we can re-use the last (ROUNDDOWN (log (N_FP_CF_VERIF))) bits
141 to store the check result, as they are guaranteed to be non significant
142 in the comparison between 2 IPs stored in fp_CF_verif_cache).
143 In other words, if two IPs are only differing on the last 2 bits,
144 then they will not land in the same cache bucket.
145*/
146
philippef7bbd792015-05-26 21:26:39 +0000147/* cached result of VG_(FPO_info_present)(). Refreshed each time
148 the fp_CF_verif_generation is different of the current debuginfo
149 generation. */
150static Bool FPO_info_present = False;
151
philippe20ede3a2013-01-30 23:18:11 +0000152static UInt fp_CF_verif_generation = 0;
153// Our cache has to be maintained in sync with the CFI cache.
philippef7bbd792015-05-26 21:26:39 +0000154// Each time the debuginfo is changed, its generation will be incremented.
philippe20ede3a2013-01-30 23:18:11 +0000155// We will clear our cache when our saved generation differs from
philippef7bbd792015-05-26 21:26:39 +0000156// the debuginfo generation.
philippe20ede3a2013-01-30 23:18:11 +0000157
sewardjb8b79ad2008-03-03 01:35:41 +0000158UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
njn3a4b58f2009-05-07 23:08:10 +0000159 /*OUT*/Addr* ips, UInt max_n_ips,
sewardjb8b79ad2008-03-03 01:35:41 +0000160 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
florian518850b2014-10-22 22:25:30 +0000161 const UnwindStartRegs* startRegs,
sewardj59570ff2010-01-01 11:59:33 +0000162 Addr fp_max_orig )
njnd01fef72005-03-25 23:35:48 +0000163{
philippe20ede3a2013-01-30 23:18:11 +0000164 const Bool do_stats = False; // compute and output some stats regularly.
165 static struct {
166 UInt nr; // nr of stacktraces computed
167 UInt nf; // nr of frames computed
168 UInt Ca; // unwind for which cache indicates CFUnwind must be used.
169 UInt FF; // unwind for which cache indicates FPUnwind can be used.
170 UInt Cf; // unwind at end of stack+store CFUNWIND (xip not end of stack).
171 UInt Fw; // unwind at end of stack+store FPUNWIND
172 UInt FO; // unwind + store FPUNWIND
173 UInt CF; // unwind + store CFUNWIND. Details below.
174 UInt xi; UInt xs; UInt xb; // register(s) which caused a 'store CFUNWIND'.
175 UInt Ck; // unwind fp invalid+store FPUNWIND
176 UInt MS; // microsoft unwind
177 } stats;
178
philippec9963262013-03-01 20:37:41 +0000179 const Bool debug = False;
180 // = VG_(debugLog_getLevel) () > 3;
181 // = True;
182 // = stats.nr >= 123456;
183 const HChar* unwind_case; // used when debug is True.
184 // Debugging this function is not straightforward.
185 // Here is the easiest way I have found:
186 // 1. Change the above to True.
187 // 2. Start your program under Valgrind with --tool=none --vgdb-error=0
188 // 3. Use GDB/vgdb to put a breakpoint where you want to debug the stacktrace
189 // 4. Continue till breakpoint is encountered
190 // 5. From GDB, use 'monitor v.info scheduler' and examine the unwind traces.
191 // You might have to do twice 'monitor v.info scheduler' to see
192 // the effect of caching the results of the verification.
193 // You can also modify the debug dynamically using by using
194 // 'monitor v.set debuglog 4.
195
sewardjacaec5f2005-08-19 16:02:59 +0000196 Int i;
197 Addr fp_max;
198 UInt n_found = 0;
philippe46207652013-01-20 17:11:58 +0000199 const Int cmrf = VG_(clo_merge_recursive_frames);
njnd01fef72005-03-25 23:35:48 +0000200
sewardjacaec5f2005-08-19 16:02:59 +0000201 vg_assert(sizeof(Addr) == sizeof(UWord));
202 vg_assert(sizeof(Addr) == sizeof(void*));
njnd01fef72005-03-25 23:35:48 +0000203
philippe20ede3a2013-01-30 23:18:11 +0000204 D3UnwindRegs fpverif_uregs; // result of CF unwind for a check reason.
philippec4feec12013-01-30 23:53:59 +0000205 Addr xip_verified = 0; // xip for which we have calculated fpverif_uregs
206 // 0 assigned to silence false positive -Wuninitialized warning
sewardj522d4d32013-01-31 10:39:07 +0000207 // This is a false positive as xip_verified is assigned when
208 // xip_verif > CFUNWIND and only used if xip_verif > CFUNWIND.
philippe20ede3a2013-01-30 23:18:11 +0000209
sewardj9365e3f2010-01-01 19:55:17 +0000210 D3UnwindRegs uregs;
211 uregs.xip = (Addr)startRegs->r_pc;
212 uregs.xsp = (Addr)startRegs->r_sp;
213 uregs.xbp = startRegs->misc.X86.r_ebp;
philippe01c353e2015-06-04 19:44:47 +0000214 Addr fp_min = uregs.xsp - VG_STACK_REDZONE_SZB;
sewardj59570ff2010-01-01 11:59:33 +0000215
njn3a4b58f2009-05-07 23:08:10 +0000216 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
njnc0ec8e92005-12-25 06:34:04 +0000217 stopping when the trail goes cold, which we guess to be
sewardjacaec5f2005-08-19 16:02:59 +0000218 when FP is not a reasonable stack location. */
219
njnd01fef72005-03-25 23:35:48 +0000220 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
221 // current page, at least. Dunno if it helps.
222 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
sewardj45f4e7c2005-09-27 19:20:21 +0000223 fp_max = VG_PGROUNDUP(fp_max_orig);
sewardjd0c0ea62008-03-03 22:20:51 +0000224 if (fp_max >= sizeof(Addr))
225 fp_max -= sizeof(Addr);
njnd01fef72005-03-25 23:35:48 +0000226
227 if (debug)
floriana5e06c32015-08-05 21:16:09 +0000228 VG_(printf)("max_n_ips=%u fp_min=0x%08lx fp_max_orig=0x08%lx, "
philippe49345542014-06-14 22:12:37 +0000229 "fp_max=0x%08lx ip=0x%08lx fp=0x%08lx\n",
sewardj9365e3f2010-01-01 19:55:17 +0000230 max_n_ips, fp_min, fp_max_orig, fp_max,
231 uregs.xip, uregs.xbp);
njnd01fef72005-03-25 23:35:48 +0000232
233 /* Assertion broken before main() is reached in pthreaded programs; the
234 * offending stack traces only have one item. --njn, 2002-aug-16 */
235 /* vg_assert(fp_min <= fp_max);*/
njnf76d27a2009-05-28 01:53:07 +0000236 // On Darwin, this kicks in for pthread-related stack traces, so they're
237 // only 1 entry long which is wrong.
sewardj8eb8bab2015-07-21 14:44:28 +0000238# if defined(VGO_linux)
sewardj5bdfbd22007-12-15 22:13:05 +0000239 if (fp_min + 512 >= fp_max) {
240 /* If the stack limits look bogus, don't poke around ... but
241 don't bomb out either. */
sewardj8eb8bab2015-07-21 14:44:28 +0000242# elif defined(VGO_solaris)
243 if (fp_max == 0) {
244 /* VG_(get_StackTrace)() can be called by tools very early when
245 various tracing options are enabled. Don't proceed further
246 if the stack limits look bogus.
247 */
248# endif
249# if defined(VGO_linux) || defined(VGO_solaris)
sewardj9365e3f2010-01-01 19:55:17 +0000250 if (sps) sps[0] = uregs.xsp;
251 if (fps) fps[0] = uregs.xbp;
252 ips[0] = uregs.xip;
sewardjacaec5f2005-08-19 16:02:59 +0000253 return 1;
254 }
sewardj59570ff2010-01-01 11:59:33 +0000255# endif
sewardj35165532005-04-30 18:47:48 +0000256
philippef7bbd792015-05-26 21:26:39 +0000257 if (UNLIKELY (fp_CF_verif_generation != VG_(debuginfo_generation)())) {
258 fp_CF_verif_generation = VG_(debuginfo_generation)();
philippe20ede3a2013-01-30 23:18:11 +0000259 VG_(memset)(&fp_CF_verif_cache, 0, sizeof(fp_CF_verif_cache));
philippef7bbd792015-05-26 21:26:39 +0000260 FPO_info_present = VG_(FPO_info_present)();
philippe20ede3a2013-01-30 23:18:11 +0000261 }
sewardj75ea7982005-11-14 15:18:25 +0000262
sewardj75ea7982005-11-14 15:18:25 +0000263
264 /* Loop unwinding the stack. Note that the IP value we get on
265 * each pass (whether from CFI info or a stack frame) is a
266 * return address so is actually after the calling instruction
267 * in the calling function.
268 *
269 * Because of this we subtract one from the IP after each pass
270 * of the loop so that we find the right CFI block on the next
271 * pass - otherwise we can find the wrong CFI info if it happens
272 * to change after the calling instruction and that will mean
273 * that we will fail to unwind the next step.
274 *
275 * This most frequently happens at the end of a function when
276 * a tail call occurs and we wind up using the CFI info for the
277 * next function which is completely wrong.
278 */
philippe20ede3a2013-01-30 23:18:11 +0000279 if (sps) sps[0] = uregs.xsp;
280 if (fps) fps[0] = uregs.xbp;
281 ips[0] = uregs.xip;
282 i = 1;
283 if (do_stats) stats.nr++;
284
sewardj75ea7982005-11-14 15:18:25 +0000285 while (True) {
286
njn3a4b58f2009-05-07 23:08:10 +0000287 if (i >= max_n_ips)
sewardj75ea7982005-11-14 15:18:25 +0000288 break;
289
philippe20ede3a2013-01-30 23:18:11 +0000290 UWord hash = uregs.xip % N_FP_CF_VERIF;
291 Addr xip_verif = uregs.xip ^ fp_CF_verif_cache [hash];
292 if (debug)
philippedcef54c2014-06-14 10:04:51 +0000293 VG_(printf)(" uregs.xip 0x%08lx xip_verif[0x%08lx]"
294 " xbp 0x%08lx xsp 0x%08lx\n",
295 uregs.xip, xip_verif,
296 uregs.xbp, uregs.xsp);
philippe20ede3a2013-01-30 23:18:11 +0000297 // If xip is in cache, then xip_verif will be <= CFUNWIND.
298 // Otherwise, if not in cache, xip_verif will be > CFUNWIND.
sewardj75ea7982005-11-14 15:18:25 +0000299
philippe20ede3a2013-01-30 23:18:11 +0000300 /* Try to derive a new (ip,sp,fp) triple from the current set. */
301
302 /* Do we have to do CFI unwinding ?
303 We do CFI unwinding if one of the following condition holds:
304 a. fp_CF_verif_cache contains xip but indicates CFUNWIND must
305 be done (i.e. fp unwind check failed when we did the first
306 unwind for this IP).
307 b. fp_CF_verif_cache does not contain xip.
308 We will try CFI unwinding in fpverif_uregs and compare with
309 FP unwind result to insert xip in the cache with the correct
310 indicator. */
311 if (UNLIKELY(xip_verif >= CFUNWIND)) {
312 if (xip_verif == CFUNWIND) {
313 /* case a : do "real" cfi unwind */
314 if ( VG_(use_CF_info)( &uregs, fp_min, fp_max ) ) {
315 if (debug) unwind_case = "Ca";
316 if (do_stats) stats.Ca++;
317 goto unwind_done;
318 }
319 /* ??? cache indicates we have to do CFI unwind (so, we
320 previously found CFI info, and failed the fp unwind
321 check). Now, we just failed with CFI. So, once we
322 succeed, once we fail. No idea what is going on =>
323 cleanup the cache entry and fallover to fp unwind (this
324 time). */
325 fp_CF_verif_cache [hash] = 0;
326 if (debug) VG_(printf)(" cache reset as CFI ok then nok\n");
327 //??? stats
328 xip_verif = NOINFO;
329 } else {
330 /* case b : do "verif" cfi unwind in fpverif_uregs */
331 fpverif_uregs = uregs;
332 xip_verified = uregs.xip;
333 if ( !VG_(use_CF_info)( &fpverif_uregs, fp_min, fp_max ) ) {
334 fp_CF_verif_cache [hash] = uregs.xip ^ NOINFO;
335 if (debug) VG_(printf)(" cache NOINFO fpverif_uregs\n");
336 xip_verif = NOINFO;
337 }
338 }
339 }
340
341 /* On x86, try the old-fashioned method of following the
342 %ebp-chain. This can be done if the fp_CF_verif_cache for xip
343 indicate fp unwind is ok. This must be done if the cache indicates
344 there is no info. This is also done to confirm what to put in the cache
345 if xip was not in the cache. */
346 /* This deals with frames resulting from functions which begin "pushl%
sewardj75ea7982005-11-14 15:18:25 +0000347 ebp ; movl %esp, %ebp" which is the ABI-mandated preamble. */
sewardj9365e3f2010-01-01 19:55:17 +0000348 if (fp_min <= uregs.xbp &&
sewardj418f6b32015-07-07 14:06:00 +0000349 uregs.xbp <= fp_max - 1 * sizeof(UWord)/*see comment below*/ &&
350 VG_IS_4_ALIGNED(uregs.xbp))
njn3a4b58f2009-05-07 23:08:10 +0000351 {
sewardj75ea7982005-11-14 15:18:25 +0000352 /* fp looks sane, so use it. */
sewardj9365e3f2010-01-01 19:55:17 +0000353 uregs.xip = (((UWord*)uregs.xbp)[1]);
njn3a4b58f2009-05-07 23:08:10 +0000354 // We stop if we hit a zero (the traditional end-of-stack
355 // marker) or a one -- these correspond to recorded IPs of 0 or -1.
356 // The latter because r8818 (in this file) changes the meaning of
357 // entries [1] and above in a stack trace, by subtracting 1 from
358 // them. Hence stacks that used to end with a zero value now end in
359 // -1 and so we must detect that too.
philippe20ede3a2013-01-30 23:18:11 +0000360 if (0 == uregs.xip || 1 == uregs.xip) {
361 if (xip_verif > CFUNWIND) {
362 // Check if we obtain the same result with fp unwind.
363 // If same result, then mark xip as fp unwindable
364 if (uregs.xip == fpverif_uregs.xip) {
365 fp_CF_verif_cache [hash] = xip_verified ^ FPUNWIND;
366 if (debug) VG_(printf)(" cache FPUNWIND 0\n");
367 unwind_case = "Fw";
368 if (do_stats) stats.Fw++;
369 break;
370 } else {
371 fp_CF_verif_cache [hash] = xip_verified ^ CFUNWIND;
372 uregs = fpverif_uregs;
373 if (debug) VG_(printf)(" cache CFUNWIND 0\n");
374 unwind_case = "Cf";
375 if (do_stats) stats.Cf++;
376 goto unwind_done;
377 }
378 } else {
379 // end of stack => out of the loop.
380 break;
381 }
382 }
383
sewardj9365e3f2010-01-01 19:55:17 +0000384 uregs.xsp = uregs.xbp + sizeof(Addr) /*saved %ebp*/
385 + sizeof(Addr) /*ra*/;
386 uregs.xbp = (((UWord*)uregs.xbp)[0]);
philippe20ede3a2013-01-30 23:18:11 +0000387 if (xip_verif > CFUNWIND) {
388 if (uregs.xip == fpverif_uregs.xip
389 && uregs.xsp == fpverif_uregs.xsp
390 && uregs.xbp == fpverif_uregs.xbp) {
391 fp_CF_verif_cache [hash] = xip_verified ^ FPUNWIND;
392 if (debug) VG_(printf)(" cache FPUNWIND >2\n");
393 if (debug) unwind_case = "FO";
394 if (do_stats) stats.FO++;
395 } else {
396 fp_CF_verif_cache [hash] = xip_verified ^ CFUNWIND;
397 if (debug) VG_(printf)(" cache CFUNWIND >2\n");
398 if (do_stats && uregs.xip != fpverif_uregs.xip) stats.xi++;
399 if (do_stats && uregs.xsp != fpverif_uregs.xsp) stats.xs++;
400 if (do_stats && uregs.xbp != fpverif_uregs.xbp) stats.xb++;
401 uregs = fpverif_uregs;
402 if (debug) unwind_case = "CF";
403 if (do_stats) stats.CF++;
404 }
405 } else {
406 if (debug) unwind_case = "FF";
407 if (do_stats) stats.FF++;
408 }
409 goto unwind_done;
410 } else {
411 // fp unwind has failed.
412 // If we were checking the validity of the cfi unwinding,
413 // we mark in the cache that the fp unwind cannot be done, and that
414 // cfi unwind is desired.
415 if (xip_verif > CFUNWIND) {
416 // We know that fpverif_uregs contains valid information,
417 // as a failed cf unwind would have put NOINFO in xip_verif.
418 fp_CF_verif_cache [hash] = xip_verified ^ CFUNWIND;
419 if (debug) VG_(printf)(" cache CFUNWIND as fp failed\n");
420 uregs = fpverif_uregs;
421 if (debug) unwind_case = "Ck";
422 if (do_stats) stats.Ck++;
423 goto unwind_done;
424 }
425 // xip_verif is FPUNWIND or NOINFO.
426 // We failed the cfi unwind and/or the fp unwind.
427 // => fallback to FPO info.
sewardj75ea7982005-11-14 15:18:25 +0000428 }
429
sewardjc8259b82009-04-22 22:42:10 +0000430 /* And, similarly, try for MSVC FPO unwind info. */
philippef7bbd792015-05-26 21:26:39 +0000431 if (FPO_info_present
432 && VG_(use_FPO_info)( &uregs.xip, &uregs.xsp, &uregs.xbp,
433 fp_min, fp_max ) ) {
philippe20ede3a2013-01-30 23:18:11 +0000434 if (debug) unwind_case = "MS";
435 if (do_stats) stats.MS++;
436 goto unwind_done;
sewardjc8259b82009-04-22 22:42:10 +0000437 }
438
sewardj75ea7982005-11-14 15:18:25 +0000439 /* No luck. We have to give up. */
440 break;
philippe20ede3a2013-01-30 23:18:11 +0000441
442 unwind_done:
443 /* Add a frame in ips/sps/fps */
444 /* fp is %ebp. sp is %esp. ip is %eip. */
445 if (0 == uregs.xip || 1 == uregs.xip) break;
446 if (sps) sps[i] = uregs.xsp;
447 if (fps) fps[i] = uregs.xbp;
448 ips[i++] = uregs.xip - 1;
449 /* -1: refer to calling insn, not the RA */
450 if (debug)
451 VG_(printf)(" ips%s[%d]=0x%08lx\n", unwind_case, i-1, ips[i-1]);
452 uregs.xip = uregs.xip - 1;
453 /* as per comment at the head of this loop */
454 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
sewardj75ea7982005-11-14 15:18:25 +0000455 }
456
philippe20ede3a2013-01-30 23:18:11 +0000457 if (do_stats) stats.nf += i;
458 if (do_stats && stats.nr % 10000 == 0) {
459 VG_(printf)("nr %u nf %u "
460 "Ca %u FF %u "
461 "Cf %u "
462 "Fw %u FO %u "
463 "CF %u (xi %u xs %u xb %u) "
464 "Ck %u MS %u\n",
465 stats.nr, stats.nf,
466 stats.Ca, stats.FF,
467 stats.Cf,
468 stats.Fw, stats.FO,
469 stats.CF, stats.xi, stats.xs, stats.xb,
470 stats.Ck, stats.MS);
471 }
sewardj59570ff2010-01-01 11:59:33 +0000472 n_found = i;
473 return n_found;
474}
sewardj75ea7982005-11-14 15:18:25 +0000475
sewardj522d4d32013-01-31 10:39:07 +0000476#undef N_FP_CF_VERIF
477#undef FPUNWIND
478#undef NOINFO
479#undef CFUNWIND
480
sewardj59570ff2010-01-01 11:59:33 +0000481#endif
482
483/* ----------------------- amd64 ------------------------ */
484
sewardj8eb8bab2015-07-21 14:44:28 +0000485#if defined(VGP_amd64_linux) || defined(VGP_amd64_darwin) \
486 || defined(VGP_amd64_solaris)
sewardj59570ff2010-01-01 11:59:33 +0000487
488UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
489 /*OUT*/Addr* ips, UInt max_n_ips,
490 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
florian518850b2014-10-22 22:25:30 +0000491 const UnwindStartRegs* startRegs,
sewardj59570ff2010-01-01 11:59:33 +0000492 Addr fp_max_orig )
493{
philippe2d207aa2015-05-31 15:18:36 +0000494 const Bool debug = False;
sewardj59570ff2010-01-01 11:59:33 +0000495 Int i;
496 Addr fp_max;
497 UInt n_found = 0;
philippe46207652013-01-20 17:11:58 +0000498 const Int cmrf = VG_(clo_merge_recursive_frames);
sewardj59570ff2010-01-01 11:59:33 +0000499
500 vg_assert(sizeof(Addr) == sizeof(UWord));
501 vg_assert(sizeof(Addr) == sizeof(void*));
502
sewardj9365e3f2010-01-01 19:55:17 +0000503 D3UnwindRegs uregs;
504 uregs.xip = startRegs->r_pc;
505 uregs.xsp = startRegs->r_sp;
506 uregs.xbp = startRegs->misc.AMD64.r_rbp;
philippe01c353e2015-06-04 19:44:47 +0000507 Addr fp_min = uregs.xsp - VG_STACK_REDZONE_SZB;
sewardj59570ff2010-01-01 11:59:33 +0000508
509 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
510 stopping when the trail goes cold, which we guess to be
511 when FP is not a reasonable stack location. */
512
513 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
514 // current page, at least. Dunno if it helps.
515 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
516 fp_max = VG_PGROUNDUP(fp_max_orig);
517 if (fp_max >= sizeof(Addr))
518 fp_max -= sizeof(Addr);
519
520 if (debug)
floriana5e06c32015-08-05 21:16:09 +0000521 VG_(printf)("max_n_ips=%u fp_min=0x%lx fp_max_orig=0x%lx, "
sewardj59570ff2010-01-01 11:59:33 +0000522 "fp_max=0x%lx ip=0x%lx fp=0x%lx\n",
sewardj9365e3f2010-01-01 19:55:17 +0000523 max_n_ips, fp_min, fp_max_orig, fp_max,
524 uregs.xip, uregs.xbp);
sewardj59570ff2010-01-01 11:59:33 +0000525
526 /* Assertion broken before main() is reached in pthreaded programs; the
527 * offending stack traces only have one item. --njn, 2002-aug-16 */
528 /* vg_assert(fp_min <= fp_max);*/
529 // On Darwin, this kicks in for pthread-related stack traces, so they're
530 // only 1 entry long which is wrong.
sewardj8eb8bab2015-07-21 14:44:28 +0000531# if defined(VGO_linux)
sewardjf2522992010-10-06 22:45:18 +0000532 if (fp_min + 256 >= fp_max) {
sewardj59570ff2010-01-01 11:59:33 +0000533 /* If the stack limits look bogus, don't poke around ... but
534 don't bomb out either. */
sewardj8eb8bab2015-07-21 14:44:28 +0000535# elif defined(VGO_solaris)
536 if (fp_max == 0) {
537 /* VG_(get_StackTrace)() can be called by tools very early when
538 various tracing options are enabled. Don't proceed further
539 if the stack limits look bogus.
540 */
541# endif
542# if defined(VGO_linux) || defined(VGO_solaris)
543
sewardj9365e3f2010-01-01 19:55:17 +0000544 if (sps) sps[0] = uregs.xsp;
545 if (fps) fps[0] = uregs.xbp;
546 ips[0] = uregs.xip;
sewardj59570ff2010-01-01 11:59:33 +0000547 return 1;
548 }
549# endif
sewardj75ea7982005-11-14 15:18:25 +0000550
551 /* fp is %rbp. sp is %rsp. ip is %rip. */
sewardj35165532005-04-30 18:47:48 +0000552
sewardj9365e3f2010-01-01 19:55:17 +0000553 ips[0] = uregs.xip;
554 if (sps) sps[0] = uregs.xsp;
555 if (fps) fps[0] = uregs.xbp;
sewardjacaec5f2005-08-19 16:02:59 +0000556 i = 1;
philippe2d207aa2015-05-31 15:18:36 +0000557 if (debug)
558 VG_(printf)(" ipsS[%d]=%#08lx rbp %#08lx rsp %#08lx\n",
559 i-1, ips[i-1], uregs.xbp, uregs.xsp);
sewardj35165532005-04-30 18:47:48 +0000560
rhyskiddbc3770e2015-03-07 05:22:12 +0000561# if defined(VGO_darwin)
562 if (VG_(is_valid_tid)(tid_if_known) &&
563 VG_(is_in_syscall)(tid_if_known) &&
564 i < max_n_ips) {
565 /* On Darwin, all the system call stubs have no function
566 * prolog. So instead of top of the stack being a new
567 * frame comprising a saved BP and a return address, we
568 * just have the return address in the caller's frame.
569 * Adjust for this by recording the return address.
570 */
571 ips[i] = *(Addr *)uregs.xsp - 1;
572 if (sps) sps[i] = uregs.xsp;
573 if (fps) fps[i] = uregs.xbp;
574 i++;
575 }
576# endif
577
tomac35f102005-11-05 00:17:21 +0000578 /* Loop unwinding the stack. Note that the IP value we get on
579 * each pass (whether from CFI info or a stack frame) is a
580 * return address so is actually after the calling instruction
581 * in the calling function.
582 *
583 * Because of this we subtract one from the IP after each pass
584 * of the loop so that we find the right CFI block on the next
585 * pass - otherwise we can find the wrong CFI info if it happens
586 * to change after the calling instruction and that will mean
587 * that we will fail to unwind the next step.
588 *
589 * This most frequently happens at the end of a function when
590 * a tail call occurs and we wind up using the CFI info for the
591 * next function which is completely wrong.
592 */
sewardjacaec5f2005-08-19 16:02:59 +0000593 while (True) {
sewardj35165532005-04-30 18:47:48 +0000594
njn3a4b58f2009-05-07 23:08:10 +0000595 if (i >= max_n_ips)
sewardj35165532005-04-30 18:47:48 +0000596 break;
sewardjacaec5f2005-08-19 16:02:59 +0000597
njn3a4b58f2009-05-07 23:08:10 +0000598 /* Try to derive a new (ip,sp,fp) triple from the current set. */
sewardjacaec5f2005-08-19 16:02:59 +0000599
600 /* First off, see if there is any CFI info to hand which can
601 be used. */
sewardj9365e3f2010-01-01 19:55:17 +0000602 if ( VG_(use_CF_info)( &uregs, fp_min, fp_max ) ) {
603 if (0 == uregs.xip || 1 == uregs.xip) break;
604 if (sps) sps[i] = uregs.xsp;
605 if (fps) fps[i] = uregs.xbp;
606 ips[i++] = uregs.xip - 1; /* -1: refer to calling insn, not the RA */
sewardjacaec5f2005-08-19 16:02:59 +0000607 if (debug)
philippe2d207aa2015-05-31 15:18:36 +0000608 VG_(printf)(" ipsC[%d]=%#08lx rbp %#08lx rsp %#08lx\n",
609 i-1, ips[i-1], uregs.xbp, uregs.xsp);
sewardj9365e3f2010-01-01 19:55:17 +0000610 uregs.xip = uregs.xip - 1; /* as per comment at the head of this loop */
philippe46207652013-01-20 17:11:58 +0000611 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
sewardjacaec5f2005-08-19 16:02:59 +0000612 continue;
njnd01fef72005-03-25 23:35:48 +0000613 }
sewardj35165532005-04-30 18:47:48 +0000614
sewardjeadcd862006-04-04 15:12:44 +0000615 /* If VG_(use_CF_info) fails, it won't modify ip/sp/fp, so
sewardjacaec5f2005-08-19 16:02:59 +0000616 we can safely try the old-fashioned method. */
617 /* This bit is supposed to deal with frames resulting from
sewardj75ea7982005-11-14 15:18:25 +0000618 functions which begin "pushq %rbp ; movq %rsp, %rbp".
619 Unfortunately, since we can't (easily) look at the insns at
620 the start of the fn, like GDB does, there's no reliable way
621 to tell. Hence the hack of first trying out CFI, and if that
622 fails, then use this as a fallback. */
sewardjf98e1c02008-10-25 16:22:41 +0000623 /* Note: re "- 1 * sizeof(UWord)", need to take account of the
624 fact that we are prodding at & ((UWord*)fp)[1] and so need to
625 adjust the limit check accordingly. Omitting this has been
626 observed to cause segfaults on rare occasions. */
sewardj9365e3f2010-01-01 19:55:17 +0000627 if (fp_min <= uregs.xbp && uregs.xbp <= fp_max - 1 * sizeof(UWord)) {
sewardjacaec5f2005-08-19 16:02:59 +0000628 /* fp looks sane, so use it. */
sewardj9365e3f2010-01-01 19:55:17 +0000629 uregs.xip = (((UWord*)uregs.xbp)[1]);
630 if (0 == uregs.xip || 1 == uregs.xip) break;
631 uregs.xsp = uregs.xbp + sizeof(Addr) /*saved %rbp*/
632 + sizeof(Addr) /*ra*/;
633 uregs.xbp = (((UWord*)uregs.xbp)[0]);
634 if (sps) sps[i] = uregs.xsp;
635 if (fps) fps[i] = uregs.xbp;
636 ips[i++] = uregs.xip - 1; /* -1: refer to calling insn, not the RA */
sewardjacaec5f2005-08-19 16:02:59 +0000637 if (debug)
philippe30fb2d32015-05-31 15:26:51 +0000638 VG_(printf)(" ipsF[%d]=%#08lx rbp %#08lx rsp %#08lx\n",
639 i-1, ips[i-1], uregs.xbp, uregs.xsp);
sewardj9365e3f2010-01-01 19:55:17 +0000640 uregs.xip = uregs.xip - 1; /* as per comment at the head of this loop */
philippe46207652013-01-20 17:11:58 +0000641 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
sewardjacaec5f2005-08-19 16:02:59 +0000642 continue;
643 }
644
sewardj39f34232007-11-09 23:02:28 +0000645 /* Last-ditch hack (evidently GDB does something similar). We
646 are in the middle of nowhere and we have a nonsense value for
647 the frame pointer. If the stack pointer is still valid,
648 assume that what it points at is a return address. Yes,
649 desperate measures. Could do better here:
650 - check that the supposed return address is in
651 an executable page
652 - check that the supposed return address is just after a call insn
653 - given those two checks, don't just consider *sp as the return
654 address; instead scan a likely section of stack (eg sp .. sp+256)
655 and use suitable values found there.
656 */
sewardj9365e3f2010-01-01 19:55:17 +0000657 if (fp_min <= uregs.xsp && uregs.xsp < fp_max) {
658 uregs.xip = ((UWord*)uregs.xsp)[0];
659 if (0 == uregs.xip || 1 == uregs.xip) break;
660 if (sps) sps[i] = uregs.xsp;
661 if (fps) fps[i] = uregs.xbp;
662 ips[i++] = uregs.xip == 0
sewardjb1ae15d2008-12-12 13:23:03 +0000663 ? 0 /* sp[0] == 0 ==> stuck at the bottom of a
664 thread stack */
sewardj9365e3f2010-01-01 19:55:17 +0000665 : uregs.xip - 1;
666 /* -1: refer to calling insn, not the RA */
sewardj39f34232007-11-09 23:02:28 +0000667 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000668 VG_(printf)(" ipsH[%d]=%#08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000669 uregs.xip = uregs.xip - 1; /* as per comment at the head of this loop */
670 uregs.xsp += 8;
philippe46207652013-01-20 17:11:58 +0000671 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
sewardj39f34232007-11-09 23:02:28 +0000672 continue;
673 }
674
675 /* No luck at all. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000676 break;
njnd01fef72005-03-25 23:35:48 +0000677 }
sewardjacaec5f2005-08-19 16:02:59 +0000678
sewardj59570ff2010-01-01 11:59:33 +0000679 n_found = i;
680 return n_found;
681}
sewardjacaec5f2005-08-19 16:02:59 +0000682
sewardj59570ff2010-01-01 11:59:33 +0000683#endif
684
685/* -----------------------ppc32/64 ---------------------- */
686
carllcae0cc22014-08-07 23:17:29 +0000687#if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
688 || defined(VGP_ppc64le_linux)
sewardj59570ff2010-01-01 11:59:33 +0000689
690UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
691 /*OUT*/Addr* ips, UInt max_n_ips,
692 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
florian518850b2014-10-22 22:25:30 +0000693 const UnwindStartRegs* startRegs,
sewardjf5f1e122010-01-02 13:24:58 +0000694 Addr fp_max_orig )
sewardj59570ff2010-01-01 11:59:33 +0000695{
696 Bool lr_is_first_RA = False;
carllcae0cc22014-08-07 23:17:29 +0000697# if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
sewardj59570ff2010-01-01 11:59:33 +0000698 Word redir_stack_size = 0;
699 Word redirs_used = 0;
700# endif
philippe46207652013-01-20 17:11:58 +0000701 const Int cmrf = VG_(clo_merge_recursive_frames);
sewardj59570ff2010-01-01 11:59:33 +0000702
703 Bool debug = False;
704 Int i;
705 Addr fp_max;
706 UInt n_found = 0;
707
708 vg_assert(sizeof(Addr) == sizeof(UWord));
709 vg_assert(sizeof(Addr) == sizeof(void*));
710
sewardjf5f1e122010-01-02 13:24:58 +0000711 Addr ip = (Addr)startRegs->r_pc;
712 Addr sp = (Addr)startRegs->r_sp;
713 Addr fp = sp;
sewardj6e9de462011-06-28 07:25:29 +0000714# if defined(VGP_ppc32_linux)
sewardjf5f1e122010-01-02 13:24:58 +0000715 Addr lr = startRegs->misc.PPC32.r_lr;
carllcae0cc22014-08-07 23:17:29 +0000716# elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
sewardjf5f1e122010-01-02 13:24:58 +0000717 Addr lr = startRegs->misc.PPC64.r_lr;
718# endif
philippe01c353e2015-06-04 19:44:47 +0000719 Addr fp_min = sp - VG_STACK_REDZONE_SZB;
sewardjf5f1e122010-01-02 13:24:58 +0000720
sewardj59570ff2010-01-01 11:59:33 +0000721 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
722 stopping when the trail goes cold, which we guess to be
723 when FP is not a reasonable stack location. */
724
725 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
726 // current page, at least. Dunno if it helps.
727 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
728 fp_max = VG_PGROUNDUP(fp_max_orig);
729 if (fp_max >= sizeof(Addr))
730 fp_max -= sizeof(Addr);
731
732 if (debug)
floriana7d291d2015-08-08 21:08:31 +0000733 VG_(printf)("max_n_ips=%u fp_min=0x%lx fp_max_orig=0x%lx, "
sewardj59570ff2010-01-01 11:59:33 +0000734 "fp_max=0x%lx ip=0x%lx fp=0x%lx\n",
735 max_n_ips, fp_min, fp_max_orig, fp_max, ip, fp);
736
737 /* Assertion broken before main() is reached in pthreaded programs; the
738 * offending stack traces only have one item. --njn, 2002-aug-16 */
739 /* vg_assert(fp_min <= fp_max);*/
740 if (fp_min + 512 >= fp_max) {
741 /* If the stack limits look bogus, don't poke around ... but
742 don't bomb out either. */
743 if (sps) sps[0] = sp;
744 if (fps) fps[0] = fp;
745 ips[0] = ip;
746 return 1;
747 }
sewardj75ea7982005-11-14 15:18:25 +0000748
sewardjacaec5f2005-08-19 16:02:59 +0000749 /* fp is %r1. ip is %cia. Note, ppc uses r1 as both the stack and
750 frame pointers. */
751
carllcae0cc22014-08-07 23:17:29 +0000752# if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
sewardj15338c52006-10-17 01:31:58 +0000753 redir_stack_size = VEX_GUEST_PPC64_REDIR_STACK_SIZE;
754 redirs_used = 0;
sewardj15338c52006-10-17 01:31:58 +0000755# endif
756
carlla6954a42015-05-06 19:18:28 +0000757# if defined(VG_PLAT_USES_PPCTOC) || defined (VGP_ppc64le_linux)
sewardjcfb5e2b2006-01-19 03:47:30 +0000758 /* Deal with bogus LR values caused by function
sewardj15338c52006-10-17 01:31:58 +0000759 interception/wrapping on ppc-TOC platforms; see comment on
760 similar code a few lines further down. */
florianddd61ff2015-01-04 17:20:45 +0000761 if (lr == (Addr)&VG_(ppctoc_magic_redirect_return_stub)
sewardjcfb5e2b2006-01-19 03:47:30 +0000762 && VG_(is_valid_tid)(tid_if_known)) {
sewardj15338c52006-10-17 01:31:58 +0000763 Word hsp = VG_(threads)[tid_if_known].arch.vex.guest_REDIR_SP;
764 redirs_used++;
765 if (hsp >= 1 && hsp < redir_stack_size)
sewardjcfb5e2b2006-01-19 03:47:30 +0000766 lr = VG_(threads)[tid_if_known]
767 .arch.vex.guest_REDIR_STACK[hsp-1];
768 }
769# endif
770
sewardj15338c52006-10-17 01:31:58 +0000771 /* We have to determine whether or not LR currently holds this fn
772 (call it F)'s return address. It might not if F has previously
773 called some other function, hence overwriting LR with a pointer
774 to some part of F. Hence if LR and IP point to the same
775 function then we conclude LR does not hold this function's
776 return address; instead the LR at entry must have been saved in
777 the stack by F's prologue and so we must get it from there
778 instead. Note all this guff only applies to the innermost
779 frame. */
sewardjacaec5f2005-08-19 16:02:59 +0000780 lr_is_first_RA = False;
781 {
florian46cc0452014-10-25 19:20:38 +0000782 const HChar *buf_lr, *buf_ip;
sewardjb1ae15d2008-12-12 13:23:03 +0000783 /* The following conditional looks grossly inefficient and
784 surely could be majorly improved, with not much effort. */
florian46cc0452014-10-25 19:20:38 +0000785 if (VG_(get_fnname_raw) (lr, &buf_lr)) {
786 HChar buf_lr_copy[VG_(strlen)(buf_lr) + 1];
787 VG_(strcpy)(buf_lr_copy, buf_lr);
788 if (VG_(get_fnname_raw) (ip, &buf_ip))
789 if (VG_(strcmp)(buf_lr_copy, buf_ip))
sewardjacaec5f2005-08-19 16:02:59 +0000790 lr_is_first_RA = True;
florian46cc0452014-10-25 19:20:38 +0000791 }
sewardjacaec5f2005-08-19 16:02:59 +0000792 }
793
sewardjb8b79ad2008-03-03 01:35:41 +0000794 if (sps) sps[0] = fp; /* NB. not sp */
795 if (fps) fps[0] = fp;
sewardjacaec5f2005-08-19 16:02:59 +0000796 ips[0] = ip;
797 i = 1;
sewardjacaec5f2005-08-19 16:02:59 +0000798
sewardjdb2ac812005-12-23 23:33:51 +0000799 if (fp_min <= fp && fp < fp_max-VG_WORDSIZE+1) {
sewardjacaec5f2005-08-19 16:02:59 +0000800
sewardj525e2322005-11-13 02:41:35 +0000801 /* initial FP is sane; keep going */
802 fp = (((UWord*)fp)[0]);
803
804 while (True) {
805
sewardj6e9de462011-06-28 07:25:29 +0000806 /* On ppc64-linux (ppc64-elf, really), the lr save
sewardj15338c52006-10-17 01:31:58 +0000807 slot is 2 words back from sp, whereas on ppc32-elf(?) it's
808 only one word back. */
carllcae0cc22014-08-07 23:17:29 +0000809# if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
sewardjdfbaa222006-01-18 04:25:20 +0000810 const Int lr_offset = 2;
811# else
812 const Int lr_offset = 1;
813# endif
sewardjdb2ac812005-12-23 23:33:51 +0000814
njn3a4b58f2009-05-07 23:08:10 +0000815 if (i >= max_n_ips)
sewardj525e2322005-11-13 02:41:35 +0000816 break;
817
818 /* Try to derive a new (ip,fp) pair from the current set. */
819
sewardjf98e1c02008-10-25 16:22:41 +0000820 if (fp_min <= fp && fp <= fp_max - lr_offset * sizeof(UWord)) {
sewardj525e2322005-11-13 02:41:35 +0000821 /* fp looks sane, so use it. */
822
823 if (i == 1 && lr_is_first_RA)
824 ip = lr;
825 else
sewardjdb2ac812005-12-23 23:33:51 +0000826 ip = (((UWord*)fp)[lr_offset]);
sewardj525e2322005-11-13 02:41:35 +0000827
carllcae0cc22014-08-07 23:17:29 +0000828# if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux)
sewardjdfbaa222006-01-18 04:25:20 +0000829 /* Nasty hack to do with function replacement/wrapping on
sewardj6e9de462011-06-28 07:25:29 +0000830 ppc64-linux. If LR points to our magic return stub,
831 then we are in a wrapped or intercepted function, in
832 which LR has been messed with. The original LR will
833 have been pushed onto the thread's hidden REDIR stack
834 one down from the top (top element is the saved R2) and
835 so we should restore the value from there instead.
836 Since nested redirections can and do happen, we keep
837 track of the number of nested LRs used by the unwinding
838 so far with 'redirs_used'. */
sewardj15338c52006-10-17 01:31:58 +0000839 if (ip == (Addr)&VG_(ppctoc_magic_redirect_return_stub)
sewardjdfbaa222006-01-18 04:25:20 +0000840 && VG_(is_valid_tid)(tid_if_known)) {
sewardjb8b79ad2008-03-03 01:35:41 +0000841 Word hsp = VG_(threads)[tid_if_known]
842 .arch.vex.guest_REDIR_SP;
sewardj15338c52006-10-17 01:31:58 +0000843 hsp -= 2 * redirs_used;
844 redirs_used ++;
845 if (hsp >= 1 && hsp < redir_stack_size)
sewardjdfbaa222006-01-18 04:25:20 +0000846 ip = VG_(threads)[tid_if_known]
847 .arch.vex.guest_REDIR_STACK[hsp-1];
848 }
849# endif
850
njn3a4b58f2009-05-07 23:08:10 +0000851 if (0 == ip || 1 == ip) break;
sewardjb8b79ad2008-03-03 01:35:41 +0000852 if (sps) sps[i] = fp; /* NB. not sp */
853 if (fps) fps[i] = fp;
tom88053262009-11-12 13:19:41 +0000854 fp = (((UWord*)fp)[0]);
sewardjb1ae15d2008-12-12 13:23:03 +0000855 ips[i++] = ip - 1; /* -1: refer to calling insn, not the RA */
sewardj525e2322005-11-13 02:41:35 +0000856 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000857 VG_(printf)(" ipsF[%d]=%#08lx\n", i-1, ips[i-1]);
sewardjb1ae15d2008-12-12 13:23:03 +0000858 ip = ip - 1; /* ip is probably dead at this point, but
859 play safe, a la x86/amd64 above. See
860 extensive comments above. */
philippe46207652013-01-20 17:11:58 +0000861 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
sewardj525e2322005-11-13 02:41:35 +0000862 continue;
863 }
864
865 /* No luck there. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000866 break;
sewardjacaec5f2005-08-19 16:02:59 +0000867 }
sewardjacaec5f2005-08-19 16:02:59 +0000868 }
869
sewardj59570ff2010-01-01 11:59:33 +0000870 n_found = i;
871 return n_found;
872}
873
874#endif
875
876/* ------------------------ arm ------------------------- */
877
878#if defined(VGP_arm_linux)
879
sewardje947ce12012-06-15 16:20:23 +0000880static Bool in_same_fn ( Addr a1, Addr a2 )
881{
florian46cc0452014-10-25 19:20:38 +0000882 const HChar *buf_a1, *buf_a2;
sewardje947ce12012-06-15 16:20:23 +0000883 /* The following conditional looks grossly inefficient and
884 surely could be majorly improved, with not much effort. */
florian46cc0452014-10-25 19:20:38 +0000885 if (VG_(get_fnname_raw) (a1, &buf_a1)) {
886 HChar buf_a1_copy[VG_(strlen)(buf_a1) + 1];
887 VG_(strcpy)(buf_a1_copy, buf_a1);
888 if (VG_(get_fnname_raw) (a2, &buf_a2))
weidendo30e866e2014-11-05 19:46:21 +0000889 if (VG_(strcmp)(buf_a1_copy, buf_a2))
sewardje947ce12012-06-15 16:20:23 +0000890 return True;
florian46cc0452014-10-25 19:20:38 +0000891 }
sewardje947ce12012-06-15 16:20:23 +0000892 return False;
893}
894
895static Bool in_same_page ( Addr a1, Addr a2 ) {
896 return (a1 & ~0xFFF) == (a2 & ~0xFFF);
897}
898
899static Addr abs_diff ( Addr a1, Addr a2 ) {
900 return (Addr)(a1 > a2 ? a1 - a2 : a2 - a1);
901}
902
903static Bool has_XT_perms ( Addr a )
904{
905 NSegment const* seg = VG_(am_find_nsegment)(a);
906 return seg && seg->hasX && seg->hasT;
907}
908
909static Bool looks_like_Thumb_call32 ( UShort w0, UShort w1 )
910{
911 if (0)
912 VG_(printf)("isT32call %04x %04x\n", (UInt)w0, (UInt)w1);
913 // BL simm26
914 if ((w0 & 0xF800) == 0xF000 && (w1 & 0xC000) == 0xC000) return True;
915 // BLX simm26
916 if ((w0 & 0xF800) == 0xF000 && (w1 & 0xC000) == 0xC000) return True;
917 return False;
918}
919
920static Bool looks_like_Thumb_call16 ( UShort w0 )
921{
922 return False;
923}
924
925static Bool looks_like_ARM_call ( UInt a0 )
926{
927 if (0)
928 VG_(printf)("isA32call %08x\n", a0);
929 // Leading E forces unconditional only -- fix
930 if ((a0 & 0xFF000000) == 0xEB000000) return True;
931 return False;
932}
933
934static Bool looks_like_RA ( Addr ra )
935{
936 /* 'ra' is a plausible return address if it points to
937 an instruction after a call insn. */
938 Bool isT = (ra & 1);
939 if (isT) {
940 // returning to Thumb code
941 ra &= ~1;
942 ra -= 4;
943 if (has_XT_perms(ra)) {
944 UShort w0 = *(UShort*)ra;
945 UShort w1 = in_same_page(ra, ra+2) ? *(UShort*)(ra+2) : 0;
946 if (looks_like_Thumb_call16(w1) || looks_like_Thumb_call32(w0,w1))
947 return True;
948 }
949 } else {
950 // ARM
951 ra &= ~3;
952 ra -= 4;
953 if (has_XT_perms(ra)) {
954 UInt a0 = *(UInt*)ra;
955 if (looks_like_ARM_call(a0))
956 return True;
957 }
958 }
959 return False;
960}
961
sewardj59570ff2010-01-01 11:59:33 +0000962UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
963 /*OUT*/Addr* ips, UInt max_n_ips,
964 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
florian518850b2014-10-22 22:25:30 +0000965 const UnwindStartRegs* startRegs,
sewardj59570ff2010-01-01 11:59:33 +0000966 Addr fp_max_orig )
967{
968 Bool debug = False;
969 Int i;
970 Addr fp_max;
971 UInt n_found = 0;
philippe46207652013-01-20 17:11:58 +0000972 const Int cmrf = VG_(clo_merge_recursive_frames);
sewardj59570ff2010-01-01 11:59:33 +0000973
974 vg_assert(sizeof(Addr) == sizeof(UWord));
975 vg_assert(sizeof(Addr) == sizeof(void*));
976
sewardj3026f712010-01-01 18:46:41 +0000977 D3UnwindRegs uregs;
sewardjfa5ce562010-09-23 22:05:59 +0000978 uregs.r15 = startRegs->r_pc & 0xFFFFFFFE;
sewardj3026f712010-01-01 18:46:41 +0000979 uregs.r14 = startRegs->misc.ARM.r14;
980 uregs.r13 = startRegs->r_sp;
981 uregs.r12 = startRegs->misc.ARM.r12;
982 uregs.r11 = startRegs->misc.ARM.r11;
sewardjfa5ce562010-09-23 22:05:59 +0000983 uregs.r7 = startRegs->misc.ARM.r7;
philippe01c353e2015-06-04 19:44:47 +0000984 Addr fp_min = uregs.r13 - VG_STACK_REDZONE_SZB;
sewardj59570ff2010-01-01 11:59:33 +0000985
986 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
987 stopping when the trail goes cold, which we guess to be
988 when FP is not a reasonable stack location. */
989
990 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
991 // current page, at least. Dunno if it helps.
992 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
993 fp_max = VG_PGROUNDUP(fp_max_orig);
994 if (fp_max >= sizeof(Addr))
995 fp_max -= sizeof(Addr);
996
997 if (debug)
floriana7d291d2015-08-08 21:08:31 +0000998 VG_(printf)("\nmax_n_ips=%u fp_min=0x%lx fp_max_orig=0x%lx, "
sewardj59570ff2010-01-01 11:59:33 +0000999 "fp_max=0x%lx r15=0x%lx r13=0x%lx\n",
sewardj3026f712010-01-01 18:46:41 +00001000 max_n_ips, fp_min, fp_max_orig, fp_max,
1001 uregs.r15, uregs.r13);
sewardj59570ff2010-01-01 11:59:33 +00001002
1003 /* Assertion broken before main() is reached in pthreaded programs; the
1004 * offending stack traces only have one item. --njn, 2002-aug-16 */
1005 /* vg_assert(fp_min <= fp_max);*/
1006 // On Darwin, this kicks in for pthread-related stack traces, so they're
1007 // only 1 entry long which is wrong.
1008 if (fp_min + 512 >= fp_max) {
1009 /* If the stack limits look bogus, don't poke around ... but
1010 don't bomb out either. */
sewardj3026f712010-01-01 18:46:41 +00001011 if (sps) sps[0] = uregs.r13;
sewardj59570ff2010-01-01 11:59:33 +00001012 if (fps) fps[0] = 0;
sewardj3026f712010-01-01 18:46:41 +00001013 ips[0] = uregs.r15;
sewardj59570ff2010-01-01 11:59:33 +00001014 return 1;
1015 }
1016
1017 /* */
1018
sewardj3026f712010-01-01 18:46:41 +00001019 if (sps) sps[0] = uregs.r13;
sewardj59570ff2010-01-01 11:59:33 +00001020 if (fps) fps[0] = 0;
sewardj3026f712010-01-01 18:46:41 +00001021 ips[0] = uregs.r15;
sewardj59570ff2010-01-01 11:59:33 +00001022 i = 1;
1023
1024 /* Loop unwinding the stack. */
sewardje947ce12012-06-15 16:20:23 +00001025 Bool do_stack_scan = False;
sewardj59570ff2010-01-01 11:59:33 +00001026
sewardj49984ea2013-10-18 13:21:26 +00001027 /* First try the Official Way, using Dwarf CFI. */
sewardj59570ff2010-01-01 11:59:33 +00001028 while (True) {
1029 if (debug) {
sewardj3026f712010-01-01 18:46:41 +00001030 VG_(printf)("i: %d, r15: 0x%lx, r13: 0x%lx\n",
1031 i, uregs.r15, uregs.r13);
sewardj59570ff2010-01-01 11:59:33 +00001032 }
1033
1034 if (i >= max_n_ips)
1035 break;
1036
sewardj3026f712010-01-01 18:46:41 +00001037 if (VG_(use_CF_info)( &uregs, fp_min, fp_max )) {
1038 if (sps) sps[i] = uregs.r13;
sewardj59570ff2010-01-01 11:59:33 +00001039 if (fps) fps[i] = 0;
sewardjfa5ce562010-09-23 22:05:59 +00001040 ips[i++] = (uregs.r15 & 0xFFFFFFFE) - 1;
sewardj59570ff2010-01-01 11:59:33 +00001041 if (debug)
sewardj3026f712010-01-01 18:46:41 +00001042 VG_(printf)("USING CFI: r15: 0x%lx, r13: 0x%lx\n",
1043 uregs.r15, uregs.r13);
sewardjfa5ce562010-09-23 22:05:59 +00001044 uregs.r15 = (uregs.r15 & 0xFFFFFFFE) - 1;
philippe46207652013-01-20 17:11:58 +00001045 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
sewardj59570ff2010-01-01 11:59:33 +00001046 continue;
1047 }
sewardj49984ea2013-10-18 13:21:26 +00001048
sewardj59570ff2010-01-01 11:59:33 +00001049 /* No luck. We have to give up. */
sewardje947ce12012-06-15 16:20:23 +00001050 do_stack_scan = True;
sewardj59570ff2010-01-01 11:59:33 +00001051 break;
1052 }
sewardjacaec5f2005-08-19 16:02:59 +00001053
sewardj49984ea2013-10-18 13:21:26 +00001054 /* Now try Plan B (maybe) -- stack scanning. This often gives
1055 pretty bad results, so this has to be enabled explicitly by the
1056 user. */
1057 if (do_stack_scan
1058 && i < max_n_ips && i < (Int)VG_(clo_unw_stack_scan_thresh)) {
sewardje947ce12012-06-15 16:20:23 +00001059 Int nByStackScan = 0;
1060 Addr lr = uregs.r14;
1061 Addr sp = uregs.r13 & ~3;
1062 Addr pc = uregs.r15;
1063 // First see if LR contains
1064 // something that could be a valid return address.
1065 if (!in_same_fn(lr, pc) && looks_like_RA(lr)) {
1066 // take it only if 'cand' isn't obviously a duplicate
1067 // of the last found IP value
1068 Addr cand = (lr & 0xFFFFFFFE) - 1;
1069 if (abs_diff(cand, ips[i-1]) > 1) {
1070 if (sps) sps[i] = 0;
1071 if (fps) fps[i] = 0;
1072 ips[i++] = cand;
philippe46207652013-01-20 17:11:58 +00001073 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
sewardje947ce12012-06-15 16:20:23 +00001074 nByStackScan++;
1075 }
1076 }
1077 while (in_same_page(sp, uregs.r13)) {
1078 if (i >= max_n_ips)
1079 break;
1080 // we're in the same page; fairly safe to keep going
1081 UWord w = *(UWord*)(sp & ~0x3);
1082 if (looks_like_RA(w)) {
1083 Addr cand = (w & 0xFFFFFFFE) - 1;
1084 // take it only if 'cand' isn't obviously a duplicate
1085 // of the last found IP value
1086 if (abs_diff(cand, ips[i-1]) > 1) {
1087 if (sps) sps[i] = 0;
1088 if (fps) fps[i] = 0;
1089 ips[i++] = cand;
philippe46207652013-01-20 17:11:58 +00001090 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
sewardj49984ea2013-10-18 13:21:26 +00001091 if (++nByStackScan >= VG_(clo_unw_stack_scan_frames)) break;
sewardje947ce12012-06-15 16:20:23 +00001092 }
1093 }
1094 sp += 4;
1095 }
1096 }
1097
njnd01fef72005-03-25 23:35:48 +00001098 n_found = i;
njnd01fef72005-03-25 23:35:48 +00001099 return n_found;
1100}
1101
sewardj59570ff2010-01-01 11:59:33 +00001102#endif
1103
sewardjf0c12502014-01-12 12:54:00 +00001104/* ------------------------ arm64 ------------------------- */
1105
1106#if defined(VGP_arm64_linux)
1107
1108UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
1109 /*OUT*/Addr* ips, UInt max_n_ips,
1110 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
florian518850b2014-10-22 22:25:30 +00001111 const UnwindStartRegs* startRegs,
sewardjf0c12502014-01-12 12:54:00 +00001112 Addr fp_max_orig )
1113{
sewardj821283b2014-01-13 00:21:09 +00001114 Bool debug = False;
1115 Int i;
1116 Addr fp_max;
1117 UInt n_found = 0;
1118 const Int cmrf = VG_(clo_merge_recursive_frames);
1119
1120 vg_assert(sizeof(Addr) == sizeof(UWord));
1121 vg_assert(sizeof(Addr) == sizeof(void*));
1122
1123 D3UnwindRegs uregs;
1124 uregs.pc = startRegs->r_pc;
1125 uregs.sp = startRegs->r_sp;
1126 uregs.x30 = startRegs->misc.ARM64.x30;
1127 uregs.x29 = startRegs->misc.ARM64.x29;
philippe01c353e2015-06-04 19:44:47 +00001128 Addr fp_min = uregs.sp - VG_STACK_REDZONE_SZB;
sewardj821283b2014-01-13 00:21:09 +00001129
1130 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
1131 stopping when the trail goes cold, which we guess to be
1132 when FP is not a reasonable stack location. */
1133
1134 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
1135 // current page, at least. Dunno if it helps.
1136 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
1137 fp_max = VG_PGROUNDUP(fp_max_orig);
1138 if (fp_max >= sizeof(Addr))
1139 fp_max -= sizeof(Addr);
1140
1141 if (debug)
floriana7d291d2015-08-08 21:08:31 +00001142 VG_(printf)("\nmax_n_ips=%u fp_min=0x%lx fp_max_orig=0x%lx, "
sewardj821283b2014-01-13 00:21:09 +00001143 "fp_max=0x%lx PC=0x%lx SP=0x%lx\n",
1144 max_n_ips, fp_min, fp_max_orig, fp_max,
1145 uregs.pc, uregs.sp);
1146
1147 /* Assertion broken before main() is reached in pthreaded programs; the
1148 * offending stack traces only have one item. --njn, 2002-aug-16 */
1149 /* vg_assert(fp_min <= fp_max);*/
1150 // On Darwin, this kicks in for pthread-related stack traces, so they're
1151 // only 1 entry long which is wrong.
1152 if (fp_min + 512 >= fp_max) {
1153 /* If the stack limits look bogus, don't poke around ... but
1154 don't bomb out either. */
1155 if (sps) sps[0] = uregs.sp;
1156 if (fps) fps[0] = uregs.x29;
1157 ips[0] = uregs.pc;
1158 return 1;
1159 }
1160
1161 /* */
1162
1163 if (sps) sps[0] = uregs.sp;
1164 if (fps) fps[0] = uregs.x29;
1165 ips[0] = uregs.pc;
1166 i = 1;
1167
1168 /* Loop unwinding the stack, using CFI. */
1169 while (True) {
1170 if (debug) {
1171 VG_(printf)("i: %d, pc: 0x%lx, sp: 0x%lx\n",
1172 i, uregs.pc, uregs.sp);
1173 }
1174
1175 if (i >= max_n_ips)
1176 break;
1177
1178 if (VG_(use_CF_info)( &uregs, fp_min, fp_max )) {
1179 if (sps) sps[i] = uregs.sp;
1180 if (fps) fps[i] = uregs.x29;
1181 ips[i++] = uregs.pc - 1;
1182 if (debug)
1183 VG_(printf)("USING CFI: pc: 0x%lx, sp: 0x%lx\n",
1184 uregs.pc, uregs.sp);
1185 uregs.pc = uregs.pc - 1;
1186 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
1187 continue;
1188 }
1189
1190 /* No luck. We have to give up. */
1191 break;
1192 }
1193
1194 n_found = i;
1195 return n_found;
sewardjf0c12502014-01-12 12:54:00 +00001196}
1197
1198#endif
1199
sewardjb5b87402011-03-07 16:05:35 +00001200/* ------------------------ s390x ------------------------- */
sewardj5db15402012-06-07 09:13:21 +00001201
sewardjb5b87402011-03-07 16:05:35 +00001202#if defined(VGP_s390x_linux)
sewardj5db15402012-06-07 09:13:21 +00001203
sewardjb5b87402011-03-07 16:05:35 +00001204UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
1205 /*OUT*/Addr* ips, UInt max_n_ips,
1206 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
florian518850b2014-10-22 22:25:30 +00001207 const UnwindStartRegs* startRegs,
sewardjb5b87402011-03-07 16:05:35 +00001208 Addr fp_max_orig )
1209{
1210 Bool debug = False;
1211 Int i;
1212 Addr fp_max;
1213 UInt n_found = 0;
philippe46207652013-01-20 17:11:58 +00001214 const Int cmrf = VG_(clo_merge_recursive_frames);
sewardjb5b87402011-03-07 16:05:35 +00001215
1216 vg_assert(sizeof(Addr) == sizeof(UWord));
1217 vg_assert(sizeof(Addr) == sizeof(void*));
1218
1219 D3UnwindRegs uregs;
1220 uregs.ia = startRegs->r_pc;
1221 uregs.sp = startRegs->r_sp;
philippe01c353e2015-06-04 19:44:47 +00001222 Addr fp_min = uregs.sp - VG_STACK_REDZONE_SZB;
sewardjb5b87402011-03-07 16:05:35 +00001223 uregs.fp = startRegs->misc.S390X.r_fp;
1224 uregs.lr = startRegs->misc.S390X.r_lr;
1225
1226 fp_max = VG_PGROUNDUP(fp_max_orig);
1227 if (fp_max >= sizeof(Addr))
1228 fp_max -= sizeof(Addr);
1229
1230 if (debug)
floriana7d291d2015-08-08 21:08:31 +00001231 VG_(printf)("max_n_ips=%u fp_min=0x%lx fp_max_orig=0x%lx, "
sewardjb5b87402011-03-07 16:05:35 +00001232 "fp_max=0x%lx IA=0x%lx SP=0x%lx FP=0x%lx\n",
1233 max_n_ips, fp_min, fp_max_orig, fp_max,
1234 uregs.ia, uregs.sp,uregs.fp);
1235
1236 /* The first frame is pretty obvious */
1237 ips[0] = uregs.ia;
1238 if (sps) sps[0] = uregs.sp;
1239 if (fps) fps[0] = uregs.fp;
1240 i = 1;
1241
1242 /* for everything else we have to rely on the eh_frame. gcc defaults to
1243 not create a backchain and all the other tools (like gdb) also have
1244 to use the CFI. */
1245 while (True) {
1246 if (i >= max_n_ips)
1247 break;
1248
1249 if (VG_(use_CF_info)( &uregs, fp_min, fp_max )) {
1250 if (sps) sps[i] = uregs.sp;
1251 if (fps) fps[i] = uregs.fp;
1252 ips[i++] = uregs.ia - 1;
1253 uregs.ia = uregs.ia - 1;
philippe46207652013-01-20 17:11:58 +00001254 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
sewardjb5b87402011-03-07 16:05:35 +00001255 continue;
1256 }
1257 /* A problem on the first frame? Lets assume it was a bad jump.
1258 We will use the link register and the current stack and frame
1259 pointers and see if we can use the CFI in the next round. */
1260 if (i == 1) {
1261 if (sps) {
1262 sps[i] = sps[0];
1263 uregs.sp = sps[0];
1264 }
1265 if (fps) {
1266 fps[i] = fps[0];
1267 uregs.fp = fps[0];
1268 }
1269 uregs.ia = uregs.lr - 1;
1270 ips[i++] = uregs.lr - 1;
philippe46207652013-01-20 17:11:58 +00001271 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
sewardjb5b87402011-03-07 16:05:35 +00001272 continue;
1273 }
1274
1275 /* No luck. We have to give up. */
1276 break;
1277 }
1278
1279 n_found = i;
1280 return n_found;
1281}
sewardj5db15402012-06-07 09:13:21 +00001282
sewardjb5b87402011-03-07 16:05:35 +00001283#endif
1284
petarj4df0bfc2013-02-27 23:17:33 +00001285/* ------------------------ mips 32/64 ------------------------- */
1286#if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
sewardj5db15402012-06-07 09:13:21 +00001287UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
1288 /*OUT*/Addr* ips, UInt max_n_ips,
1289 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
florian518850b2014-10-22 22:25:30 +00001290 const UnwindStartRegs* startRegs,
sewardj5db15402012-06-07 09:13:21 +00001291 Addr fp_max_orig )
1292{
1293 Bool debug = False;
1294 Int i;
1295 Addr fp_max;
1296 UInt n_found = 0;
philippe46207652013-01-20 17:11:58 +00001297 const Int cmrf = VG_(clo_merge_recursive_frames);
sewardj5db15402012-06-07 09:13:21 +00001298
1299 vg_assert(sizeof(Addr) == sizeof(UWord));
1300 vg_assert(sizeof(Addr) == sizeof(void*));
1301
1302 D3UnwindRegs uregs;
1303 uregs.pc = startRegs->r_pc;
1304 uregs.sp = startRegs->r_sp;
philippe01c353e2015-06-04 19:44:47 +00001305 Addr fp_min = uregs.sp - VG_STACK_REDZONE_SZB;
sewardj5db15402012-06-07 09:13:21 +00001306
petarj4df0bfc2013-02-27 23:17:33 +00001307#if defined(VGP_mips32_linux)
sewardj5db15402012-06-07 09:13:21 +00001308 uregs.fp = startRegs->misc.MIPS32.r30;
1309 uregs.ra = startRegs->misc.MIPS32.r31;
petarj4df0bfc2013-02-27 23:17:33 +00001310#elif defined(VGP_mips64_linux)
1311 uregs.fp = startRegs->misc.MIPS64.r30;
1312 uregs.ra = startRegs->misc.MIPS64.r31;
1313#endif
sewardj5db15402012-06-07 09:13:21 +00001314
1315 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
1316 stopping when the trail goes cold, which we guess to be
1317 when FP is not a reasonable stack location. */
1318
1319 fp_max = VG_PGROUNDUP(fp_max_orig);
1320 if (fp_max >= sizeof(Addr))
1321 fp_max -= sizeof(Addr);
1322
1323 if (debug)
floriana7d291d2015-08-08 21:08:31 +00001324 VG_(printf)("max_n_ips=%u fp_min=0x%lx fp_max_orig=0x%lx, "
sewardj5db15402012-06-07 09:13:21 +00001325 "fp_max=0x%lx pc=0x%lx sp=0x%lx fp=0x%lx\n",
1326 max_n_ips, fp_min, fp_max_orig, fp_max,
1327 uregs.pc, uregs.sp, uregs.fp);
1328
1329 if (sps) sps[0] = uregs.sp;
1330 if (fps) fps[0] = uregs.fp;
1331 ips[0] = uregs.pc;
1332 i = 1;
1333
1334 /* Loop unwinding the stack. */
1335
1336 while (True) {
1337 if (debug) {
1338 VG_(printf)("i: %d, pc: 0x%lx, sp: 0x%lx, ra: 0x%lx\n",
1339 i, uregs.pc, uregs.sp, uregs.ra);
1340 }
1341 if (i >= max_n_ips)
1342 break;
1343
petarj92280672012-09-09 01:56:56 +00001344 D3UnwindRegs uregs_copy = uregs;
sewardj5db15402012-06-07 09:13:21 +00001345 if (VG_(use_CF_info)( &uregs, fp_min, fp_max )) {
1346 if (debug)
1347 VG_(printf)("USING CFI: pc: 0x%lx, sp: 0x%lx, ra: 0x%lx\n",
1348 uregs.pc, uregs.sp, uregs.ra);
petarj92280672012-09-09 01:56:56 +00001349 if (0 != uregs.pc && 1 != uregs.pc) {
1350 if (sps) sps[i] = uregs.sp;
1351 if (fps) fps[i] = uregs.fp;
1352 ips[i++] = uregs.pc - 4;
1353 uregs.pc = uregs.pc - 4;
philippe46207652013-01-20 17:11:58 +00001354 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
petarj92280672012-09-09 01:56:56 +00001355 continue;
1356 } else
1357 uregs = uregs_copy;
sewardj5db15402012-06-07 09:13:21 +00001358 }
1359
1360 int seen_sp_adjust = 0;
1361 long frame_offset = 0;
1362 PtrdiffT offset;
1363 if (VG_(get_inst_offset_in_function)(uregs.pc, &offset)) {
1364 Addr start_pc = uregs.pc - offset;
1365 Addr limit_pc = uregs.pc;
1366 Addr cur_pc;
1367 for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4) {
1368 unsigned long inst, high_word, low_word;
1369 unsigned long * cur_inst;
sewardj5db15402012-06-07 09:13:21 +00001370 /* Fetch the instruction. */
1371 cur_inst = (unsigned long *)cur_pc;
1372 inst = *((UInt *) cur_inst);
1373 if(debug)
1374 VG_(printf)("cur_pc: 0x%lx, inst: 0x%lx\n", cur_pc, inst);
1375
1376 /* Save some code by pre-extracting some useful fields. */
1377 high_word = (inst >> 16) & 0xffff;
1378 low_word = inst & 0xffff;
sewardj5db15402012-06-07 09:13:21 +00001379
1380 if (high_word == 0x27bd /* addiu $sp,$sp,-i */
1381 || high_word == 0x23bd /* addi $sp,$sp,-i */
1382 || high_word == 0x67bd) { /* daddiu $sp,$sp,-i */
1383 if (low_word & 0x8000) /* negative stack adjustment? */
1384 frame_offset += 0x10000 - low_word;
1385 else
1386 /* Exit loop if a positive stack adjustment is found, which
1387 usually means that the stack cleanup code in the function
1388 epilogue is reached. */
1389 break;
1390 seen_sp_adjust = 1;
1391 }
1392 }
1393 if(debug)
1394 VG_(printf)("offset: 0x%lx\n", frame_offset);
1395 }
1396 if (seen_sp_adjust) {
1397 if (0 == uregs.pc || 1 == uregs.pc) break;
1398 if (uregs.pc == uregs.ra - 8) break;
1399 if (sps) {
1400 sps[i] = uregs.sp + frame_offset;
1401 }
1402 uregs.sp = uregs.sp + frame_offset;
1403
1404 if (fps) {
1405 fps[i] = fps[0];
1406 uregs.fp = fps[0];
1407 }
1408 if (0 == uregs.ra || 1 == uregs.ra) break;
1409 uregs.pc = uregs.ra - 8;
1410 ips[i++] = uregs.ra - 8;
philippe46207652013-01-20 17:11:58 +00001411 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
sewardj5db15402012-06-07 09:13:21 +00001412 continue;
1413 }
1414
1415 if (i == 1) {
1416 if (sps) {
1417 sps[i] = sps[0];
1418 uregs.sp = sps[0];
1419 }
1420 if (fps) {
1421 fps[i] = fps[0];
1422 uregs.fp = fps[0];
1423 }
1424 if (0 == uregs.ra || 1 == uregs.ra) break;
1425 uregs.pc = uregs.ra - 8;
1426 ips[i++] = uregs.ra - 8;
philippe46207652013-01-20 17:11:58 +00001427 if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
sewardj5db15402012-06-07 09:13:21 +00001428 continue;
1429 }
1430 /* No luck. We have to give up. */
1431 break;
1432 }
1433
1434 n_found = i;
1435 return n_found;
1436}
1437
1438#endif
1439
sewardj112711a2015-04-10 12:30:09 +00001440/* ------------------------ tilegx ------------------------- */
1441#if defined(VGP_tilegx_linux)
1442UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
1443 /*OUT*/Addr* ips, UInt max_n_ips,
1444 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
1445 const UnwindStartRegs* startRegs,
1446 Addr fp_max_orig )
1447{
1448 Bool debug = False;
1449 Int i;
1450 Addr fp_max;
1451 UInt n_found = 0;
1452 const Int cmrf = VG_(clo_merge_recursive_frames);
1453
1454 vg_assert(sizeof(Addr) == sizeof(UWord));
1455 vg_assert(sizeof(Addr) == sizeof(void*));
1456
1457 D3UnwindRegs uregs;
1458 uregs.pc = startRegs->r_pc;
1459 uregs.sp = startRegs->r_sp;
philippe01c353e2015-06-04 19:44:47 +00001460 Addr fp_min = uregs.sp - VG_STACK_REDZONE_SZB;
sewardj112711a2015-04-10 12:30:09 +00001461
1462 uregs.fp = startRegs->misc.TILEGX.r52;
1463 uregs.lr = startRegs->misc.TILEGX.r55;
1464
1465 fp_max = VG_PGROUNDUP(fp_max_orig);
1466 if (fp_max >= sizeof(Addr))
1467 fp_max -= sizeof(Addr);
1468
1469 if (debug)
floriana7d291d2015-08-08 21:08:31 +00001470 VG_(printf)("max_n_ips=%u fp_min=0x%lx fp_max_orig=0x%lx, "
sewardj112711a2015-04-10 12:30:09 +00001471 "fp_max=0x%lx pc=0x%lx sp=0x%lx fp=0x%lx\n",
1472 max_n_ips, fp_min, fp_max_orig, fp_max,
1473 uregs.pc, uregs.sp, uregs.fp);
1474
1475 if (sps) sps[0] = uregs.sp;
1476 if (fps) fps[0] = uregs.fp;
1477 ips[0] = uregs.pc;
1478 i = 1;
1479
1480 /* Loop unwinding the stack. */
1481 while (True) {
1482 if (debug) {
1483 VG_(printf)("i: %d, pc: 0x%lx, sp: 0x%lx, lr: 0x%lx\n",
1484 i, uregs.pc, uregs.sp, uregs.lr);
1485 }
1486 if (i >= max_n_ips)
1487 break;
1488
1489 D3UnwindRegs uregs_copy = uregs;
1490 if (VG_(use_CF_info)( &uregs, fp_min, fp_max )) {
1491 if (debug)
1492 VG_(printf)("USING CFI: pc: 0x%lx, sp: 0x%lx, fp: 0x%lx, lr: 0x%lx\n",
1493 uregs.pc, uregs.sp, uregs.fp, uregs.lr);
1494 if (0 != uregs.pc && 1 != uregs.pc &&
1495 (uregs.pc < fp_min || uregs.pc > fp_max)) {
1496 if (sps) sps[i] = uregs.sp;
1497 if (fps) fps[i] = uregs.fp;
1498 if (uregs.pc != uregs_copy.pc && uregs.sp != uregs_copy.sp)
1499 ips[i++] = uregs.pc - 8;
1500 uregs.pc = uregs.pc - 8;
1501 if (UNLIKELY(cmrf > 0)) { RECURSIVE_MERGE(cmrf,ips,i); };
1502 continue;
1503 } else
1504 uregs = uregs_copy;
1505 }
1506
1507 Long frame_offset = 0;
1508 PtrdiffT offset;
1509 if (VG_(get_inst_offset_in_function)(uregs.pc, &offset)) {
1510 Addr start_pc = uregs.pc;
1511 Addr limit_pc = uregs.pc - offset;
1512 Addr cur_pc;
1513 /* Try to find any stack adjustment from current instruction
1514 bundles downward. */
1515 for (cur_pc = start_pc; cur_pc > limit_pc; cur_pc -= 8) {
1516 ULong inst;
1517 Long off = 0;
1518 ULong* cur_inst;
1519 /* Fetch the instruction. */
1520 cur_inst = (ULong *)cur_pc;
1521 inst = *cur_inst;
1522 if(debug)
1523 VG_(printf)("cur_pc: 0x%lx, inst: 0x%lx\n", cur_pc, inst);
1524
1525 if ((inst & 0xC000000000000000ULL) == 0) {
1526 /* Bundle is X type. */
1527 if ((inst & 0xC000000070000fffULL) ==
1528 (0x0000000010000db6ULL)) {
1529 /* addli at X0 */
1530 off = (short)(0xFFFF & (inst >> 12));
1531 } else if ((inst & 0xF80007ff80000000ULL) ==
1532 (0x000006db00000000ULL)) {
1533 /* addli at X1 addli*/
1534 off = (short)(0xFFFF & (inst >> 43));
1535 } else if ((inst & 0xC00000007FF00FFFULL) ==
1536 (0x0000000040100db6ULL)) {
1537 /* addi at X0 */
1538 off = (char)(0xFF & (inst >> 12));
1539 } else if ((inst & 0xFFF807ff80000000ULL) ==
1540 (0x180806db00000000ULL)) {
1541 /* addi at X1 */
1542 off = (char)(0xFF & (inst >> 43));
1543 }
1544 } else {
1545 /* Bundle is Y type. */
1546 if ((inst & 0x0000000078000FFFULL) ==
1547 (0x0000000000000db6ULL)) {
1548 /* addi at Y0 */
1549 off = (char)(0xFF & (inst >> 12));
1550 } else if ((inst & 0x3C0007FF80000000ULL) ==
1551 (0x040006db00000000ULL)) {
1552 /* addi at Y1 */
1553 off = (char)(0xFF & (inst >> 43));
1554 }
1555 }
1556
1557 if(debug && off)
1558 VG_(printf)("offset: -0x%lx\n", -off);
1559
1560 if (off < 0) {
1561 /* frame offset should be modular of 8 */
1562 vg_assert((off & 7) == 0);
1563 frame_offset += off;
1564 } else if (off > 0)
1565 /* Exit loop if a positive stack adjustment is found, which
1566 usually means that the stack cleanup code in the function
1567 epilogue is reached. */
1568 break;
1569 }
1570 }
1571
1572 if (frame_offset < 0) {
1573 if (0 == uregs.pc || 1 == uregs.pc) break;
1574
1575 /* Subtract the offset from the current stack. */
1576 uregs.sp = uregs.sp + (ULong)(-frame_offset);
1577
1578 if (debug)
1579 VG_(printf)("offset: i: %d, pc: 0x%lx, sp: 0x%lx, lr: 0x%lx\n",
1580 i, uregs.pc, uregs.sp, uregs.lr);
1581
1582 if (uregs.pc == uregs.lr - 8 ||
1583 uregs.lr - 8 >= fp_min && uregs.lr - 8 <= fp_max) {
1584 if (debug)
1585 VG_(printf)("new lr = 0x%lx\n", *(ULong*)uregs.sp);
1586 uregs.lr = *(ULong*)uregs.sp;
1587 }
1588
1589 uregs.pc = uregs.lr - 8;
1590
1591 if (uregs.lr != 0) {
1592 /* Avoid the invalid pc = 0xffff...ff8 */
1593 if (sps)
1594 sps[i] = uregs.sp;
1595
1596 if (fps)
1597 fps[i] = fps[0];
1598
1599 ips[i++] = uregs.pc;
1600
1601 if (UNLIKELY(cmrf > 0)) { RECURSIVE_MERGE(cmrf,ips,i); };
1602 }
1603 continue;
1604 }
1605
1606 /* A special case for the 1st frame. Assume it was a bad jump.
1607 Use the link register "lr" and current stack and frame to
1608 try again. */
1609 if (i == 1) {
1610 if (sps) {
1611 sps[1] = sps[0];
1612 uregs.sp = sps[0];
1613 }
1614 if (fps) {
1615 fps[1] = fps[0];
1616 uregs.fp = fps[0];
1617 }
1618 if (0 == uregs.lr || 1 == uregs.lr)
1619 break;
1620
1621 uregs.pc = uregs.lr - 8;
1622 ips[i++] = uregs.lr - 8;
1623 if (UNLIKELY(cmrf > 0)) { RECURSIVE_MERGE(cmrf,ips,i); };
1624 continue;
1625 }
1626 /* No luck. We have to give up. */
1627 break;
1628 }
1629
1630 if (debug) {
1631 /* Display the back trace. */
1632 Int ii ;
1633 for ( ii = 0; ii < i; ii++) {
1634 if (sps) {
1635 VG_(printf)("%d: pc=%lx ", ii, ips[ii]);
1636 VG_(printf)("sp=%lx\n", sps[ii]);
1637 } else {
1638 VG_(printf)("%d: pc=%lx\n", ii, ips[ii]);
1639 }
1640 }
1641 }
1642
1643 n_found = i;
1644 return n_found;
1645}
1646#endif
sewardj5db15402012-06-07 09:13:21 +00001647
sewardj59570ff2010-01-01 11:59:33 +00001648/*------------------------------------------------------------*/
1649/*--- ---*/
1650/*--- END platform-dependent unwinder worker functions ---*/
1651/*--- ---*/
1652/*------------------------------------------------------------*/
1653
1654/*------------------------------------------------------------*/
1655/*--- Exported functions. ---*/
1656/*------------------------------------------------------------*/
1657
sewardjb8b79ad2008-03-03 01:35:41 +00001658UInt VG_(get_StackTrace) ( ThreadId tid,
njn3a4b58f2009-05-07 23:08:10 +00001659 /*OUT*/StackTrace ips, UInt max_n_ips,
sewardjb8b79ad2008-03-03 01:35:41 +00001660 /*OUT*/StackTrace sps,
1661 /*OUT*/StackTrace fps,
sewardj39f34232007-11-09 23:02:28 +00001662 Word first_ip_delta )
njnd01fef72005-03-25 23:35:48 +00001663{
sewardj59570ff2010-01-01 11:59:33 +00001664 /* Get the register values with which to start the unwind. */
1665 UnwindStartRegs startRegs;
1666 VG_(memset)( &startRegs, 0, sizeof(startRegs) );
1667 VG_(get_UnwindStartRegs)( &startRegs, tid );
1668
philippe38a74d22014-08-29 22:53:19 +00001669 Addr stack_highest_byte = VG_(threads)[tid].client_stack_highest_byte;
1670 Addr stack_lowest_byte = 0;
njnd01fef72005-03-25 23:35:48 +00001671
sewardjb9bce632005-06-21 01:41:34 +00001672# if defined(VGP_x86_linux)
sewardja672ea32006-04-29 18:03:14 +00001673 /* Nasty little hack to deal with syscalls - if libc is using its
1674 _dl_sysinfo_int80 function for syscalls (the TLS version does),
1675 then ip will always appear to be in that function when doing a
1676 syscall, not the actual libc function doing the syscall. This
1677 check sees if IP is within that function, and pops the return
1678 address off the stack so that ip is placed within the library
1679 function calling the syscall. This makes stack backtraces much
1680 more useful.
1681
1682 The function is assumed to look like this (from glibc-2.3.6 sources):
1683 _dl_sysinfo_int80:
1684 int $0x80
1685 ret
1686 That is 3 (2+1) bytes long. We could be more thorough and check
1687 the 3 bytes of the function are as expected, but I can't be
1688 bothered.
1689 */
1690 if (VG_(client__dl_sysinfo_int80) != 0 /* we know its address */
sewardj59570ff2010-01-01 11:59:33 +00001691 && startRegs.r_pc >= VG_(client__dl_sysinfo_int80)
1692 && startRegs.r_pc < VG_(client__dl_sysinfo_int80)+3
1693 && VG_(am_is_valid_for_client)(startRegs.r_pc, sizeof(Addr),
1694 VKI_PROT_READ)) {
1695 startRegs.r_pc = (ULong) *(Addr*)(UWord)startRegs.r_sp;
1696 startRegs.r_sp += (ULong) sizeof(Addr);
njnd01fef72005-03-25 23:35:48 +00001697 }
sewardjb9bce632005-06-21 01:41:34 +00001698# endif
1699
tom690c3c82008-02-08 15:17:07 +00001700 /* See if we can get a better idea of the stack limits */
sewardj59570ff2010-01-01 11:59:33 +00001701 VG_(stack_limits)( (Addr)startRegs.r_sp,
philippe38a74d22014-08-29 22:53:19 +00001702 &stack_lowest_byte, &stack_highest_byte );
tom690c3c82008-02-08 15:17:07 +00001703
sewardj39f34232007-11-09 23:02:28 +00001704 /* Take into account the first_ip_delta. */
sewardj59570ff2010-01-01 11:59:33 +00001705 startRegs.r_pc += (Long)(Word)first_ip_delta;
sewardj39f34232007-11-09 23:02:28 +00001706
njnd01fef72005-03-25 23:35:48 +00001707 if (0)
floriana5e06c32015-08-05 21:16:09 +00001708 VG_(printf)("tid %u: stack_highest=0x%08lx ip=0x%010llx "
sewardj59570ff2010-01-01 11:59:33 +00001709 "sp=0x%010llx\n",
floriana5e06c32015-08-05 21:16:09 +00001710 tid, stack_highest_byte,
sewardj59570ff2010-01-01 11:59:33 +00001711 startRegs.r_pc, startRegs.r_sp);
njnd01fef72005-03-25 23:35:48 +00001712
njn3a4b58f2009-05-07 23:08:10 +00001713 return VG_(get_StackTrace_wrk)(tid, ips, max_n_ips,
sewardjb8b79ad2008-03-03 01:35:41 +00001714 sps, fps,
sewardj59570ff2010-01-01 11:59:33 +00001715 &startRegs,
philippe38a74d22014-08-29 22:53:19 +00001716 stack_highest_byte);
njnd01fef72005-03-25 23:35:48 +00001717}
1718
sewardj588adef2009-08-15 22:41:51 +00001719static void printIpDesc(UInt n, Addr ip, void* uu_opaque)
njnd01fef72005-03-25 23:35:48 +00001720{
philippea0a73932014-06-15 15:42:20 +00001721 InlIPCursor *iipc = VG_(new_IIPC)(ip);
sewardj71bc3cb2005-05-19 00:25:45 +00001722
philippea0a73932014-06-15 15:42:20 +00001723 do {
florian770a8d22014-11-03 22:43:42 +00001724 const HChar *buf = VG_(describe_IP)(ip, iipc);
philippea0a73932014-06-15 15:42:20 +00001725 if (VG_(clo_xml)) {
1726 VG_(printf_xml)(" %s\n", buf);
1727 } else {
1728 VG_(message)(Vg_UserMsg, " %s %s\n",
1729 ( n == 0 ? "at" : "by" ), buf);
1730 }
1731 n++;
1732 // Increase n to show "at" for only one level.
1733 } while (VG_(next_IIPC)(iipc));
1734 VG_(delete_IIPC)(iipc);
njnd01fef72005-03-25 23:35:48 +00001735}
1736
1737/* Print a StackTrace. */
1738void VG_(pp_StackTrace) ( StackTrace ips, UInt n_ips )
1739{
1740 vg_assert( n_ips > 0 );
sewardj71bc3cb2005-05-19 00:25:45 +00001741
1742 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001743 VG_(printf_xml)(" <stack>\n");
sewardj71bc3cb2005-05-19 00:25:45 +00001744
sewardj588adef2009-08-15 22:41:51 +00001745 VG_(apply_StackTrace)( printIpDesc, NULL, ips, n_ips );
sewardj71bc3cb2005-05-19 00:25:45 +00001746
1747 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +00001748 VG_(printf_xml)(" </stack>\n");
njnd01fef72005-03-25 23:35:48 +00001749}
1750
1751/* Get and immediately print a StackTrace. */
njn3a4b58f2009-05-07 23:08:10 +00001752void VG_(get_and_pp_StackTrace) ( ThreadId tid, UInt max_n_ips )
njnd01fef72005-03-25 23:35:48 +00001753{
njn3a4b58f2009-05-07 23:08:10 +00001754 Addr ips[max_n_ips];
1755 UInt n_ips
1756 = VG_(get_StackTrace)(tid, ips, max_n_ips,
sewardjb8b79ad2008-03-03 01:35:41 +00001757 NULL/*array to dump SP values in*/,
1758 NULL/*array to dump FP values in*/,
1759 0/*first_ip_delta*/);
njn3a4b58f2009-05-07 23:08:10 +00001760 VG_(pp_StackTrace)(ips, n_ips);
njnd01fef72005-03-25 23:35:48 +00001761}
1762
sewardj588adef2009-08-15 22:41:51 +00001763void VG_(apply_StackTrace)(
1764 void(*action)(UInt n, Addr ip, void* opaque),
1765 void* opaque,
1766 StackTrace ips, UInt n_ips
1767 )
njnd01fef72005-03-25 23:35:48 +00001768{
njnd01fef72005-03-25 23:35:48 +00001769 Bool main_done = False;
njnd01fef72005-03-25 23:35:48 +00001770 Int i = 0;
1771
1772 vg_assert(n_ips > 0);
1773 do {
1774 Addr ip = ips[i];
njnd01fef72005-03-25 23:35:48 +00001775
sewardj73cf4c62005-11-17 15:12:34 +00001776 // Stop after the first appearance of "main" or one of the other names
1777 // (the appearance of which is a pretty good sign that we've gone past
1778 // main without seeing it, for whatever reason)
njn68824432009-02-10 06:48:00 +00001779 if ( ! VG_(clo_show_below_main) ) {
1780 Vg_FnNameKind kind = VG_(get_fnname_kind_from_IP)(ip);
1781 if (Vg_FnNameMain == kind || Vg_FnNameBelowMain == kind) {
njnd01fef72005-03-25 23:35:48 +00001782 main_done = True;
njn68824432009-02-10 06:48:00 +00001783 }
njnd01fef72005-03-25 23:35:48 +00001784 }
1785
1786 // Act on the ip
sewardj588adef2009-08-15 22:41:51 +00001787 action(i, ip, opaque);
njnd01fef72005-03-25 23:35:48 +00001788
1789 i++;
njn3a4b58f2009-05-07 23:08:10 +00001790 } while (i < n_ips && !main_done);
njnd01fef72005-03-25 23:35:48 +00001791}
1792
1793
1794/*--------------------------------------------------------------------*/
njn24a6efb2005-06-20 03:36:51 +00001795/*--- end ---*/
njnd01fef72005-03-25 23:35:48 +00001796/*--------------------------------------------------------------------*/