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