m_stacktrace.c revision 75ea798c1eabd31eb50d13f77cf751c378eb8c10
1
2/*--------------------------------------------------------------------*/
3/*--- Take snapshots of client stacks.              m_stacktrace.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2000-2005 Julian Seward
11      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
31#include "pub_core_basics.h"
32#include "pub_core_threadstate.h"
33#include "pub_core_debuginfo.h"
34#include "pub_core_aspacemgr.h"     // For VG_(is_addressable)()
35#include "pub_core_libcbase.h"
36#include "pub_core_libcassert.h"
37#include "pub_core_libcprint.h"
38#include "pub_core_machine.h"
39#include "pub_core_options.h"
40#include "pub_core_profile.h"
41#include "pub_core_stacktrace.h"
42#include "pub_core_trampoline.h"
43
44/*------------------------------------------------------------*/
45/*--- Exported functions.                                  ---*/
46/*------------------------------------------------------------*/
47
48/* Take a snapshot of the client's stack, putting the up to 'n_ips'
49   IPs into 'ips'.  In order to be thread-safe, we pass in the
50   thread's IP SP, FP if that's meaningful, and LR if that's
51   meaningful.  Returns number of IPs put in 'ips'.
52*/
53UInt VG_(get_StackTrace2) ( Addr* ips, UInt n_ips,
54                            Addr ip, Addr sp, Addr fp, Addr lr,
55                            Addr fp_min, Addr fp_max_orig )
56{
57#if defined(VGP_ppc32_linux)
58   Bool  lr_is_first_RA = False; /* ppc only */
59#endif
60   Bool  debug = False;
61   Int   i;
62   Addr  fp_max;
63   UInt  n_found = 0;
64
65   VGP_PUSHCC(VgpExeContext);
66
67   vg_assert(sizeof(Addr) == sizeof(UWord));
68   vg_assert(sizeof(Addr) == sizeof(void*));
69
70   /* Snaffle IPs from the client's stack into ips[0 .. n_ips-1],
71      putting zeroes in when the trail goes cold, which we guess to be
72      when FP is not a reasonable stack location. */
73
74   for (i = 0; i < n_ips; i++)
75      ips[i] = 0;
76
77   // JRS 2002-sep-17: hack, to round up fp_max to the end of the
78   // current page, at least.  Dunno if it helps.
79   // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
80   fp_max = VG_PGROUNDUP(fp_max_orig);
81   fp_max -= sizeof(Addr);
82
83   if (debug)
84      VG_(printf)("n_ips=%d fp_min=%p fp_max_orig=%p, fp_max=%p ip=%p fp=%p\n",
85		  n_ips, fp_min, fp_max_orig, fp_max, ip, fp);
86
87   /* Assertion broken before main() is reached in pthreaded programs;  the
88    * offending stack traces only have one item.  --njn, 2002-aug-16 */
89   /* vg_assert(fp_min <= fp_max);*/
90
91   if (fp_min + VG_(clo_max_stackframe) <= fp_max) {
92      /* If the stack is ridiculously big, don't poke around ... but
93         don't bomb out either.  Needed to make John Regehr's
94         user-space threads package work. JRS 20021001 */
95      ips[0] = ip;
96      VGP_POPCC(VgpExeContext);
97      return 1;
98   }
99
100   /* Otherwise unwind the stack in a platform-specific way.  Trying
101      to merge the x86, amd64 and ppc32 logic into a single piece of
102      code is just too confusing and difficult to performance-tune.  */
103
104#  if defined(VGP_x86_linux)
105
106   /*--------------------- x86 ---------------------*/
107
108   /* fp is %ebp.  sp is %esp.  ip is %eip. */
109
110   ips[0] = ip;
111   i = 1;
112
113   /* Loop unwinding the stack. Note that the IP value we get on
114    * each pass (whether from CFI info or a stack frame) is a
115    * return address so is actually after the calling instruction
116    * in the calling function.
117    *
118    * Because of this we subtract one from the IP after each pass
119    * of the loop so that we find the right CFI block on the next
120    * pass - otherwise we can find the wrong CFI info if it happens
121    * to change after the calling instruction and that will mean
122    * that we will fail to unwind the next step.
123    *
124    * This most frequently happens at the end of a function when
125    * a tail call occurs and we wind up using the CFI info for the
126    * next function which is completely wrong.
127    */
128   while (True) {
129
130      if (i >= n_ips)
131         break;
132
133      /* Try to derive a new (ip,sp,fp) triple from the current
134         set. */
135
136      /* On x86, first try the old-fashioned method of following the
137         %ebp-chain.  Code which doesn't use this (that is, compiled
138         with -fomit-frame-pointer) is not ABI compliant and so
139         relatively rare.  Besides, trying the CFI first almost always
140         fails, and is expensive. */
141      /* Deal with frames resulting from functions which begin "pushl%
142         ebp ; movl %esp, %ebp" which is the ABI-mandated preamble. */
143      if (fp_min <= fp && fp <= fp_max) {
144         /* fp looks sane, so use it. */
145         ip = (((UWord*)fp)[1]);
146         sp = fp + sizeof(Addr) /*saved %ebp*/
147                 + sizeof(Addr) /*ra*/;
148         fp = (((UWord*)fp)[0]);
149         ips[i++] = ip;
150         if (debug)
151            VG_(printf)("     ipsF[%d]=%08p\n", i-1, ips[i-1]);
152         ip = ip - 1;
153         continue;
154      }
155
156      /* That didn't work out, so see if there is any CFI info to hand
157         which can be used. */
158      if ( VG_(use_CFI_info)( &ip, &sp, &fp, fp_min, fp_max ) ) {
159         ips[i++] = ip;
160         if (debug)
161            VG_(printf)("     ipsC[%d]=%08p\n", i-1, ips[i-1]);
162         ip = ip - 1;
163         continue;
164      }
165
166      /* No luck.  We have to give up. */
167      break;
168   }
169
170#  elif defined(VGP_amd64_linux)
171
172   /*--------------------- amd64 ---------------------*/
173
174   /* fp is %rbp.  sp is %rsp.  ip is %rip. */
175
176   ips[0] = ip;
177   i = 1;
178
179   /* Loop unwinding the stack. Note that the IP value we get on
180    * each pass (whether from CFI info or a stack frame) is a
181    * return address so is actually after the calling instruction
182    * in the calling function.
183    *
184    * Because of this we subtract one from the IP after each pass
185    * of the loop so that we find the right CFI block on the next
186    * pass - otherwise we can find the wrong CFI info if it happens
187    * to change after the calling instruction and that will mean
188    * that we will fail to unwind the next step.
189    *
190    * This most frequently happens at the end of a function when
191    * a tail call occurs and we wind up using the CFI info for the
192    * next function which is completely wrong.
193    */
194   while (True) {
195
196      if (i >= n_ips)
197         break;
198
199      /* Try to derive a new (ip,sp,fp) triple from the current
200         set. */
201
202      /* First off, see if there is any CFI info to hand which can
203         be used. */
204      if ( VG_(use_CFI_info)( &ip, &sp, &fp, fp_min, fp_max ) ) {
205         ips[i++] = ip;
206         if (debug)
207            VG_(printf)("     ipsC[%d]=%08p\n", i-1, ips[i-1]);
208         ip = ip - 1;
209         continue;
210      }
211
212      /* If VG_(use_CFI_info) fails, it won't modify ip/sp/fp, so
213         we can safely try the old-fashioned method. */
214      /* This bit is supposed to deal with frames resulting from
215         functions which begin "pushq %rbp ; movq %rsp, %rbp".
216         Unfortunately, since we can't (easily) look at the insns at
217         the start of the fn, like GDB does, there's no reliable way
218         to tell.  Hence the hack of first trying out CFI, and if that
219         fails, then use this as a fallback. */
220      if (fp_min <= fp && fp <= fp_max) {
221         /* fp looks sane, so use it. */
222         ip = (((UWord*)fp)[1]);
223         sp = fp + sizeof(Addr) /*saved %rbp*/
224                 + sizeof(Addr) /*ra*/;
225         fp = (((UWord*)fp)[0]);
226         ips[i++] = ip;
227         if (debug)
228            VG_(printf)("     ipsF[%d]=%08p\n", i-1, ips[i-1]);
229         ip = ip - 1;
230         continue;
231      }
232
233      /* No luck there.  We have to give up. */
234      break;
235   }
236
237#  elif defined(VGP_ppc32_linux)
238
239   /*--------------------- ppc32 ---------------------*/
240
241   /* fp is %r1.  ip is %cia.  Note, ppc uses r1 as both the stack and
242      frame pointers. */
243
244   lr_is_first_RA = False;
245   {
246#     define M_VG_ERRTXT 1000
247      UChar buf_lr[M_VG_ERRTXT], buf_ip[M_VG_ERRTXT];
248      if (VG_(get_fnname_nodemangle) (lr, buf_lr, M_VG_ERRTXT))
249         if (VG_(get_fnname_nodemangle) (ip, buf_ip, M_VG_ERRTXT))
250            if (VG_(strncmp)(buf_lr, buf_ip, M_VG_ERRTXT))
251               lr_is_first_RA = True;
252#     undef M_VG_ERRTXT
253   }
254
255   ips[0] = ip;
256   i = 1;
257
258   if (fp_min <= fp && fp < fp_max-4+1) {
259
260      /* initial FP is sane; keep going */
261      fp = (((UWord*)fp)[0]);
262
263      while (True) {
264
265         if (i >= n_ips)
266            break;
267
268         /* Try to derive a new (ip,fp) pair from the current set. */
269
270         if (fp_min <= fp && fp <= fp_max) {
271            /* fp looks sane, so use it. */
272
273            if (i == 1 && lr_is_first_RA)
274               ip = lr;
275            else
276               ip = (((UWord*)fp)[1]);
277
278            fp = (((UWord*)fp)[0]);
279            ips[i++] = ip;
280            if (debug)
281               VG_(printf)("     ipsF[%d]=%08p\n", i-1, ips[i-1]);
282            continue;
283         }
284
285         /* No luck there.  We have to give up. */
286         break;
287      }
288   }
289
290#  else
291#    error "Unknown platform"
292#  endif
293
294   n_found = i;
295   VGP_POPCC(VgpExeContext);
296   return n_found;
297}
298
299UInt VG_(get_StackTrace) ( ThreadId tid, StackTrace ips, UInt n_ips )
300{
301   /* thread in thread table */
302   Addr ip                 = VG_(get_IP)(tid);
303   Addr fp                 = VG_(get_FP)(tid);
304   Addr sp                 = VG_(get_SP)(tid);
305   Addr lr                 = VG_(get_LR)(tid);
306   Addr stack_highest_word = VG_(threads)[tid].client_stack_highest_word;
307
308#  if defined(VGP_x86_linux)
309   /* Nasty little hack to deal with sysinfo syscalls - if libc is
310      using the sysinfo page for syscalls (the TLS version does), then
311      ip will always appear to be in that page when doing a syscall,
312      not the actual libc function doing the syscall.  This check sees
313      if IP is within the syscall code, and pops the return address
314      off the stack so that ip is placed within the library function
315      calling the syscall.  This makes stack backtraces much more
316      useful.  */
317   if (ip >= (Addr)&VG_(trampoline_stuff_start)
318       && ip < (Addr)&VG_(trampoline_stuff_end)
319       && VG_(am_is_valid_for_client)(sp, sizeof(Addr), VKI_PROT_READ)) {
320      ip = *(Addr *)sp;
321      sp += sizeof(Addr);
322   }
323#  endif
324
325   if (0)
326      VG_(printf)("tid %d: stack_highest=%p ip=%p sp=%p fp=%p\n",
327		  tid, stack_highest_word, ip, sp, fp);
328
329   return VG_(get_StackTrace2)(ips, n_ips, ip, sp, fp, lr, sp, stack_highest_word);
330}
331
332static void printIpDesc(UInt n, Addr ip)
333{
334   #define BUF_LEN   4096
335
336   static UChar buf[BUF_LEN];
337
338   VG_(describe_IP)(ip, buf, BUF_LEN);
339
340   if (VG_(clo_xml)) {
341      VG_(message)(Vg_UserMsg, "    %s", buf);
342   } else {
343      VG_(message)(Vg_UserMsg, "   %s %s", ( n == 0 ? "at" : "by" ), buf);
344   }
345}
346
347/* Print a StackTrace. */
348void VG_(pp_StackTrace) ( StackTrace ips, UInt n_ips )
349{
350   vg_assert( n_ips > 0 );
351
352   if (VG_(clo_xml))
353      VG_(message)(Vg_UserMsg, "  <stack>");
354
355   VG_(apply_StackTrace)( printIpDesc, ips, n_ips );
356
357   if (VG_(clo_xml))
358      VG_(message)(Vg_UserMsg, "  </stack>");
359}
360
361/* Get and immediately print a StackTrace. */
362void VG_(get_and_pp_StackTrace) ( ThreadId tid, UInt n_ips )
363{
364   Addr ips[n_ips];
365   VG_(get_StackTrace)(tid, ips, n_ips);
366   VG_(pp_StackTrace) (     ips, n_ips);
367}
368
369
370void VG_(apply_StackTrace)( void(*action)(UInt n, Addr ip),
371                            StackTrace ips, UInt n_ips )
372{
373   #define MYBUF_LEN 10    // only needs to be long enough for "main"
374
375   Bool main_done = False;
376   Char mybuf[MYBUF_LEN];     // ok to stack allocate mybuf[] -- it's tiny
377   Int i = 0;
378
379   vg_assert(n_ips > 0);
380   do {
381      Addr ip = ips[i];
382      if (i > 0)
383         ip -= VG_MIN_INSTR_SZB;   // point to calling line
384
385      // Stop after "main";  if main() is recursive, stop after last main().
386      if ( ! VG_(clo_show_below_main)) {
387         VG_(get_fnname_nodemangle)( ip, mybuf, MYBUF_LEN );
388         if ( VG_STREQ("main", mybuf) )
389            main_done = True;
390         else if (main_done)
391            break;
392      }
393
394      // Act on the ip
395      action(i, ip);
396
397      i++;
398   } while (i < n_ips && ips[i] != 0);
399
400   #undef MYBUF_LEN
401}
402
403
404/*--------------------------------------------------------------------*/
405/*--- end                                                          ---*/
406/*--------------------------------------------------------------------*/
407