stackwalk_common.cc
1 // Copyright 2010 Google LLC 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following disclaimer 11 // in the documentation and/or other materials provided with the 12 // distribution. 13 // * Neither the name of Google LLC nor the names of its 14 // contributors may be used to endorse or promote products derived from 15 // this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 // stackwalk_common.cc: Module shared by the {micro,mini}dump_stackwalck 30 // executables to print the content of dumps (w/ stack traces) on the console. 31 // 32 // Author: Mark Mentovai 33 34 #ifdef HAVE_CONFIG_H 35 #include <config.h> // Must come first 36 #endif 37 38 #include "processor/stackwalk_common.h" 39 40 #include <assert.h> 41 #include <stdlib.h> 42 #include <string.h> 43 44 #include <string> 45 #include <vector> 46 47 #include "common/stdio_wrapper.h" 48 #include "common/using_std_string.h" 49 #include "google_breakpad/processor/call_stack.h" 50 #include "google_breakpad/processor/code_module.h" 51 #include "google_breakpad/processor/code_modules.h" 52 #include "google_breakpad/processor/process_state.h" 53 #include "google_breakpad/processor/source_line_resolver_interface.h" 54 #include "google_breakpad/processor/stack_frame_cpu.h" 55 #include "processor/logging.h" 56 #include "processor/pathname_stripper.h" 57 58 namespace google_breakpad { 59 60 namespace { 61 62 using std::vector; 63 using std::unique_ptr; 64 65 // Separator character for machine readable output. 66 static const char kOutputSeparator = '|'; 67 68 // PrintRegister prints a register's name and value to stdout. It will 69 // print four registers on a line. For the first register in a set, 70 // pass 0 for |start_col|. For registers in a set, pass the most recent 71 // return value of PrintRegister. 72 // The caller is responsible for printing the final newline after a set 73 // of registers is completely printed, regardless of the number of calls 74 // to PrintRegister. 75 static const int kMaxWidth = 80; // optimize for an 80-column terminal 76 static int PrintRegister(const char* name, uint32_t value, int start_col) { 77 char buffer[64]; 78 snprintf(buffer, sizeof(buffer), " %5s = 0x%08x", name, value); 79 80 if (start_col + static_cast<ssize_t>(strlen(buffer)) > kMaxWidth) { 81 start_col = 0; 82 printf("\n "); 83 } 84 fputs(buffer, stdout); 85 86 return start_col + strlen(buffer); 87 } 88 89 // PrintRegister64 does the same thing, but for 64-bit registers. 90 static int PrintRegister64(const char* name, uint64_t value, int start_col) { 91 char buffer[64]; 92 snprintf(buffer, sizeof(buffer), " %5s = 0x%016" PRIx64 , name, value); 93 94 if (start_col + static_cast<ssize_t>(strlen(buffer)) > kMaxWidth) { 95 start_col = 0; 96 printf("\n "); 97 } 98 fputs(buffer, stdout); 99 100 return start_col + strlen(buffer); 101 } 102 103 // StripSeparator takes a string |original| and returns a copy 104 // of the string with all occurences of |kOutputSeparator| removed. 105 static string StripSeparator(const string& original) { 106 string result = original; 107 string::size_type position = 0; 108 while ((position = result.find(kOutputSeparator, position)) != string::npos) { 109 result.erase(position, 1); 110 } 111 position = 0; 112 while ((position = result.find('\n', position)) != string::npos) { 113 result.erase(position, 1); 114 } 115 return result; 116 } 117 118 // PrintStackContents prints the stack contents of the current frame to stdout. 119 static void PrintStackContents(const string& indent, 120 const StackFrame* frame, 121 const StackFrame* prev_frame, 122 const string& cpu, 123 const MemoryRegion* memory, 124 const CodeModules* modules, 125 SourceLineResolverInterface* resolver) { 126 // Find stack range. 127 int word_length = 0; 128 uint64_t stack_begin = 0, stack_end = 0; 129 if (cpu == "x86") { 130 word_length = 4; 131 const StackFrameX86* frame_x86 = static_cast<const StackFrameX86*>(frame); 132 const StackFrameX86* prev_frame_x86 = 133 static_cast<const StackFrameX86*>(prev_frame); 134 if ((frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESP) && 135 (prev_frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESP)) { 136 stack_begin = frame_x86->context.esp; 137 stack_end = prev_frame_x86->context.esp; 138 } 139 } else if (cpu == "amd64") { 140 word_length = 8; 141 const StackFrameAMD64* frame_amd64 = 142 static_cast<const StackFrameAMD64*>(frame); 143 const StackFrameAMD64* prev_frame_amd64 = 144 static_cast<const StackFrameAMD64*>(prev_frame); 145 if ((frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RSP) && 146 (prev_frame_amd64->context_validity & 147 StackFrameAMD64::CONTEXT_VALID_RSP)) { 148 stack_begin = frame_amd64->context.rsp; 149 stack_end = prev_frame_amd64->context.rsp; 150 } 151 } else if (cpu == "arm") { 152 word_length = 4; 153 const StackFrameARM* frame_arm = static_cast<const StackFrameARM*>(frame); 154 const StackFrameARM* prev_frame_arm = 155 static_cast<const StackFrameARM*>(prev_frame); 156 if ((frame_arm->context_validity & 157 StackFrameARM::CONTEXT_VALID_SP) && 158 (prev_frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_SP)) { 159 stack_begin = frame_arm->context.iregs[13]; 160 stack_end = prev_frame_arm->context.iregs[13]; 161 } 162 } else if (cpu == "arm64") { 163 word_length = 8; 164 const StackFrameARM64* frame_arm64 = 165 static_cast<const StackFrameARM64*>(frame); 166 const StackFrameARM64* prev_frame_arm64 = 167 static_cast<const StackFrameARM64*>(prev_frame); 168 if ((frame_arm64->context_validity & 169 StackFrameARM64::CONTEXT_VALID_SP) && 170 (prev_frame_arm64->context_validity & 171 StackFrameARM64::CONTEXT_VALID_SP)) { 172 stack_begin = frame_arm64->context.iregs[31]; 173 stack_end = prev_frame_arm64->context.iregs[31]; 174 } 175 } else if (cpu == "riscv") { 176 word_length = 4; 177 const StackFrameRISCV* frame_riscv = 178 static_cast<const StackFrameRISCV*>(frame); 179 const StackFrameRISCV* prev_frame_riscv = 180 static_cast<const StackFrameRISCV*>(prev_frame); 181 if ((frame_riscv->context_validity & 182 StackFrameRISCV::CONTEXT_VALID_SP) && 183 (prev_frame_riscv->context_validity & 184 StackFrameRISCV::CONTEXT_VALID_SP)) { 185 stack_begin = frame_riscv->context.sp; 186 stack_end = prev_frame_riscv->context.sp; 187 } 188 } else if (cpu == "riscv64") { 189 word_length = 8; 190 const StackFrameRISCV64* frame_riscv64 = 191 static_cast<const StackFrameRISCV64*>(frame); 192 const StackFrameRISCV64* prev_frame_riscv64 = 193 static_cast<const StackFrameRISCV64*>(prev_frame); 194 if ((frame_riscv64->context_validity & 195 StackFrameRISCV64::CONTEXT_VALID_SP) && 196 (prev_frame_riscv64->context_validity & 197 StackFrameRISCV64::CONTEXT_VALID_SP)) { 198 stack_begin = frame_riscv64->context.sp; 199 stack_end = prev_frame_riscv64->context.sp; 200 } 201 } 202 if (!word_length || !stack_begin || !stack_end) 203 return; 204 205 // Print stack contents. 206 printf("\n%sStack contents:", indent.c_str()); 207 for(uint64_t address = stack_begin; address < stack_end; ) { 208 // Print the start address of this row. 209 if (word_length == 4) 210 printf("\n%s %08x", indent.c_str(), static_cast<uint32_t>(address)); 211 else 212 printf("\n%s %016" PRIx64, indent.c_str(), address); 213 214 // Print data in hex. 215 const int kBytesPerRow = 16; 216 string data_as_string; 217 for (int i = 0; i < kBytesPerRow; ++i, ++address) { 218 uint8_t value = 0; 219 if (address < stack_end && 220 memory->GetMemoryAtAddress(address, &value)) { 221 printf(" %02x", value); 222 data_as_string.push_back(isprint(value) ? value : '.'); 223 } else { 224 printf(" "); 225 data_as_string.push_back(' '); 226 } 227 } 228 // Print data as string. 229 printf(" %s", data_as_string.c_str()); 230 } 231 232 // Try to find instruction pointers from stack. 233 printf("\n%sPossible instruction pointers:\n", indent.c_str()); 234 for (uint64_t address = stack_begin; address < stack_end; 235 address += word_length) { 236 StackFrame pointee_frame; 237 238 // Read a word (possible instruction pointer) from stack. 239 if (word_length == 4) { 240 uint32_t data32 = 0; 241 memory->GetMemoryAtAddress(address, &data32); 242 pointee_frame.instruction = data32; 243 } else { 244 uint64_t data64 = 0; 245 memory->GetMemoryAtAddress(address, &data64); 246 pointee_frame.instruction = data64; 247 } 248 pointee_frame.module = 249 modules->GetModuleForAddress(pointee_frame.instruction); 250 251 // Try to look up the function name. 252 std::deque<unique_ptr<StackFrame>> inlined_frames; 253 if (pointee_frame.module) 254 resolver->FillSourceLineInfo(&pointee_frame, &inlined_frames); 255 256 // Print function name. 257 auto print_function_name = [&](StackFrame* frame) { 258 if (!frame->function_name.empty()) { 259 if (word_length == 4) { 260 printf("%s *(0x%08x) = 0x%08x", indent.c_str(), 261 static_cast<uint32_t>(address), 262 static_cast<uint32_t>(frame->instruction)); 263 } else { 264 printf("%s *(0x%016" PRIx64 ") = 0x%016" PRIx64, indent.c_str(), 265 address, frame->instruction); 266 } 267 printf( 268 " <%s> [%s : %d + 0x%" PRIx64 "]\n", frame->function_name.c_str(), 269 PathnameStripper::File(frame->source_file_name).c_str(), 270 frame->source_line, frame->instruction - frame->source_line_base); 271 } 272 }; 273 print_function_name(&pointee_frame); 274 for (unique_ptr<StackFrame> &frame : inlined_frames) 275 print_function_name(frame.get()); 276 } 277 printf("\n"); 278 } 279 280 static void PrintFrameHeader(const StackFrame* frame, int frame_index) { 281 printf("%2d ", frame_index); 282 283 uint64_t instruction_address = frame->ReturnAddress(); 284 285 if (frame->module) { 286 printf("%s", PathnameStripper::File(frame->module->code_file()).c_str()); 287 if (!frame->function_name.empty()) { 288 printf("!%s", frame->function_name.c_str()); 289 if (!frame->source_file_name.empty()) { 290 string source_file = PathnameStripper::File(frame->source_file_name); 291 printf(" [%s : %d + 0x%" PRIx64 "]", source_file.c_str(), 292 frame->source_line, 293 instruction_address - frame->source_line_base); 294 } else { 295 printf(" + 0x%" PRIx64, instruction_address - frame->function_base); 296 } 297 } else { 298 printf(" + 0x%" PRIx64, 299 instruction_address - frame->module->base_address()); 300 } 301 } else { 302 printf("0x%" PRIx64, instruction_address); 303 } 304 } 305 306 // PrintStack prints the call stack in |stack| to stdout, in a reasonably 307 // useful form. Module, function, and source file names are displayed if 308 // they are available. The code offset to the base code address of the 309 // source line, function, or module is printed, preferring them in that 310 // order. If no source line, function, or module information is available, 311 // an absolute code offset is printed. 312 // 313 // If |cpu| is a recognized CPU name, relevant register state for each stack 314 // frame printed is also output, if available. 315 static void PrintStack(const CallStack* stack, 316 const string& cpu, 317 bool output_stack_contents, 318 const MemoryRegion* memory, 319 const CodeModules* modules, 320 SourceLineResolverInterface* resolver) { 321 int frame_count = stack->frames()->size(); 322 if (frame_count == 0) { 323 printf(" <no frames>\n"); 324 } 325 for (int frame_index = 0; frame_index < frame_count; ++frame_index) { 326 const StackFrame* frame = stack->frames()->at(frame_index); 327 PrintFrameHeader(frame, frame_index); 328 printf("\n "); 329 330 // Inlined frames don't have registers info. 331 if (frame->trust != StackFrameAMD64::FRAME_TRUST_INLINE) { 332 int sequence = 0; 333 if (cpu == "x86") { 334 const StackFrameX86* frame_x86 = 335 reinterpret_cast<const StackFrameX86*>(frame); 336 337 if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EIP) 338 sequence = PrintRegister("eip", frame_x86->context.eip, sequence); 339 if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESP) 340 sequence = PrintRegister("esp", frame_x86->context.esp, sequence); 341 if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EBP) 342 sequence = PrintRegister("ebp", frame_x86->context.ebp, sequence); 343 if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EBX) 344 sequence = PrintRegister("ebx", frame_x86->context.ebx, sequence); 345 if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_ESI) 346 sequence = PrintRegister("esi", frame_x86->context.esi, sequence); 347 if (frame_x86->context_validity & StackFrameX86::CONTEXT_VALID_EDI) 348 sequence = PrintRegister("edi", frame_x86->context.edi, sequence); 349 if (frame_x86->context_validity == StackFrameX86::CONTEXT_VALID_ALL) { 350 sequence = PrintRegister("eax", frame_x86->context.eax, sequence); 351 sequence = PrintRegister("ecx", frame_x86->context.ecx, sequence); 352 sequence = PrintRegister("edx", frame_x86->context.edx, sequence); 353 sequence = PrintRegister("efl", frame_x86->context.eflags, sequence); 354 } 355 } else if (cpu == "ppc") { 356 const StackFramePPC* frame_ppc = 357 reinterpret_cast<const StackFramePPC*>(frame); 358 359 if (frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_SRR0) 360 sequence = PrintRegister("srr0", frame_ppc->context.srr0, sequence); 361 if (frame_ppc->context_validity & StackFramePPC::CONTEXT_VALID_GPR1) 362 sequence = PrintRegister("r1", frame_ppc->context.gpr[1], sequence); 363 } else if (cpu == "amd64") { 364 const StackFrameAMD64* frame_amd64 = 365 reinterpret_cast<const StackFrameAMD64*>(frame); 366 367 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RAX) 368 sequence = PrintRegister64("rax", frame_amd64->context.rax, sequence); 369 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RDX) 370 sequence = PrintRegister64("rdx", frame_amd64->context.rdx, sequence); 371 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RCX) 372 sequence = PrintRegister64("rcx", frame_amd64->context.rcx, sequence); 373 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RBX) 374 sequence = PrintRegister64("rbx", frame_amd64->context.rbx, sequence); 375 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RSI) 376 sequence = PrintRegister64("rsi", frame_amd64->context.rsi, sequence); 377 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RDI) 378 sequence = PrintRegister64("rdi", frame_amd64->context.rdi, sequence); 379 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RBP) 380 sequence = PrintRegister64("rbp", frame_amd64->context.rbp, sequence); 381 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RSP) 382 sequence = PrintRegister64("rsp", frame_amd64->context.rsp, sequence); 383 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R8) 384 sequence = PrintRegister64("r8", frame_amd64->context.r8, sequence); 385 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R9) 386 sequence = PrintRegister64("r9", frame_amd64->context.r9, sequence); 387 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R10) 388 sequence = PrintRegister64("r10", frame_amd64->context.r10, sequence); 389 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R11) 390 sequence = PrintRegister64("r11", frame_amd64->context.r11, sequence); 391 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R12) 392 sequence = PrintRegister64("r12", frame_amd64->context.r12, sequence); 393 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R13) 394 sequence = PrintRegister64("r13", frame_amd64->context.r13, sequence); 395 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R14) 396 sequence = PrintRegister64("r14", frame_amd64->context.r14, sequence); 397 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_R15) 398 sequence = PrintRegister64("r15", frame_amd64->context.r15, sequence); 399 if (frame_amd64->context_validity & StackFrameAMD64::CONTEXT_VALID_RIP) 400 sequence = PrintRegister64("rip", frame_amd64->context.rip, sequence); 401 } else if (cpu == "sparc") { 402 const StackFrameSPARC* frame_sparc = 403 reinterpret_cast<const StackFrameSPARC*>(frame); 404 405 if (frame_sparc->context_validity & StackFrameSPARC::CONTEXT_VALID_SP) 406 sequence = 407 PrintRegister("sp", frame_sparc->context.g_r[14], sequence); 408 if (frame_sparc->context_validity & StackFrameSPARC::CONTEXT_VALID_FP) 409 sequence = 410 PrintRegister("fp", frame_sparc->context.g_r[30], sequence); 411 if (frame_sparc->context_validity & StackFrameSPARC::CONTEXT_VALID_PC) 412 sequence = PrintRegister("pc", frame_sparc->context.pc, sequence); 413 } else if (cpu == "arm") { 414 const StackFrameARM* frame_arm = 415 reinterpret_cast<const StackFrameARM*>(frame); 416 417 // Argument registers (caller-saves), which will likely only be valid 418 // for the youngest frame. 419 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R0) 420 sequence = PrintRegister("r0", frame_arm->context.iregs[0], sequence); 421 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R1) 422 sequence = PrintRegister("r1", frame_arm->context.iregs[1], sequence); 423 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R2) 424 sequence = PrintRegister("r2", frame_arm->context.iregs[2], sequence); 425 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R3) 426 sequence = PrintRegister("r3", frame_arm->context.iregs[3], sequence); 427 428 // General-purpose callee-saves registers. 429 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R4) 430 sequence = PrintRegister("r4", frame_arm->context.iregs[4], sequence); 431 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R5) 432 sequence = PrintRegister("r5", frame_arm->context.iregs[5], sequence); 433 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R6) 434 sequence = PrintRegister("r6", frame_arm->context.iregs[6], sequence); 435 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R7) 436 sequence = PrintRegister("r7", frame_arm->context.iregs[7], sequence); 437 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R8) 438 sequence = PrintRegister("r8", frame_arm->context.iregs[8], sequence); 439 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R9) 440 sequence = PrintRegister("r9", frame_arm->context.iregs[9], sequence); 441 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R10) 442 sequence = 443 PrintRegister("r10", frame_arm->context.iregs[10], sequence); 444 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_R12) 445 sequence = 446 PrintRegister("r12", frame_arm->context.iregs[12], sequence); 447 448 // Registers with a dedicated or conventional purpose. 449 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_FP) 450 sequence = 451 PrintRegister("fp", frame_arm->context.iregs[11], sequence); 452 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_SP) 453 sequence = 454 PrintRegister("sp", frame_arm->context.iregs[13], sequence); 455 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_LR) 456 sequence = 457 PrintRegister("lr", frame_arm->context.iregs[14], sequence); 458 if (frame_arm->context_validity & StackFrameARM::CONTEXT_VALID_PC) 459 sequence = 460 PrintRegister("pc", frame_arm->context.iregs[15], sequence); 461 } else if (cpu == "arm64") { 462 const StackFrameARM64* frame_arm64 = 463 reinterpret_cast<const StackFrameARM64*>(frame); 464 465 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X0) { 466 sequence = 467 PrintRegister64("x0", frame_arm64->context.iregs[0], sequence); 468 } 469 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X1) { 470 sequence = 471 PrintRegister64("x1", frame_arm64->context.iregs[1], sequence); 472 } 473 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X2) { 474 sequence = 475 PrintRegister64("x2", frame_arm64->context.iregs[2], sequence); 476 } 477 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X3) { 478 sequence = 479 PrintRegister64("x3", frame_arm64->context.iregs[3], sequence); 480 } 481 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X4) { 482 sequence = 483 PrintRegister64("x4", frame_arm64->context.iregs[4], sequence); 484 } 485 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X5) { 486 sequence = 487 PrintRegister64("x5", frame_arm64->context.iregs[5], sequence); 488 } 489 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X6) { 490 sequence = 491 PrintRegister64("x6", frame_arm64->context.iregs[6], sequence); 492 } 493 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X7) { 494 sequence = 495 PrintRegister64("x7", frame_arm64->context.iregs[7], sequence); 496 } 497 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X8) { 498 sequence = 499 PrintRegister64("x8", frame_arm64->context.iregs[8], sequence); 500 } 501 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_X9) { 502 sequence = 503 PrintRegister64("x9", frame_arm64->context.iregs[9], sequence); 504 } 505 if (frame_arm64->context_validity & 506 StackFrameARM64::CONTEXT_VALID_X10) { 507 sequence = 508 PrintRegister64("x10", frame_arm64->context.iregs[10], sequence); 509 } 510 if (frame_arm64->context_validity & 511 StackFrameARM64::CONTEXT_VALID_X11) { 512 sequence = 513 PrintRegister64("x11", frame_arm64->context.iregs[11], sequence); 514 } 515 if (frame_arm64->context_validity & 516 StackFrameARM64::CONTEXT_VALID_X12) { 517 sequence = 518 PrintRegister64("x12", frame_arm64->context.iregs[12], sequence); 519 } 520 if (frame_arm64->context_validity & 521 StackFrameARM64::CONTEXT_VALID_X13) { 522 sequence = 523 PrintRegister64("x13", frame_arm64->context.iregs[13], sequence); 524 } 525 if (frame_arm64->context_validity & 526 StackFrameARM64::CONTEXT_VALID_X14) { 527 sequence = 528 PrintRegister64("x14", frame_arm64->context.iregs[14], sequence); 529 } 530 if (frame_arm64->context_validity & 531 StackFrameARM64::CONTEXT_VALID_X15) { 532 sequence = 533 PrintRegister64("x15", frame_arm64->context.iregs[15], sequence); 534 } 535 if (frame_arm64->context_validity & 536 StackFrameARM64::CONTEXT_VALID_X16) { 537 sequence = 538 PrintRegister64("x16", frame_arm64->context.iregs[16], sequence); 539 } 540 if (frame_arm64->context_validity & 541 StackFrameARM64::CONTEXT_VALID_X17) { 542 sequence = 543 PrintRegister64("x17", frame_arm64->context.iregs[17], sequence); 544 } 545 if (frame_arm64->context_validity & 546 StackFrameARM64::CONTEXT_VALID_X18) { 547 sequence = 548 PrintRegister64("x18", frame_arm64->context.iregs[18], sequence); 549 } 550 if (frame_arm64->context_validity & 551 StackFrameARM64::CONTEXT_VALID_X19) { 552 sequence = 553 PrintRegister64("x19", frame_arm64->context.iregs[19], sequence); 554 } 555 if (frame_arm64->context_validity & 556 StackFrameARM64::CONTEXT_VALID_X20) { 557 sequence = 558 PrintRegister64("x20", frame_arm64->context.iregs[20], sequence); 559 } 560 if (frame_arm64->context_validity & 561 StackFrameARM64::CONTEXT_VALID_X21) { 562 sequence = 563 PrintRegister64("x21", frame_arm64->context.iregs[21], sequence); 564 } 565 if (frame_arm64->context_validity & 566 StackFrameARM64::CONTEXT_VALID_X22) { 567 sequence = 568 PrintRegister64("x22", frame_arm64->context.iregs[22], sequence); 569 } 570 if (frame_arm64->context_validity & 571 StackFrameARM64::CONTEXT_VALID_X23) { 572 sequence = 573 PrintRegister64("x23", frame_arm64->context.iregs[23], sequence); 574 } 575 if (frame_arm64->context_validity & 576 StackFrameARM64::CONTEXT_VALID_X24) { 577 sequence = 578 PrintRegister64("x24", frame_arm64->context.iregs[24], sequence); 579 } 580 if (frame_arm64->context_validity & 581 StackFrameARM64::CONTEXT_VALID_X25) { 582 sequence = 583 PrintRegister64("x25", frame_arm64->context.iregs[25], sequence); 584 } 585 if (frame_arm64->context_validity & 586 StackFrameARM64::CONTEXT_VALID_X26) { 587 sequence = 588 PrintRegister64("x26", frame_arm64->context.iregs[26], sequence); 589 } 590 if (frame_arm64->context_validity & 591 StackFrameARM64::CONTEXT_VALID_X27) { 592 sequence = 593 PrintRegister64("x27", frame_arm64->context.iregs[27], sequence); 594 } 595 if (frame_arm64->context_validity & 596 StackFrameARM64::CONTEXT_VALID_X28) { 597 sequence = 598 PrintRegister64("x28", frame_arm64->context.iregs[28], sequence); 599 } 600 601 // Registers with a dedicated or conventional purpose. 602 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_FP) { 603 sequence = 604 PrintRegister64("fp", frame_arm64->context.iregs[29], sequence); 605 } 606 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_LR) { 607 sequence = 608 PrintRegister64("lr", frame_arm64->context.iregs[30], sequence); 609 } 610 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_SP) { 611 sequence = 612 PrintRegister64("sp", frame_arm64->context.iregs[31], sequence); 613 } 614 if (frame_arm64->context_validity & StackFrameARM64::CONTEXT_VALID_PC) { 615 sequence = 616 PrintRegister64("pc", frame_arm64->context.iregs[32], sequence); 617 } 618 } else if ((cpu == "mips") || (cpu == "mips64")) { 619 const StackFrameMIPS* frame_mips = 620 reinterpret_cast<const StackFrameMIPS*>(frame); 621 622 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_GP) 623 sequence = PrintRegister64( 624 "gp", frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_GP], 625 sequence); 626 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_SP) 627 sequence = PrintRegister64( 628 "sp", frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_SP], 629 sequence); 630 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_FP) 631 sequence = PrintRegister64( 632 "fp", frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_FP], 633 sequence); 634 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_RA) 635 sequence = PrintRegister64( 636 "ra", frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_RA], 637 sequence); 638 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_PC) 639 sequence = PrintRegister64("pc", frame_mips->context.epc, sequence); 640 641 // Save registers s0-s7 642 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S0) 643 sequence = PrintRegister64( 644 "s0", frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S0], 645 sequence); 646 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S1) 647 sequence = PrintRegister64( 648 "s1", frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S1], 649 sequence); 650 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S2) 651 sequence = PrintRegister64( 652 "s2", frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S2], 653 sequence); 654 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S3) 655 sequence = PrintRegister64( 656 "s3", frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S3], 657 sequence); 658 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S4) 659 sequence = PrintRegister64( 660 "s4", frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S4], 661 sequence); 662 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S5) 663 sequence = PrintRegister64( 664 "s5", frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S5], 665 sequence); 666 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S6) 667 sequence = PrintRegister64( 668 "s6", frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S6], 669 sequence); 670 if (frame_mips->context_validity & StackFrameMIPS::CONTEXT_VALID_S7) 671 sequence = PrintRegister64( 672 "s7", frame_mips->context.iregs[MD_CONTEXT_MIPS_REG_S7], 673 sequence); 674 } else if (cpu == "riscv") { 675 const StackFrameRISCV* frame_riscv = 676 reinterpret_cast<const StackFrameRISCV*>(frame); 677 678 if (frame_riscv->context_validity & 679 StackFrameRISCV::CONTEXT_VALID_PC) 680 sequence = PrintRegister( 681 "pc", frame_riscv->context.pc, sequence); 682 if (frame_riscv->context_validity & 683 StackFrameRISCV::CONTEXT_VALID_RA) 684 sequence = PrintRegister( 685 "ra", frame_riscv->context.ra, sequence); 686 if (frame_riscv->context_validity & 687 StackFrameRISCV::CONTEXT_VALID_SP) 688 sequence = PrintRegister( 689 "sp", frame_riscv->context.sp, sequence); 690 if (frame_riscv->context_validity & 691 StackFrameRISCV::CONTEXT_VALID_GP) 692 sequence = PrintRegister( 693 "gp", frame_riscv->context.gp, sequence); 694 if (frame_riscv->context_validity & 695 StackFrameRISCV::CONTEXT_VALID_TP) 696 sequence = PrintRegister( 697 "tp", frame_riscv->context.tp, sequence); 698 if (frame_riscv->context_validity & 699 StackFrameRISCV::CONTEXT_VALID_T0) 700 sequence = PrintRegister( 701 "t0", frame_riscv->context.t0, sequence); 702 if (frame_riscv->context_validity & 703 StackFrameRISCV::CONTEXT_VALID_T1) 704 sequence = PrintRegister( 705 "t1", frame_riscv->context.t1, sequence); 706 if (frame_riscv->context_validity & 707 StackFrameRISCV::CONTEXT_VALID_T2) 708 sequence = PrintRegister( 709 "t2", frame_riscv->context.t2, sequence); 710 if (frame_riscv->context_validity & 711 StackFrameRISCV::CONTEXT_VALID_S0) 712 sequence = PrintRegister( 713 "s0", frame_riscv->context.s0, sequence); 714 if (frame_riscv->context_validity & 715 StackFrameRISCV::CONTEXT_VALID_S1) 716 sequence = PrintRegister( 717 "s1", frame_riscv->context.s1, sequence); 718 if (frame_riscv->context_validity & 719 StackFrameRISCV::CONTEXT_VALID_A0) 720 sequence = PrintRegister( 721 "a0", frame_riscv->context.a0, sequence); 722 if (frame_riscv->context_validity & 723 StackFrameRISCV::CONTEXT_VALID_A1) 724 sequence = PrintRegister( 725 "a1", frame_riscv->context.a1, sequence); 726 if (frame_riscv->context_validity & 727 StackFrameRISCV::CONTEXT_VALID_A2) 728 sequence = PrintRegister( 729 "a2", frame_riscv->context.a2, sequence); 730 if (frame_riscv->context_validity & 731 StackFrameRISCV::CONTEXT_VALID_A3) 732 sequence = PrintRegister( 733 "a3", frame_riscv->context.a3, sequence); 734 if (frame_riscv->context_validity & 735 StackFrameRISCV::CONTEXT_VALID_A4) 736 sequence = PrintRegister( 737 "a4", frame_riscv->context.a4, sequence); 738 if (frame_riscv->context_validity & 739 StackFrameRISCV::CONTEXT_VALID_A5) 740 sequence = PrintRegister( 741 "a5", frame_riscv->context.a5, sequence); 742 if (frame_riscv->context_validity & 743 StackFrameRISCV::CONTEXT_VALID_A6) 744 sequence = PrintRegister( 745 "a6", frame_riscv->context.a6, sequence); 746 if (frame_riscv->context_validity & 747 StackFrameRISCV::CONTEXT_VALID_A7) 748 sequence = PrintRegister( 749 "a7", frame_riscv->context.a7, sequence); 750 if (frame_riscv->context_validity & 751 StackFrameRISCV::CONTEXT_VALID_S2) 752 sequence = PrintRegister( 753 "s2", frame_riscv->context.s2, sequence); 754 if (frame_riscv->context_validity & 755 StackFrameRISCV::CONTEXT_VALID_S3) 756 sequence = PrintRegister( 757 "s3", frame_riscv->context.s3, sequence); 758 if (frame_riscv->context_validity & 759 StackFrameRISCV::CONTEXT_VALID_S4) 760 sequence = PrintRegister( 761 "s4", frame_riscv->context.s4, sequence); 762 if (frame_riscv->context_validity & 763 StackFrameRISCV::CONTEXT_VALID_S5) 764 sequence = PrintRegister( 765 "s5", frame_riscv->context.s5, sequence); 766 if (frame_riscv->context_validity & 767 StackFrameRISCV::CONTEXT_VALID_S6) 768 sequence = PrintRegister( 769 "s6", frame_riscv->context.s6, sequence); 770 if (frame_riscv->context_validity & 771 StackFrameRISCV::CONTEXT_VALID_S7) 772 sequence = PrintRegister( 773 "s7", frame_riscv->context.s7, sequence); 774 if (frame_riscv->context_validity & 775 StackFrameRISCV::CONTEXT_VALID_S8) 776 sequence = PrintRegister( 777 "s8", frame_riscv->context.s8, sequence); 778 if (frame_riscv->context_validity & 779 StackFrameRISCV::CONTEXT_VALID_S9) 780 sequence = PrintRegister( 781 "s9", frame_riscv->context.s9, sequence); 782 if (frame_riscv->context_validity & 783 StackFrameRISCV::CONTEXT_VALID_S10) 784 sequence = PrintRegister( 785 "s10", frame_riscv->context.s10, sequence); 786 if (frame_riscv->context_validity & 787 StackFrameRISCV::CONTEXT_VALID_S11) 788 sequence = PrintRegister( 789 "s11", frame_riscv->context.s11, sequence); 790 if (frame_riscv->context_validity & 791 StackFrameRISCV::CONTEXT_VALID_T3) 792 sequence = PrintRegister( 793 "t3", frame_riscv->context.t3, sequence); 794 if (frame_riscv->context_validity & 795 StackFrameRISCV::CONTEXT_VALID_T4) 796 sequence = PrintRegister( 797 "t4", frame_riscv->context.t4, sequence); 798 if (frame_riscv->context_validity & 799 StackFrameRISCV::CONTEXT_VALID_T5) 800 sequence = PrintRegister( 801 "t5", frame_riscv->context.t5, sequence); 802 if (frame_riscv->context_validity & 803 StackFrameRISCV::CONTEXT_VALID_T6) 804 sequence = PrintRegister( 805 "t6", frame_riscv->context.t6, sequence); 806 } else if (cpu == "riscv64") { 807 const StackFrameRISCV64* frame_riscv64 = 808 reinterpret_cast<const StackFrameRISCV64*>(frame); 809 810 if (frame_riscv64->context_validity & 811 StackFrameRISCV64::CONTEXT_VALID_PC) 812 sequence = PrintRegister64( 813 "pc", frame_riscv64->context.pc, sequence); 814 if (frame_riscv64->context_validity & 815 StackFrameRISCV64::CONTEXT_VALID_RA) 816 sequence = PrintRegister64( 817 "ra", frame_riscv64->context.ra, sequence); 818 if (frame_riscv64->context_validity & 819 StackFrameRISCV64::CONTEXT_VALID_SP) 820 sequence = PrintRegister64( 821 "sp", frame_riscv64->context.sp, sequence); 822 if (frame_riscv64->context_validity & 823 StackFrameRISCV64::CONTEXT_VALID_GP) 824 sequence = PrintRegister64( 825 "gp", frame_riscv64->context.gp, sequence); 826 if (frame_riscv64->context_validity & 827 StackFrameRISCV64::CONTEXT_VALID_TP) 828 sequence = PrintRegister64( 829 "tp", frame_riscv64->context.tp, sequence); 830 if (frame_riscv64->context_validity & 831 StackFrameRISCV64::CONTEXT_VALID_T0) 832 sequence = PrintRegister64( 833 "t0", frame_riscv64->context.t0, sequence); 834 if (frame_riscv64->context_validity & 835 StackFrameRISCV64::CONTEXT_VALID_T1) 836 sequence = PrintRegister64( 837 "t1", frame_riscv64->context.t1, sequence); 838 if (frame_riscv64->context_validity & 839 StackFrameRISCV64::CONTEXT_VALID_T2) 840 sequence = PrintRegister64( 841 "t2", frame_riscv64->context.t2, sequence); 842 if (frame_riscv64->context_validity & 843 StackFrameRISCV64::CONTEXT_VALID_S0) 844 sequence = PrintRegister64( 845 "s0", frame_riscv64->context.s0, sequence); 846 if (frame_riscv64->context_validity & 847 StackFrameRISCV64::CONTEXT_VALID_S1) 848 sequence = PrintRegister64( 849 "s1", frame_riscv64->context.s1, sequence); 850 if (frame_riscv64->context_validity & 851 StackFrameRISCV64::CONTEXT_VALID_A0) 852 sequence = PrintRegister64( 853 "a0", frame_riscv64->context.a0, sequence); 854 if (frame_riscv64->context_validity & 855 StackFrameRISCV64::CONTEXT_VALID_A1) 856 sequence = PrintRegister64( 857 "a1", frame_riscv64->context.a1, sequence); 858 if (frame_riscv64->context_validity & 859 StackFrameRISCV64::CONTEXT_VALID_A2) 860 sequence = PrintRegister64( 861 "a2", frame_riscv64->context.a2, sequence); 862 if (frame_riscv64->context_validity & 863 StackFrameRISCV64::CONTEXT_VALID_A3) 864 sequence = PrintRegister64( 865 "a3", frame_riscv64->context.a3, sequence); 866 if (frame_riscv64->context_validity & 867 StackFrameRISCV64::CONTEXT_VALID_A4) 868 sequence = PrintRegister64( 869 "a4", frame_riscv64->context.a4, sequence); 870 if (frame_riscv64->context_validity & 871 StackFrameRISCV64::CONTEXT_VALID_A5) 872 sequence = PrintRegister64( 873 "a5", frame_riscv64->context.a5, sequence); 874 if (frame_riscv64->context_validity & 875 StackFrameRISCV64::CONTEXT_VALID_A6) 876 sequence = PrintRegister64( 877 "a6", frame_riscv64->context.a6, sequence); 878 if (frame_riscv64->context_validity & 879 StackFrameRISCV64::CONTEXT_VALID_A7) 880 sequence = PrintRegister64( 881 "a7", frame_riscv64->context.a7, sequence); 882 if (frame_riscv64->context_validity & 883 StackFrameRISCV64::CONTEXT_VALID_S2) 884 sequence = PrintRegister64( 885 "s2", frame_riscv64->context.s2, sequence); 886 if (frame_riscv64->context_validity & 887 StackFrameRISCV64::CONTEXT_VALID_S3) 888 sequence = PrintRegister64( 889 "s3", frame_riscv64->context.s3, sequence); 890 if (frame_riscv64->context_validity & 891 StackFrameRISCV64::CONTEXT_VALID_S4) 892 sequence = PrintRegister64( 893 "s4", frame_riscv64->context.s4, sequence); 894 if (frame_riscv64->context_validity & 895 StackFrameRISCV64::CONTEXT_VALID_S5) 896 sequence = PrintRegister64( 897 "s5", frame_riscv64->context.s5, sequence); 898 if (frame_riscv64->context_validity & 899 StackFrameRISCV64::CONTEXT_VALID_S6) 900 sequence = PrintRegister64( 901 "s6", frame_riscv64->context.s6, sequence); 902 if (frame_riscv64->context_validity & 903 StackFrameRISCV64::CONTEXT_VALID_S7) 904 sequence = PrintRegister64( 905 "s7", frame_riscv64->context.s7, sequence); 906 if (frame_riscv64->context_validity & 907 StackFrameRISCV64::CONTEXT_VALID_S8) 908 sequence = PrintRegister64( 909 "s8", frame_riscv64->context.s8, sequence); 910 if (frame_riscv64->context_validity & 911 StackFrameRISCV64::CONTEXT_VALID_S9) 912 sequence = PrintRegister64( 913 "s9", frame_riscv64->context.s9, sequence); 914 if (frame_riscv64->context_validity & 915 StackFrameRISCV64::CONTEXT_VALID_S10) 916 sequence = PrintRegister64( 917 "s10", frame_riscv64->context.s10, sequence); 918 if (frame_riscv64->context_validity & 919 StackFrameRISCV64::CONTEXT_VALID_S11) 920 sequence = PrintRegister64( 921 "s11", frame_riscv64->context.s11, sequence); 922 if (frame_riscv64->context_validity & 923 StackFrameRISCV64::CONTEXT_VALID_T3) 924 sequence = PrintRegister64( 925 "t3", frame_riscv64->context.t3, sequence); 926 if (frame_riscv64->context_validity & 927 StackFrameRISCV64::CONTEXT_VALID_T4) 928 sequence = PrintRegister64( 929 "t4", frame_riscv64->context.t4, sequence); 930 if (frame_riscv64->context_validity & 931 StackFrameRISCV64::CONTEXT_VALID_T5) 932 sequence = PrintRegister64( 933 "t5", frame_riscv64->context.t5, sequence); 934 if (frame_riscv64->context_validity & 935 StackFrameRISCV64::CONTEXT_VALID_T6) 936 sequence = PrintRegister64( 937 "t6", frame_riscv64->context.t6, sequence); 938 } 939 } 940 printf("\n Found by: %s\n", frame->trust_description().c_str()); 941 942 // Print stack contents. 943 if (output_stack_contents && frame_index + 1 < frame_count) { 944 const string indent(" "); 945 PrintStackContents(indent, frame, stack->frames()->at(frame_index + 1), 946 cpu, memory, modules, resolver); 947 } 948 } 949 } 950 951 // PrintStackMachineReadable prints the call stack in |stack| to stdout, 952 // in the following machine readable pipe-delimited text format: 953 // thread number|frame number|module|function|source file|line|offset 954 // 955 // Module, function, source file, and source line may all be empty 956 // depending on availability. The code offset follows the same rules as 957 // PrintStack above. 958 static void PrintStackMachineReadable(int thread_num, const CallStack* stack) { 959 int frame_count = stack->frames()->size(); 960 for (int frame_index = 0; frame_index < frame_count; ++frame_index) { 961 const StackFrame* frame = stack->frames()->at(frame_index); 962 printf("%d%c%d%c", thread_num, kOutputSeparator, frame_index, 963 kOutputSeparator); 964 965 uint64_t instruction_address = frame->ReturnAddress(); 966 967 if (frame->module) { 968 assert(!frame->module->code_file().empty()); 969 printf("%s", StripSeparator(PathnameStripper::File( 970 frame->module->code_file())).c_str()); 971 if (!frame->function_name.empty()) { 972 printf("%c%s", kOutputSeparator, 973 StripSeparator(frame->function_name).c_str()); 974 if (!frame->source_file_name.empty()) { 975 printf("%c%s%c%d%c0x%" PRIx64, 976 kOutputSeparator, 977 StripSeparator(frame->source_file_name).c_str(), 978 kOutputSeparator, 979 frame->source_line, 980 kOutputSeparator, 981 instruction_address - frame->source_line_base); 982 } else { 983 printf("%c%c%c0x%" PRIx64, 984 kOutputSeparator, // empty source file 985 kOutputSeparator, // empty source line 986 kOutputSeparator, 987 instruction_address - frame->function_base); 988 } 989 } else { 990 printf("%c%c%c%c0x%" PRIx64, 991 kOutputSeparator, // empty function name 992 kOutputSeparator, // empty source file 993 kOutputSeparator, // empty source line 994 kOutputSeparator, 995 instruction_address - frame->module->base_address()); 996 } 997 } else { 998 // the printf before this prints a trailing separator for module name 999 printf("%c%c%c%c0x%" PRIx64, 1000 kOutputSeparator, // empty function name 1001 kOutputSeparator, // empty source file 1002 kOutputSeparator, // empty source line 1003 kOutputSeparator, 1004 instruction_address); 1005 } 1006 printf("\n"); 1007 } 1008 } 1009 1010 // ContainsModule checks whether a given |module| is in the vector 1011 // |modules_without_symbols|. 1012 static bool ContainsModule( 1013 const vector<const CodeModule*>* modules, 1014 const CodeModule* module) { 1015 assert(modules); 1016 assert(module); 1017 vector<const CodeModule*>::const_iterator iter; 1018 for (iter = modules->begin(); iter != modules->end(); ++iter) { 1019 if (module->debug_file().compare((*iter)->debug_file()) == 0 && 1020 module->debug_identifier().compare((*iter)->debug_identifier()) == 0) { 1021 return true; 1022 } 1023 } 1024 return false; 1025 } 1026 1027 // PrintModule prints a single |module| to stdout. 1028 // |modules_without_symbols| should contain the list of modules that were 1029 // confirmed to be missing their symbols during the stack walk. 1030 static void PrintModule( 1031 const CodeModule* module, 1032 const vector<const CodeModule*>* modules_without_symbols, 1033 const vector<const CodeModule*>* modules_with_corrupt_symbols, 1034 uint64_t main_address) { 1035 string symbol_issues; 1036 if (ContainsModule(modules_without_symbols, module)) { 1037 symbol_issues = " (WARNING: No symbols, " + 1038 PathnameStripper::File(module->debug_file()) + ", " + 1039 module->debug_identifier() + ")"; 1040 } else if (ContainsModule(modules_with_corrupt_symbols, module)) { 1041 symbol_issues = " (WARNING: Corrupt symbols, " + 1042 PathnameStripper::File(module->debug_file()) + ", " + 1043 module->debug_identifier() + ")"; 1044 } 1045 uint64_t base_address = module->base_address(); 1046 printf("0x%08" PRIx64 " - 0x%08" PRIx64 " %s %s%s%s\n", 1047 base_address, base_address + module->size() - 1, 1048 PathnameStripper::File(module->code_file()).c_str(), 1049 module->version().empty() ? "???" : module->version().c_str(), 1050 main_address != 0 && base_address == main_address ? " (main)" : "", 1051 symbol_issues.c_str()); 1052 } 1053 1054 // PrintModules prints the list of all loaded |modules| to stdout. 1055 // |modules_without_symbols| should contain the list of modules that were 1056 // confirmed to be missing their symbols during the stack walk. 1057 static void PrintModules( 1058 const CodeModules* modules, 1059 const vector<const CodeModule*>* modules_without_symbols, 1060 const vector<const CodeModule*>* modules_with_corrupt_symbols) { 1061 if (!modules) 1062 return; 1063 1064 printf("\n"); 1065 printf("Loaded modules:\n"); 1066 1067 uint64_t main_address = 0; 1068 const CodeModule* main_module = modules->GetMainModule(); 1069 if (main_module) { 1070 main_address = main_module->base_address(); 1071 } 1072 1073 unsigned int module_count = modules->module_count(); 1074 for (unsigned int module_sequence = 0; 1075 module_sequence < module_count; 1076 ++module_sequence) { 1077 const CodeModule* module = modules->GetModuleAtSequence(module_sequence); 1078 PrintModule(module, modules_without_symbols, modules_with_corrupt_symbols, 1079 main_address); 1080 } 1081 } 1082 1083 // PrintModulesMachineReadable outputs a list of loaded modules, 1084 // one per line, in the following machine-readable pipe-delimited 1085 // text format: 1086 // Module|{Module Filename}|{Version}|{Debug Filename}|{Debug Identifier}| 1087 // {Base Address}|{Max Address}|{Main} 1088 static void PrintModulesMachineReadable(const CodeModules* modules) { 1089 if (!modules) 1090 return; 1091 1092 uint64_t main_address = 0; 1093 const CodeModule* main_module = modules->GetMainModule(); 1094 if (main_module) { 1095 main_address = main_module->base_address(); 1096 } 1097 1098 unsigned int module_count = modules->module_count(); 1099 for (unsigned int module_sequence = 0; 1100 module_sequence < module_count; 1101 ++module_sequence) { 1102 const CodeModule* module = modules->GetModuleAtSequence(module_sequence); 1103 uint64_t base_address = module->base_address(); 1104 printf("Module%c%s%c%s%c%s%c%s%c0x%08" PRIx64 "%c0x%08" PRIx64 "%c%d\n", 1105 kOutputSeparator, 1106 StripSeparator(PathnameStripper::File(module->code_file())).c_str(), 1107 kOutputSeparator, StripSeparator(module->version()).c_str(), 1108 kOutputSeparator, 1109 StripSeparator(PathnameStripper::File(module->debug_file())).c_str(), 1110 kOutputSeparator, 1111 StripSeparator(module->debug_identifier()).c_str(), 1112 kOutputSeparator, base_address, 1113 kOutputSeparator, base_address + module->size() - 1, 1114 kOutputSeparator, 1115 main_module != NULL && base_address == main_address ? 1 : 0); 1116 } 1117 } 1118 1119 } // namespace 1120 1121 void PrintProcessState(const ProcessState& process_state, 1122 bool output_stack_contents, 1123 bool output_requesting_thread_only, 1124 SourceLineResolverInterface* resolver) { 1125 // Print OS and CPU information. 1126 string cpu = process_state.system_info()->cpu; 1127 string cpu_info = process_state.system_info()->cpu_info; 1128 printf("Operating system: %s\n", process_state.system_info()->os.c_str()); 1129 printf(" %s\n", 1130 process_state.system_info()->os_version.c_str()); 1131 printf("CPU: %s\n", cpu.c_str()); 1132 if (!cpu_info.empty()) { 1133 // This field is optional. 1134 printf(" %s\n", cpu_info.c_str()); 1135 } 1136 printf(" %d CPU%s\n", 1137 process_state.system_info()->cpu_count, 1138 process_state.system_info()->cpu_count != 1 ? "s" : ""); 1139 printf("\n"); 1140 1141 // Print GPU information 1142 string gl_version = process_state.system_info()->gl_version; 1143 string gl_vendor = process_state.system_info()->gl_vendor; 1144 string gl_renderer = process_state.system_info()->gl_renderer; 1145 printf("GPU:"); 1146 if (!gl_version.empty() || !gl_vendor.empty() || !gl_renderer.empty()) { 1147 printf(" %s\n", gl_version.c_str()); 1148 printf(" %s\n", gl_vendor.c_str()); 1149 printf(" %s\n", gl_renderer.c_str()); 1150 } else { 1151 printf(" UNKNOWN\n"); 1152 } 1153 printf("\n"); 1154 1155 // Print crash information. 1156 if (process_state.crashed()) { 1157 printf("Crash reason: %s\n", process_state.crash_reason().c_str()); 1158 printf("Crash address: 0x%" PRIx64 "\n", process_state.crash_address()); 1159 } else { 1160 printf("No crash\n"); 1161 } 1162 1163 string assertion = process_state.assertion(); 1164 if (!assertion.empty()) { 1165 printf("Assertion: %s\n", assertion.c_str()); 1166 } 1167 1168 // Compute process uptime if the process creation and crash times are 1169 // available in the dump. 1170 if (process_state.time_date_stamp() != 0 && 1171 process_state.process_create_time() != 0 && 1172 process_state.time_date_stamp() >= process_state.process_create_time()) { 1173 printf("Process uptime: %d seconds\n", 1174 process_state.time_date_stamp() - 1175 process_state.process_create_time()); 1176 } else { 1177 printf("Process uptime: not available\n"); 1178 } 1179 1180 // If the thread that requested the dump is known, print it first. 1181 int requesting_thread = process_state.requesting_thread(); 1182 if (requesting_thread != -1) { 1183 printf("\n"); 1184 printf("Thread %d (%s)\n", 1185 requesting_thread, 1186 process_state.crashed() ? "crashed" : 1187 "requested dump, did not crash"); 1188 PrintStack(process_state.threads()->at(requesting_thread), cpu, 1189 output_stack_contents, 1190 process_state.thread_memory_regions()->at(requesting_thread), 1191 process_state.modules(), resolver); 1192 } 1193 1194 if (!output_requesting_thread_only) { 1195 // Print all of the threads in the dump. 1196 int thread_count = process_state.threads()->size(); 1197 for (int thread_index = 0; thread_index < thread_count; ++thread_index) { 1198 if (thread_index != requesting_thread) { 1199 // Don't print the crash thread again, it was already printed. 1200 printf("\n"); 1201 printf("Thread %d\n", thread_index); 1202 PrintStack(process_state.threads()->at(thread_index), cpu, 1203 output_stack_contents, 1204 process_state.thread_memory_regions()->at(thread_index), 1205 process_state.modules(), resolver); 1206 } 1207 } 1208 } 1209 1210 PrintModules(process_state.modules(), 1211 process_state.modules_without_symbols(), 1212 process_state.modules_with_corrupt_symbols()); 1213 } 1214 1215 void PrintProcessStateMachineReadable(const ProcessState& process_state) { 1216 // Print OS and CPU information. 1217 // OS|{OS Name}|{OS Version} 1218 // CPU|{CPU Name}|{CPU Info}|{Number of CPUs} 1219 // GPU|{GPU version}|{GPU vendor}|{GPU renderer} 1220 printf("OS%c%s%c%s\n", kOutputSeparator, 1221 StripSeparator(process_state.system_info()->os).c_str(), 1222 kOutputSeparator, 1223 StripSeparator(process_state.system_info()->os_version).c_str()); 1224 printf("CPU%c%s%c%s%c%d\n", kOutputSeparator, 1225 StripSeparator(process_state.system_info()->cpu).c_str(), 1226 kOutputSeparator, 1227 // this may be empty 1228 StripSeparator(process_state.system_info()->cpu_info).c_str(), 1229 kOutputSeparator, 1230 process_state.system_info()->cpu_count); 1231 printf("GPU%c%s%c%s%c%s\n", kOutputSeparator, 1232 StripSeparator(process_state.system_info()->gl_version).c_str(), 1233 kOutputSeparator, 1234 StripSeparator(process_state.system_info()->gl_vendor).c_str(), 1235 kOutputSeparator, 1236 StripSeparator(process_state.system_info()->gl_renderer).c_str()); 1237 1238 int requesting_thread = process_state.requesting_thread(); 1239 1240 // Print crash information. 1241 // Crash|{Crash Reason}|{Crash Address}|{Crashed Thread} 1242 printf("Crash%c", kOutputSeparator); 1243 if (process_state.crashed()) { 1244 printf("%s%c0x%" PRIx64 "%c", 1245 StripSeparator(process_state.crash_reason()).c_str(), 1246 kOutputSeparator, process_state.crash_address(), kOutputSeparator); 1247 } else { 1248 // print assertion info, if available, in place of crash reason, 1249 // instead of the unhelpful "No crash" 1250 string assertion = process_state.assertion(); 1251 if (!assertion.empty()) { 1252 printf("%s%c%c", StripSeparator(assertion).c_str(), 1253 kOutputSeparator, kOutputSeparator); 1254 } else { 1255 printf("No crash%c%c", kOutputSeparator, kOutputSeparator); 1256 } 1257 } 1258 1259 if (requesting_thread != -1) { 1260 printf("%d\n", requesting_thread); 1261 } else { 1262 printf("\n"); 1263 } 1264 1265 PrintModulesMachineReadable(process_state.modules()); 1266 1267 // blank line to indicate start of threads 1268 printf("\n"); 1269 1270 // If the thread that requested the dump is known, print it first. 1271 if (requesting_thread != -1) { 1272 PrintStackMachineReadable(requesting_thread, 1273 process_state.threads()->at(requesting_thread)); 1274 } 1275 1276 // Print all of the threads in the dump. 1277 int thread_count = process_state.threads()->size(); 1278 for (int thread_index = 0; thread_index < thread_count; ++thread_index) { 1279 if (thread_index != requesting_thread) { 1280 // Don't print the crash thread again, it was already printed. 1281 PrintStackMachineReadable(thread_index, 1282 process_state.threads()->at(thread_index)); 1283 } 1284 } 1285 } 1286 1287 void PrintRequestingThreadBrief(const ProcessState& process_state) { 1288 int requesting_thread = process_state.requesting_thread(); 1289 if (requesting_thread == -1) { 1290 printf(" <no crashing or requesting dump thread identified>\n"); 1291 return; 1292 } 1293 1294 printf("Thread %d (%s)\n", requesting_thread, 1295 process_state.crashed() ? "crashed" : "requested dump, did not crash"); 1296 const CallStack* stack = process_state.threads()->at(requesting_thread); 1297 int frame_count = stack->frames()->size(); 1298 for (int frame_index = 0; frame_index < frame_count; ++frame_index) { 1299 PrintFrameHeader(stack->frames()->at(frame_index), frame_index); 1300 printf("\n"); 1301 } 1302 } 1303 1304 } // namespace google_breakpad