blob: 489f6d71d8d49076ceb86ea2a2aae930fd7b4106 [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"
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"
sewardj14c7cc52007-02-25 15:08:24 +000043#include "pub_core_xarray.h"
sewardja672ea32006-04-29 18:03:14 +000044#include "pub_core_clientstate.h" // VG_(client__dl_sysinfo_int80)
njna7598f62005-06-18 03:27:58 +000045#include "pub_core_trampoline.h"
njnd01fef72005-03-25 23:35:48 +000046
sewardj59570ff2010-01-01 11:59:33 +000047
njnd01fef72005-03-25 23:35:48 +000048/*------------------------------------------------------------*/
sewardj59570ff2010-01-01 11:59:33 +000049/*--- ---*/
50/*--- BEGIN platform-dependent unwinder worker functions ---*/
51/*--- ---*/
njnd01fef72005-03-25 23:35:48 +000052/*------------------------------------------------------------*/
53
njn3a4b58f2009-05-07 23:08:10 +000054/* Take a snapshot of the client's stack, putting up to 'max_n_ips'
sewardjacaec5f2005-08-19 16:02:59 +000055 IPs into 'ips'. In order to be thread-safe, we pass in the
56 thread's IP SP, FP if that's meaningful, and LR if that's
57 meaningful. Returns number of IPs put in 'ips'.
sewardjdfbaa222006-01-18 04:25:20 +000058
59 If you know what the thread ID for this stack is, send that as the
60 first parameter, else send zero. This helps generate better stack
61 traces on ppc64-linux and has no effect on other platforms.
sewardjacaec5f2005-08-19 16:02:59 +000062*/
sewardj59570ff2010-01-01 11:59:33 +000063
64/* ------------------------ x86 ------------------------- */
65
66#if defined(VGP_x86_linux) || defined(VGP_x86_darwin)
67
sewardjb8b79ad2008-03-03 01:35:41 +000068UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
njn3a4b58f2009-05-07 23:08:10 +000069 /*OUT*/Addr* ips, UInt max_n_ips,
sewardjb8b79ad2008-03-03 01:35:41 +000070 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
sewardj59570ff2010-01-01 11:59:33 +000071 UnwindStartRegs* startRegs,
72 Addr fp_max_orig )
njnd01fef72005-03-25 23:35:48 +000073{
sewardjacaec5f2005-08-19 16:02:59 +000074 Bool debug = False;
75 Int i;
76 Addr fp_max;
77 UInt n_found = 0;
njnd01fef72005-03-25 23:35:48 +000078
sewardjacaec5f2005-08-19 16:02:59 +000079 vg_assert(sizeof(Addr) == sizeof(UWord));
80 vg_assert(sizeof(Addr) == sizeof(void*));
njnd01fef72005-03-25 23:35:48 +000081
sewardj9365e3f2010-01-01 19:55:17 +000082 D3UnwindRegs uregs;
83 uregs.xip = (Addr)startRegs->r_pc;
84 uregs.xsp = (Addr)startRegs->r_sp;
85 uregs.xbp = startRegs->misc.X86.r_ebp;
86 Addr fp_min = uregs.xsp;
sewardj59570ff2010-01-01 11:59:33 +000087
njn3a4b58f2009-05-07 23:08:10 +000088 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
njnc0ec8e92005-12-25 06:34:04 +000089 stopping when the trail goes cold, which we guess to be
sewardjacaec5f2005-08-19 16:02:59 +000090 when FP is not a reasonable stack location. */
91
njnd01fef72005-03-25 23:35:48 +000092 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
93 // current page, at least. Dunno if it helps.
94 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
sewardj45f4e7c2005-09-27 19:20:21 +000095 fp_max = VG_PGROUNDUP(fp_max_orig);
sewardjd0c0ea62008-03-03 22:20:51 +000096 if (fp_max >= sizeof(Addr))
97 fp_max -= sizeof(Addr);
njnd01fef72005-03-25 23:35:48 +000098
99 if (debug)
njn3a4b58f2009-05-07 23:08:10 +0000100 VG_(printf)("max_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
barta0b6b2c2008-07-07 06:49:24 +0000101 "fp_max=0x%lx ip=0x%lx fp=0x%lx\n",
sewardj9365e3f2010-01-01 19:55:17 +0000102 max_n_ips, fp_min, fp_max_orig, fp_max,
103 uregs.xip, uregs.xbp);
njnd01fef72005-03-25 23:35:48 +0000104
105 /* Assertion broken before main() is reached in pthreaded programs; the
106 * offending stack traces only have one item. --njn, 2002-aug-16 */
107 /* vg_assert(fp_min <= fp_max);*/
njnf76d27a2009-05-28 01:53:07 +0000108 // On Darwin, this kicks in for pthread-related stack traces, so they're
109 // only 1 entry long which is wrong.
sewardj59570ff2010-01-01 11:59:33 +0000110# if !defined(VGO_darwin)
sewardj5bdfbd22007-12-15 22:13:05 +0000111 if (fp_min + 512 >= fp_max) {
112 /* If the stack limits look bogus, don't poke around ... but
113 don't bomb out either. */
sewardj9365e3f2010-01-01 19:55:17 +0000114 if (sps) sps[0] = uregs.xsp;
115 if (fps) fps[0] = uregs.xbp;
116 ips[0] = uregs.xip;
sewardjacaec5f2005-08-19 16:02:59 +0000117 return 1;
118 }
sewardj59570ff2010-01-01 11:59:33 +0000119# endif
sewardj35165532005-04-30 18:47:48 +0000120
sewardj75ea7982005-11-14 15:18:25 +0000121 /* fp is %ebp. sp is %esp. ip is %eip. */
122
sewardj9365e3f2010-01-01 19:55:17 +0000123 if (sps) sps[0] = uregs.xsp;
124 if (fps) fps[0] = uregs.xbp;
125 ips[0] = uregs.xip;
sewardj75ea7982005-11-14 15:18:25 +0000126 i = 1;
127
128 /* Loop unwinding the stack. Note that the IP value we get on
129 * each pass (whether from CFI info or a stack frame) is a
130 * return address so is actually after the calling instruction
131 * in the calling function.
132 *
133 * Because of this we subtract one from the IP after each pass
134 * of the loop so that we find the right CFI block on the next
135 * pass - otherwise we can find the wrong CFI info if it happens
136 * to change after the calling instruction and that will mean
137 * that we will fail to unwind the next step.
138 *
139 * This most frequently happens at the end of a function when
140 * a tail call occurs and we wind up using the CFI info for the
141 * next function which is completely wrong.
142 */
143 while (True) {
144
njn3a4b58f2009-05-07 23:08:10 +0000145 if (i >= max_n_ips)
sewardj75ea7982005-11-14 15:18:25 +0000146 break;
147
148 /* Try to derive a new (ip,sp,fp) triple from the current
149 set. */
150
151 /* On x86, first try the old-fashioned method of following the
152 %ebp-chain. Code which doesn't use this (that is, compiled
153 with -fomit-frame-pointer) is not ABI compliant and so
154 relatively rare. Besides, trying the CFI first almost always
155 fails, and is expensive. */
156 /* Deal with frames resulting from functions which begin "pushl%
157 ebp ; movl %esp, %ebp" which is the ABI-mandated preamble. */
sewardj9365e3f2010-01-01 19:55:17 +0000158 if (fp_min <= uregs.xbp &&
159 uregs.xbp <= fp_max - 1 * sizeof(UWord)/*see comment below*/)
njn3a4b58f2009-05-07 23:08:10 +0000160 {
sewardj75ea7982005-11-14 15:18:25 +0000161 /* fp looks sane, so use it. */
sewardj9365e3f2010-01-01 19:55:17 +0000162 uregs.xip = (((UWord*)uregs.xbp)[1]);
njn3a4b58f2009-05-07 23:08:10 +0000163 // We stop if we hit a zero (the traditional end-of-stack
164 // marker) or a one -- these correspond to recorded IPs of 0 or -1.
165 // The latter because r8818 (in this file) changes the meaning of
166 // entries [1] and above in a stack trace, by subtracting 1 from
167 // them. Hence stacks that used to end with a zero value now end in
168 // -1 and so we must detect that too.
sewardj9365e3f2010-01-01 19:55:17 +0000169 if (0 == uregs.xip || 1 == uregs.xip) break;
170 uregs.xsp = uregs.xbp + sizeof(Addr) /*saved %ebp*/
171 + sizeof(Addr) /*ra*/;
172 uregs.xbp = (((UWord*)uregs.xbp)[0]);
173 if (sps) sps[i] = uregs.xsp;
174 if (fps) fps[i] = uregs.xbp;
175 ips[i++] = uregs.xip - 1; /* -1: refer to calling insn, not the RA */
sewardj75ea7982005-11-14 15:18:25 +0000176 if (debug)
dirke4067232007-10-04 21:36:40 +0000177 VG_(printf)(" ipsF[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000178 uregs.xip = uregs.xip - 1;
179 /* as per comment at the head of this loop */
sewardj75ea7982005-11-14 15:18:25 +0000180 continue;
181 }
182
sewardj15338c52006-10-17 01:31:58 +0000183 /* That didn't work out, so see if there is any CF info to hand
sewardj75ea7982005-11-14 15:18:25 +0000184 which can be used. */
sewardj9365e3f2010-01-01 19:55:17 +0000185 if ( VG_(use_CF_info)( &uregs, fp_min, fp_max ) ) {
186 if (0 == uregs.xip || 1 == uregs.xip) break;
187 if (sps) sps[i] = uregs.xsp;
188 if (fps) fps[i] = uregs.xbp;
189 ips[i++] = uregs.xip - 1; /* -1: refer to calling insn, not the RA */
sewardj75ea7982005-11-14 15:18:25 +0000190 if (debug)
dirke4067232007-10-04 21:36:40 +0000191 VG_(printf)(" ipsC[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000192 uregs.xip = uregs.xip - 1;
193 /* as per comment at the head of this loop */
sewardj75ea7982005-11-14 15:18:25 +0000194 continue;
195 }
196
sewardjc8259b82009-04-22 22:42:10 +0000197 /* And, similarly, try for MSVC FPO unwind info. */
sewardj9365e3f2010-01-01 19:55:17 +0000198 if ( VG_(use_FPO_info)( &uregs.xip, &uregs.xsp, &uregs.xbp,
199 fp_min, fp_max ) ) {
200 if (0 == uregs.xip || 1 == uregs.xip) break;
201 if (sps) sps[i] = uregs.xsp;
202 if (fps) fps[i] = uregs.xbp;
203 ips[i++] = uregs.xip;
sewardjc8259b82009-04-22 22:42:10 +0000204 if (debug)
205 VG_(printf)(" ipsC[%d]=0x%08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000206 uregs.xip = uregs.xip - 1;
sewardjc8259b82009-04-22 22:42:10 +0000207 continue;
208 }
209
sewardj75ea7982005-11-14 15:18:25 +0000210 /* No luck. We have to give up. */
211 break;
212 }
213
sewardj59570ff2010-01-01 11:59:33 +0000214 n_found = i;
215 return n_found;
216}
sewardj75ea7982005-11-14 15:18:25 +0000217
sewardj59570ff2010-01-01 11:59:33 +0000218#endif
219
220/* ----------------------- amd64 ------------------------ */
221
222#if defined(VGP_amd64_linux) || defined(VGP_amd64_darwin)
223
224UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
225 /*OUT*/Addr* ips, UInt max_n_ips,
226 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
227 UnwindStartRegs* startRegs,
228 Addr fp_max_orig )
229{
230 Bool debug = False;
231 Int i;
232 Addr fp_max;
233 UInt n_found = 0;
234
235 vg_assert(sizeof(Addr) == sizeof(UWord));
236 vg_assert(sizeof(Addr) == sizeof(void*));
237
sewardj9365e3f2010-01-01 19:55:17 +0000238 D3UnwindRegs uregs;
239 uregs.xip = startRegs->r_pc;
240 uregs.xsp = startRegs->r_sp;
241 uregs.xbp = startRegs->misc.AMD64.r_rbp;
242 Addr fp_min = uregs.xsp;
sewardj59570ff2010-01-01 11:59:33 +0000243
244 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
245 stopping when the trail goes cold, which we guess to be
246 when FP is not a reasonable stack location. */
247
248 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
249 // current page, at least. Dunno if it helps.
250 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
251 fp_max = VG_PGROUNDUP(fp_max_orig);
252 if (fp_max >= sizeof(Addr))
253 fp_max -= sizeof(Addr);
254
255 if (debug)
256 VG_(printf)("max_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
257 "fp_max=0x%lx ip=0x%lx fp=0x%lx\n",
sewardj9365e3f2010-01-01 19:55:17 +0000258 max_n_ips, fp_min, fp_max_orig, fp_max,
259 uregs.xip, uregs.xbp);
sewardj59570ff2010-01-01 11:59:33 +0000260
261 /* Assertion broken before main() is reached in pthreaded programs; the
262 * offending stack traces only have one item. --njn, 2002-aug-16 */
263 /* vg_assert(fp_min <= fp_max);*/
264 // On Darwin, this kicks in for pthread-related stack traces, so they're
265 // only 1 entry long which is wrong.
266# if !defined(VGO_darwin)
sewardjf2522992010-10-06 22:45:18 +0000267 if (fp_min + 256 >= fp_max) {
sewardj59570ff2010-01-01 11:59:33 +0000268 /* If the stack limits look bogus, don't poke around ... but
269 don't bomb out either. */
sewardj9365e3f2010-01-01 19:55:17 +0000270 if (sps) sps[0] = uregs.xsp;
271 if (fps) fps[0] = uregs.xbp;
272 ips[0] = uregs.xip;
sewardj59570ff2010-01-01 11:59:33 +0000273 return 1;
274 }
275# endif
sewardj75ea7982005-11-14 15:18:25 +0000276
277 /* fp is %rbp. sp is %rsp. ip is %rip. */
sewardj35165532005-04-30 18:47:48 +0000278
sewardj9365e3f2010-01-01 19:55:17 +0000279 ips[0] = uregs.xip;
280 if (sps) sps[0] = uregs.xsp;
281 if (fps) fps[0] = uregs.xbp;
sewardjacaec5f2005-08-19 16:02:59 +0000282 i = 1;
sewardj35165532005-04-30 18:47:48 +0000283
tomac35f102005-11-05 00:17:21 +0000284 /* Loop unwinding the stack. Note that the IP value we get on
285 * each pass (whether from CFI info or a stack frame) is a
286 * return address so is actually after the calling instruction
287 * in the calling function.
288 *
289 * Because of this we subtract one from the IP after each pass
290 * of the loop so that we find the right CFI block on the next
291 * pass - otherwise we can find the wrong CFI info if it happens
292 * to change after the calling instruction and that will mean
293 * that we will fail to unwind the next step.
294 *
295 * This most frequently happens at the end of a function when
296 * a tail call occurs and we wind up using the CFI info for the
297 * next function which is completely wrong.
298 */
sewardjacaec5f2005-08-19 16:02:59 +0000299 while (True) {
sewardj35165532005-04-30 18:47:48 +0000300
njn3a4b58f2009-05-07 23:08:10 +0000301 if (i >= max_n_ips)
sewardj35165532005-04-30 18:47:48 +0000302 break;
sewardjacaec5f2005-08-19 16:02:59 +0000303
njn3a4b58f2009-05-07 23:08:10 +0000304 /* Try to derive a new (ip,sp,fp) triple from the current set. */
sewardjacaec5f2005-08-19 16:02:59 +0000305
306 /* First off, see if there is any CFI info to hand which can
307 be used. */
sewardj9365e3f2010-01-01 19:55:17 +0000308 if ( VG_(use_CF_info)( &uregs, fp_min, fp_max ) ) {
309 if (0 == uregs.xip || 1 == uregs.xip) break;
310 if (sps) sps[i] = uregs.xsp;
311 if (fps) fps[i] = uregs.xbp;
312 ips[i++] = uregs.xip - 1; /* -1: refer to calling insn, not the RA */
sewardjacaec5f2005-08-19 16:02:59 +0000313 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000314 VG_(printf)(" ipsC[%d]=%#08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000315 uregs.xip = uregs.xip - 1; /* as per comment at the head of this loop */
sewardjacaec5f2005-08-19 16:02:59 +0000316 continue;
njnd01fef72005-03-25 23:35:48 +0000317 }
sewardj35165532005-04-30 18:47:48 +0000318
sewardjeadcd862006-04-04 15:12:44 +0000319 /* If VG_(use_CF_info) fails, it won't modify ip/sp/fp, so
sewardjacaec5f2005-08-19 16:02:59 +0000320 we can safely try the old-fashioned method. */
321 /* This bit is supposed to deal with frames resulting from
sewardj75ea7982005-11-14 15:18:25 +0000322 functions which begin "pushq %rbp ; movq %rsp, %rbp".
323 Unfortunately, since we can't (easily) look at the insns at
324 the start of the fn, like GDB does, there's no reliable way
325 to tell. Hence the hack of first trying out CFI, and if that
326 fails, then use this as a fallback. */
sewardjf98e1c02008-10-25 16:22:41 +0000327 /* Note: re "- 1 * sizeof(UWord)", need to take account of the
328 fact that we are prodding at & ((UWord*)fp)[1] and so need to
329 adjust the limit check accordingly. Omitting this has been
330 observed to cause segfaults on rare occasions. */
sewardj9365e3f2010-01-01 19:55:17 +0000331 if (fp_min <= uregs.xbp && uregs.xbp <= fp_max - 1 * sizeof(UWord)) {
sewardjacaec5f2005-08-19 16:02:59 +0000332 /* fp looks sane, so use it. */
sewardj9365e3f2010-01-01 19:55:17 +0000333 uregs.xip = (((UWord*)uregs.xbp)[1]);
334 if (0 == uregs.xip || 1 == uregs.xip) break;
335 uregs.xsp = uregs.xbp + sizeof(Addr) /*saved %rbp*/
336 + sizeof(Addr) /*ra*/;
337 uregs.xbp = (((UWord*)uregs.xbp)[0]);
338 if (sps) sps[i] = uregs.xsp;
339 if (fps) fps[i] = uregs.xbp;
340 ips[i++] = uregs.xip - 1; /* -1: refer to calling insn, not the RA */
sewardjacaec5f2005-08-19 16:02:59 +0000341 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000342 VG_(printf)(" ipsF[%d]=%#08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000343 uregs.xip = uregs.xip - 1; /* as per comment at the head of this loop */
sewardjacaec5f2005-08-19 16:02:59 +0000344 continue;
345 }
346
sewardj39f34232007-11-09 23:02:28 +0000347 /* Last-ditch hack (evidently GDB does something similar). We
348 are in the middle of nowhere and we have a nonsense value for
349 the frame pointer. If the stack pointer is still valid,
350 assume that what it points at is a return address. Yes,
351 desperate measures. Could do better here:
352 - check that the supposed return address is in
353 an executable page
354 - check that the supposed return address is just after a call insn
355 - given those two checks, don't just consider *sp as the return
356 address; instead scan a likely section of stack (eg sp .. sp+256)
357 and use suitable values found there.
358 */
sewardj9365e3f2010-01-01 19:55:17 +0000359 if (fp_min <= uregs.xsp && uregs.xsp < fp_max) {
360 uregs.xip = ((UWord*)uregs.xsp)[0];
361 if (0 == uregs.xip || 1 == uregs.xip) break;
362 if (sps) sps[i] = uregs.xsp;
363 if (fps) fps[i] = uregs.xbp;
364 ips[i++] = uregs.xip == 0
sewardjb1ae15d2008-12-12 13:23:03 +0000365 ? 0 /* sp[0] == 0 ==> stuck at the bottom of a
366 thread stack */
sewardj9365e3f2010-01-01 19:55:17 +0000367 : uregs.xip - 1;
368 /* -1: refer to calling insn, not the RA */
sewardj39f34232007-11-09 23:02:28 +0000369 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000370 VG_(printf)(" ipsH[%d]=%#08lx\n", i-1, ips[i-1]);
sewardj9365e3f2010-01-01 19:55:17 +0000371 uregs.xip = uregs.xip - 1; /* as per comment at the head of this loop */
372 uregs.xsp += 8;
sewardj39f34232007-11-09 23:02:28 +0000373 continue;
374 }
375
376 /* No luck at all. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000377 break;
njnd01fef72005-03-25 23:35:48 +0000378 }
sewardjacaec5f2005-08-19 16:02:59 +0000379
sewardj59570ff2010-01-01 11:59:33 +0000380 n_found = i;
381 return n_found;
382}
sewardjacaec5f2005-08-19 16:02:59 +0000383
sewardj59570ff2010-01-01 11:59:33 +0000384#endif
385
386/* -----------------------ppc32/64 ---------------------- */
387
388#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
389 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
390
391UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
392 /*OUT*/Addr* ips, UInt max_n_ips,
393 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
sewardjf5f1e122010-01-02 13:24:58 +0000394 UnwindStartRegs* startRegs,
395 Addr fp_max_orig )
sewardj59570ff2010-01-01 11:59:33 +0000396{
397 Bool lr_is_first_RA = False;
398# if defined(VG_PLAT_USES_PPCTOC)
399 Word redir_stack_size = 0;
400 Word redirs_used = 0;
401# endif
402
403 Bool debug = False;
404 Int i;
405 Addr fp_max;
406 UInt n_found = 0;
407
408 vg_assert(sizeof(Addr) == sizeof(UWord));
409 vg_assert(sizeof(Addr) == sizeof(void*));
410
sewardjf5f1e122010-01-02 13:24:58 +0000411 Addr ip = (Addr)startRegs->r_pc;
412 Addr sp = (Addr)startRegs->r_sp;
413 Addr fp = sp;
414# if defined(VGP_ppc32_linux) || defined(VGP_ppc32_aix5)
415 Addr lr = startRegs->misc.PPC32.r_lr;
416# elif defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
417 Addr lr = startRegs->misc.PPC64.r_lr;
418# endif
419 Addr fp_min = sp;
420
sewardj59570ff2010-01-01 11:59:33 +0000421 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
422 stopping when the trail goes cold, which we guess to be
423 when FP is not a reasonable stack location. */
424
425 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
426 // current page, at least. Dunno if it helps.
427 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
428 fp_max = VG_PGROUNDUP(fp_max_orig);
429 if (fp_max >= sizeof(Addr))
430 fp_max -= sizeof(Addr);
431
432 if (debug)
433 VG_(printf)("max_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
434 "fp_max=0x%lx ip=0x%lx fp=0x%lx\n",
435 max_n_ips, fp_min, fp_max_orig, fp_max, ip, fp);
436
437 /* Assertion broken before main() is reached in pthreaded programs; the
438 * offending stack traces only have one item. --njn, 2002-aug-16 */
439 /* vg_assert(fp_min <= fp_max);*/
440 if (fp_min + 512 >= fp_max) {
441 /* If the stack limits look bogus, don't poke around ... but
442 don't bomb out either. */
443 if (sps) sps[0] = sp;
444 if (fps) fps[0] = fp;
445 ips[0] = ip;
446 return 1;
447 }
sewardj75ea7982005-11-14 15:18:25 +0000448
sewardjacaec5f2005-08-19 16:02:59 +0000449 /* fp is %r1. ip is %cia. Note, ppc uses r1 as both the stack and
450 frame pointers. */
451
sewardj15338c52006-10-17 01:31:58 +0000452# if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
453 redir_stack_size = VEX_GUEST_PPC64_REDIR_STACK_SIZE;
454 redirs_used = 0;
455# elif defined(VGP_ppc32_aix5)
456 redir_stack_size = VEX_GUEST_PPC32_REDIR_STACK_SIZE;
457 redirs_used = 0;
458# endif
459
460# if defined(VG_PLAT_USES_PPCTOC)
sewardjcfb5e2b2006-01-19 03:47:30 +0000461 /* Deal with bogus LR values caused by function
sewardj15338c52006-10-17 01:31:58 +0000462 interception/wrapping on ppc-TOC platforms; see comment on
463 similar code a few lines further down. */
464 if (ULong_to_Ptr(lr) == (void*)&VG_(ppctoc_magic_redirect_return_stub)
sewardjcfb5e2b2006-01-19 03:47:30 +0000465 && VG_(is_valid_tid)(tid_if_known)) {
sewardj15338c52006-10-17 01:31:58 +0000466 Word hsp = VG_(threads)[tid_if_known].arch.vex.guest_REDIR_SP;
467 redirs_used++;
468 if (hsp >= 1 && hsp < redir_stack_size)
sewardjcfb5e2b2006-01-19 03:47:30 +0000469 lr = VG_(threads)[tid_if_known]
470 .arch.vex.guest_REDIR_STACK[hsp-1];
471 }
472# endif
473
sewardj15338c52006-10-17 01:31:58 +0000474 /* We have to determine whether or not LR currently holds this fn
475 (call it F)'s return address. It might not if F has previously
476 called some other function, hence overwriting LR with a pointer
477 to some part of F. Hence if LR and IP point to the same
478 function then we conclude LR does not hold this function's
479 return address; instead the LR at entry must have been saved in
480 the stack by F's prologue and so we must get it from there
481 instead. Note all this guff only applies to the innermost
482 frame. */
sewardjacaec5f2005-08-19 16:02:59 +0000483 lr_is_first_RA = False;
484 {
485# define M_VG_ERRTXT 1000
486 UChar buf_lr[M_VG_ERRTXT], buf_ip[M_VG_ERRTXT];
sewardjb1ae15d2008-12-12 13:23:03 +0000487 /* The following conditional looks grossly inefficient and
488 surely could be majorly improved, with not much effort. */
njn6b7611b2009-02-11 06:06:10 +0000489 if (VG_(get_fnname_raw) (lr, buf_lr, M_VG_ERRTXT))
490 if (VG_(get_fnname_raw) (ip, buf_ip, M_VG_ERRTXT))
sewardjacaec5f2005-08-19 16:02:59 +0000491 if (VG_(strncmp)(buf_lr, buf_ip, M_VG_ERRTXT))
492 lr_is_first_RA = True;
493# undef M_VG_ERRTXT
494 }
495
sewardjb8b79ad2008-03-03 01:35:41 +0000496 if (sps) sps[0] = fp; /* NB. not sp */
497 if (fps) fps[0] = fp;
sewardjacaec5f2005-08-19 16:02:59 +0000498 ips[0] = ip;
499 i = 1;
sewardjacaec5f2005-08-19 16:02:59 +0000500
sewardjdb2ac812005-12-23 23:33:51 +0000501 if (fp_min <= fp && fp < fp_max-VG_WORDSIZE+1) {
sewardjacaec5f2005-08-19 16:02:59 +0000502
sewardj525e2322005-11-13 02:41:35 +0000503 /* initial FP is sane; keep going */
504 fp = (((UWord*)fp)[0]);
505
506 while (True) {
507
sewardj15338c52006-10-17 01:31:58 +0000508 /* On ppc64-linux (ppc64-elf, really), and on AIX, the lr save
509 slot is 2 words back from sp, whereas on ppc32-elf(?) it's
510 only one word back. */
sewardj59570ff2010-01-01 11:59:33 +0000511# if defined(VG_PLAT_USES_PPCTOC)
sewardjdfbaa222006-01-18 04:25:20 +0000512 const Int lr_offset = 2;
513# else
514 const Int lr_offset = 1;
515# endif
sewardjdb2ac812005-12-23 23:33:51 +0000516
njn3a4b58f2009-05-07 23:08:10 +0000517 if (i >= max_n_ips)
sewardj525e2322005-11-13 02:41:35 +0000518 break;
519
520 /* Try to derive a new (ip,fp) pair from the current set. */
521
sewardjf98e1c02008-10-25 16:22:41 +0000522 if (fp_min <= fp && fp <= fp_max - lr_offset * sizeof(UWord)) {
sewardj525e2322005-11-13 02:41:35 +0000523 /* fp looks sane, so use it. */
524
525 if (i == 1 && lr_is_first_RA)
526 ip = lr;
527 else
sewardjdb2ac812005-12-23 23:33:51 +0000528 ip = (((UWord*)fp)[lr_offset]);
sewardj525e2322005-11-13 02:41:35 +0000529
sewardj15338c52006-10-17 01:31:58 +0000530# if defined(VG_PLAT_USES_PPCTOC)
sewardjdfbaa222006-01-18 04:25:20 +0000531 /* Nasty hack to do with function replacement/wrapping on
sewardj15338c52006-10-17 01:31:58 +0000532 ppc64-linux/ppc64-aix/ppc32-aix. If LR points to our
533 magic return stub, then we are in a wrapped or
534 intercepted function, in which LR has been messed with.
535 The original LR will have been pushed onto the thread's
536 hidden REDIR stack one down from the top (top element
537 is the saved R2) and so we should restore the value
538 from there instead. Since nested redirections can and
539 do happen, we keep track of the number of nested LRs
540 used by the unwinding so far with 'redirs_used'. */
541 if (ip == (Addr)&VG_(ppctoc_magic_redirect_return_stub)
sewardjdfbaa222006-01-18 04:25:20 +0000542 && VG_(is_valid_tid)(tid_if_known)) {
sewardjb8b79ad2008-03-03 01:35:41 +0000543 Word hsp = VG_(threads)[tid_if_known]
544 .arch.vex.guest_REDIR_SP;
sewardj15338c52006-10-17 01:31:58 +0000545 hsp -= 2 * redirs_used;
546 redirs_used ++;
547 if (hsp >= 1 && hsp < redir_stack_size)
sewardjdfbaa222006-01-18 04:25:20 +0000548 ip = VG_(threads)[tid_if_known]
549 .arch.vex.guest_REDIR_STACK[hsp-1];
550 }
551# endif
552
njn3a4b58f2009-05-07 23:08:10 +0000553 if (0 == ip || 1 == ip) break;
sewardjb8b79ad2008-03-03 01:35:41 +0000554 if (sps) sps[i] = fp; /* NB. not sp */
555 if (fps) fps[i] = fp;
tom88053262009-11-12 13:19:41 +0000556 fp = (((UWord*)fp)[0]);
sewardjb1ae15d2008-12-12 13:23:03 +0000557 ips[i++] = ip - 1; /* -1: refer to calling insn, not the RA */
sewardj525e2322005-11-13 02:41:35 +0000558 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000559 VG_(printf)(" ipsF[%d]=%#08lx\n", i-1, ips[i-1]);
sewardjb1ae15d2008-12-12 13:23:03 +0000560 ip = ip - 1; /* ip is probably dead at this point, but
561 play safe, a la x86/amd64 above. See
562 extensive comments above. */
sewardj525e2322005-11-13 02:41:35 +0000563 continue;
564 }
565
566 /* No luck there. We have to give up. */
sewardjacaec5f2005-08-19 16:02:59 +0000567 break;
sewardjacaec5f2005-08-19 16:02:59 +0000568 }
sewardjacaec5f2005-08-19 16:02:59 +0000569 }
570
sewardj59570ff2010-01-01 11:59:33 +0000571 n_found = i;
572 return n_found;
573}
574
575#endif
576
577/* ------------------------ arm ------------------------- */
578
579#if defined(VGP_arm_linux)
580
581UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
582 /*OUT*/Addr* ips, UInt max_n_ips,
583 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
584 UnwindStartRegs* startRegs,
585 Addr fp_max_orig )
586{
587 Bool debug = False;
588 Int i;
589 Addr fp_max;
590 UInt n_found = 0;
591
592 vg_assert(sizeof(Addr) == sizeof(UWord));
593 vg_assert(sizeof(Addr) == sizeof(void*));
594
sewardj3026f712010-01-01 18:46:41 +0000595 D3UnwindRegs uregs;
sewardjfa5ce562010-09-23 22:05:59 +0000596 uregs.r15 = startRegs->r_pc & 0xFFFFFFFE;
sewardj3026f712010-01-01 18:46:41 +0000597 uregs.r14 = startRegs->misc.ARM.r14;
598 uregs.r13 = startRegs->r_sp;
599 uregs.r12 = startRegs->misc.ARM.r12;
600 uregs.r11 = startRegs->misc.ARM.r11;
sewardjfa5ce562010-09-23 22:05:59 +0000601 uregs.r7 = startRegs->misc.ARM.r7;
sewardj3026f712010-01-01 18:46:41 +0000602 Addr fp_min = uregs.r13;
sewardj59570ff2010-01-01 11:59:33 +0000603
604 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
605 stopping when the trail goes cold, which we guess to be
606 when FP is not a reasonable stack location. */
607
608 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
609 // current page, at least. Dunno if it helps.
610 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
611 fp_max = VG_PGROUNDUP(fp_max_orig);
612 if (fp_max >= sizeof(Addr))
613 fp_max -= sizeof(Addr);
614
615 if (debug)
sewardjfa5ce562010-09-23 22:05:59 +0000616 VG_(printf)("\nmax_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
sewardj59570ff2010-01-01 11:59:33 +0000617 "fp_max=0x%lx r15=0x%lx r13=0x%lx\n",
sewardj3026f712010-01-01 18:46:41 +0000618 max_n_ips, fp_min, fp_max_orig, fp_max,
619 uregs.r15, uregs.r13);
sewardj59570ff2010-01-01 11:59:33 +0000620
621 /* Assertion broken before main() is reached in pthreaded programs; the
622 * offending stack traces only have one item. --njn, 2002-aug-16 */
623 /* vg_assert(fp_min <= fp_max);*/
624 // On Darwin, this kicks in for pthread-related stack traces, so they're
625 // only 1 entry long which is wrong.
626 if (fp_min + 512 >= fp_max) {
627 /* If the stack limits look bogus, don't poke around ... but
628 don't bomb out either. */
sewardj3026f712010-01-01 18:46:41 +0000629 if (sps) sps[0] = uregs.r13;
sewardj59570ff2010-01-01 11:59:33 +0000630 if (fps) fps[0] = 0;
sewardj3026f712010-01-01 18:46:41 +0000631 ips[0] = uregs.r15;
sewardj59570ff2010-01-01 11:59:33 +0000632 return 1;
633 }
634
635 /* */
636
sewardj3026f712010-01-01 18:46:41 +0000637 if (sps) sps[0] = uregs.r13;
sewardj59570ff2010-01-01 11:59:33 +0000638 if (fps) fps[0] = 0;
sewardj3026f712010-01-01 18:46:41 +0000639 ips[0] = uregs.r15;
sewardj59570ff2010-01-01 11:59:33 +0000640 i = 1;
641
642 /* Loop unwinding the stack. */
643
644 while (True) {
645 if (debug) {
sewardj3026f712010-01-01 18:46:41 +0000646 VG_(printf)("i: %d, r15: 0x%lx, r13: 0x%lx\n",
647 i, uregs.r15, uregs.r13);
sewardj59570ff2010-01-01 11:59:33 +0000648 }
649
650 if (i >= max_n_ips)
651 break;
652
sewardj3026f712010-01-01 18:46:41 +0000653 if (VG_(use_CF_info)( &uregs, fp_min, fp_max )) {
654 if (sps) sps[i] = uregs.r13;
sewardj59570ff2010-01-01 11:59:33 +0000655 if (fps) fps[i] = 0;
sewardjfa5ce562010-09-23 22:05:59 +0000656 ips[i++] = (uregs.r15 & 0xFFFFFFFE) - 1;
sewardj59570ff2010-01-01 11:59:33 +0000657 if (debug)
sewardj3026f712010-01-01 18:46:41 +0000658 VG_(printf)("USING CFI: r15: 0x%lx, r13: 0x%lx\n",
659 uregs.r15, uregs.r13);
sewardjfa5ce562010-09-23 22:05:59 +0000660 uregs.r15 = (uregs.r15 & 0xFFFFFFFE) - 1;
sewardj59570ff2010-01-01 11:59:33 +0000661 continue;
662 }
663 /* No luck. We have to give up. */
664 break;
665 }
sewardjacaec5f2005-08-19 16:02:59 +0000666
njnd01fef72005-03-25 23:35:48 +0000667 n_found = i;
njnd01fef72005-03-25 23:35:48 +0000668 return n_found;
669}
670
sewardj59570ff2010-01-01 11:59:33 +0000671#endif
672
673/*------------------------------------------------------------*/
674/*--- ---*/
675/*--- END platform-dependent unwinder worker functions ---*/
676/*--- ---*/
677/*------------------------------------------------------------*/
678
679/*------------------------------------------------------------*/
680/*--- Exported functions. ---*/
681/*------------------------------------------------------------*/
682
sewardjb8b79ad2008-03-03 01:35:41 +0000683UInt VG_(get_StackTrace) ( ThreadId tid,
njn3a4b58f2009-05-07 23:08:10 +0000684 /*OUT*/StackTrace ips, UInt max_n_ips,
sewardjb8b79ad2008-03-03 01:35:41 +0000685 /*OUT*/StackTrace sps,
686 /*OUT*/StackTrace fps,
sewardj39f34232007-11-09 23:02:28 +0000687 Word first_ip_delta )
njnd01fef72005-03-25 23:35:48 +0000688{
sewardj59570ff2010-01-01 11:59:33 +0000689 /* Get the register values with which to start the unwind. */
690 UnwindStartRegs startRegs;
691 VG_(memset)( &startRegs, 0, sizeof(startRegs) );
692 VG_(get_UnwindStartRegs)( &startRegs, tid );
693
njnf536bbb2005-06-13 04:21:38 +0000694 Addr stack_highest_word = VG_(threads)[tid].client_stack_highest_word;
tom690c3c82008-02-08 15:17:07 +0000695 Addr stack_lowest_word = 0;
njnd01fef72005-03-25 23:35:48 +0000696
sewardjb9bce632005-06-21 01:41:34 +0000697# if defined(VGP_x86_linux)
sewardja672ea32006-04-29 18:03:14 +0000698 /* Nasty little hack to deal with syscalls - if libc is using its
699 _dl_sysinfo_int80 function for syscalls (the TLS version does),
700 then ip will always appear to be in that function when doing a
701 syscall, not the actual libc function doing the syscall. This
702 check sees if IP is within that function, and pops the return
703 address off the stack so that ip is placed within the library
704 function calling the syscall. This makes stack backtraces much
705 more useful.
706
707 The function is assumed to look like this (from glibc-2.3.6 sources):
708 _dl_sysinfo_int80:
709 int $0x80
710 ret
711 That is 3 (2+1) bytes long. We could be more thorough and check
712 the 3 bytes of the function are as expected, but I can't be
713 bothered.
714 */
715 if (VG_(client__dl_sysinfo_int80) != 0 /* we know its address */
sewardj59570ff2010-01-01 11:59:33 +0000716 && startRegs.r_pc >= VG_(client__dl_sysinfo_int80)
717 && startRegs.r_pc < VG_(client__dl_sysinfo_int80)+3
718 && VG_(am_is_valid_for_client)(startRegs.r_pc, sizeof(Addr),
719 VKI_PROT_READ)) {
720 startRegs.r_pc = (ULong) *(Addr*)(UWord)startRegs.r_sp;
721 startRegs.r_sp += (ULong) sizeof(Addr);
njnd01fef72005-03-25 23:35:48 +0000722 }
sewardjb9bce632005-06-21 01:41:34 +0000723# endif
724
tom690c3c82008-02-08 15:17:07 +0000725 /* See if we can get a better idea of the stack limits */
sewardj59570ff2010-01-01 11:59:33 +0000726 VG_(stack_limits)( (Addr)startRegs.r_sp,
727 &stack_lowest_word, &stack_highest_word );
tom690c3c82008-02-08 15:17:07 +0000728
sewardj39f34232007-11-09 23:02:28 +0000729 /* Take into account the first_ip_delta. */
sewardj59570ff2010-01-01 11:59:33 +0000730 startRegs.r_pc += (Long)(Word)first_ip_delta;
sewardj39f34232007-11-09 23:02:28 +0000731
njnd01fef72005-03-25 23:35:48 +0000732 if (0)
sewardj59570ff2010-01-01 11:59:33 +0000733 VG_(printf)("tid %d: stack_highest=0x%08lx ip=0x%010llx "
734 "sp=0x%010llx\n",
735 tid, stack_highest_word,
736 startRegs.r_pc, startRegs.r_sp);
njnd01fef72005-03-25 23:35:48 +0000737
njn3a4b58f2009-05-07 23:08:10 +0000738 return VG_(get_StackTrace_wrk)(tid, ips, max_n_ips,
sewardjb8b79ad2008-03-03 01:35:41 +0000739 sps, fps,
sewardj59570ff2010-01-01 11:59:33 +0000740 &startRegs,
sewardjb8b79ad2008-03-03 01:35:41 +0000741 stack_highest_word);
njnd01fef72005-03-25 23:35:48 +0000742}
743
sewardj588adef2009-08-15 22:41:51 +0000744static void printIpDesc(UInt n, Addr ip, void* uu_opaque)
njnd01fef72005-03-25 23:35:48 +0000745{
njn83f9e792005-06-11 05:04:09 +0000746 #define BUF_LEN 4096
747
748 static UChar buf[BUF_LEN];
njnd01fef72005-03-25 23:35:48 +0000749
njn83f9e792005-06-11 05:04:09 +0000750 VG_(describe_IP)(ip, buf, BUF_LEN);
sewardj71bc3cb2005-05-19 00:25:45 +0000751
752 if (VG_(clo_xml)) {
sewardj738856f2009-07-15 14:48:32 +0000753 VG_(printf_xml)(" %s\n", buf);
sewardj71bc3cb2005-05-19 00:25:45 +0000754 } else {
sewardj738856f2009-07-15 14:48:32 +0000755 VG_(message)(Vg_UserMsg, " %s %s\n", ( n == 0 ? "at" : "by" ), buf);
sewardj71bc3cb2005-05-19 00:25:45 +0000756 }
njnd01fef72005-03-25 23:35:48 +0000757}
758
759/* Print a StackTrace. */
760void VG_(pp_StackTrace) ( StackTrace ips, UInt n_ips )
761{
762 vg_assert( n_ips > 0 );
sewardj71bc3cb2005-05-19 00:25:45 +0000763
764 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000765 VG_(printf_xml)(" <stack>\n");
sewardj71bc3cb2005-05-19 00:25:45 +0000766
sewardj588adef2009-08-15 22:41:51 +0000767 VG_(apply_StackTrace)( printIpDesc, NULL, ips, n_ips );
sewardj71bc3cb2005-05-19 00:25:45 +0000768
769 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000770 VG_(printf_xml)(" </stack>\n");
njnd01fef72005-03-25 23:35:48 +0000771}
772
773/* Get and immediately print a StackTrace. */
njn3a4b58f2009-05-07 23:08:10 +0000774void VG_(get_and_pp_StackTrace) ( ThreadId tid, UInt max_n_ips )
njnd01fef72005-03-25 23:35:48 +0000775{
njn3a4b58f2009-05-07 23:08:10 +0000776 Addr ips[max_n_ips];
777 UInt n_ips
778 = VG_(get_StackTrace)(tid, ips, max_n_ips,
sewardjb8b79ad2008-03-03 01:35:41 +0000779 NULL/*array to dump SP values in*/,
780 NULL/*array to dump FP values in*/,
781 0/*first_ip_delta*/);
njn3a4b58f2009-05-07 23:08:10 +0000782 VG_(pp_StackTrace)(ips, n_ips);
njnd01fef72005-03-25 23:35:48 +0000783}
784
sewardj588adef2009-08-15 22:41:51 +0000785void VG_(apply_StackTrace)(
786 void(*action)(UInt n, Addr ip, void* opaque),
787 void* opaque,
788 StackTrace ips, UInt n_ips
789 )
njnd01fef72005-03-25 23:35:48 +0000790{
njnd01fef72005-03-25 23:35:48 +0000791 Bool main_done = False;
njnd01fef72005-03-25 23:35:48 +0000792 Int i = 0;
793
794 vg_assert(n_ips > 0);
795 do {
796 Addr ip = ips[i];
njnd01fef72005-03-25 23:35:48 +0000797
sewardj73cf4c62005-11-17 15:12:34 +0000798 // Stop after the first appearance of "main" or one of the other names
799 // (the appearance of which is a pretty good sign that we've gone past
800 // main without seeing it, for whatever reason)
njn68824432009-02-10 06:48:00 +0000801 if ( ! VG_(clo_show_below_main) ) {
802 Vg_FnNameKind kind = VG_(get_fnname_kind_from_IP)(ip);
803 if (Vg_FnNameMain == kind || Vg_FnNameBelowMain == kind) {
njnd01fef72005-03-25 23:35:48 +0000804 main_done = True;
njn68824432009-02-10 06:48:00 +0000805 }
njnd01fef72005-03-25 23:35:48 +0000806 }
807
808 // Act on the ip
sewardj588adef2009-08-15 22:41:51 +0000809 action(i, ip, opaque);
njnd01fef72005-03-25 23:35:48 +0000810
811 i++;
njn3a4b58f2009-05-07 23:08:10 +0000812 } while (i < n_ips && !main_done);
njnd01fef72005-03-25 23:35:48 +0000813
814 #undef MYBUF_LEN
815}
816
817
818/*--------------------------------------------------------------------*/
njn24a6efb2005-06-20 03:36:51 +0000819/*--- end ---*/
njnd01fef72005-03-25 23:35:48 +0000820/*--------------------------------------------------------------------*/