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
PrintRegister(const char * name,uint32_t value,int start_col)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.
PrintRegister64(const char * name,uint64_t value,int start_col)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.
StripSeparator(const string & original)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.
PrintStackContents(const string & indent,const StackFrame * frame,const StackFrame * prev_frame,const string & cpu,const MemoryRegion * memory,const CodeModules * modules,SourceLineResolverInterface * resolver)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
PrintFrameHeader(const StackFrame * frame,int frame_index)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.
PrintStack(const CallStack * stack,const string & cpu,bool output_stack_contents,const MemoryRegion * memory,const CodeModules * modules,SourceLineResolverInterface * resolver)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.
PrintStackMachineReadable(int thread_num,const CallStack * stack)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|.
ContainsModule(const vector<const CodeModule * > * modules,const CodeModule * module)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.
PrintModule(const CodeModule * module,const vector<const CodeModule * > * modules_without_symbols,const vector<const CodeModule * > * modules_with_corrupt_symbols,uint64_t main_address)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.
PrintModules(const CodeModules * modules,const vector<const CodeModule * > * modules_without_symbols,const vector<const CodeModule * > * modules_with_corrupt_symbols)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}
PrintModulesMachineReadable(const CodeModules * modules)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
PrintProcessState(const ProcessState & process_state,bool output_stack_contents,bool output_requesting_thread_only,SourceLineResolverInterface * resolver)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
PrintProcessStateMachineReadable(const ProcessState & process_state)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
PrintRequestingThreadBrief(const ProcessState & process_state)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
1305