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