1 //===-- sanitizer_stacktrace_libcdep.cc -----------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is shared between AddressSanitizer and ThreadSanitizer 11 // run-time libraries. 12 //===----------------------------------------------------------------------===// 13 14 #include "sanitizer_common.h" 15 #include "sanitizer_placement_new.h" 16 #include "sanitizer_stacktrace.h" 17 #include "sanitizer_stacktrace_printer.h" 18 #include "sanitizer_symbolizer.h" 19 20 namespace __sanitizer { 21 22 void StackTrace::Print() const { 23 if (trace == nullptr || size == 0) { 24 Printf(" <empty stack>\n\n"); 25 return; 26 } 27 InternalScopedString frame_desc(GetPageSizeCached() * 2); 28 uptr frame_num = 0; 29 for (uptr i = 0; i < size && trace[i]; i++) { 30 // PCs in stack traces are actually the return addresses, that is, 31 // addresses of the next instructions after the call. 32 uptr pc = GetPreviousInstructionPc(trace[i]); 33 SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(pc); 34 CHECK(frames); 35 for (SymbolizedStack *cur = frames; cur; cur = cur->next) { 36 frame_desc.clear(); 37 RenderFrame(&frame_desc, common_flags()->stack_trace_format, frame_num++, 38 cur->info, common_flags()->symbolize_vs_style, 39 common_flags()->strip_path_prefix); 40 Printf("%s\n", frame_desc.data()); 41 } 42 frames->ClearAll(); 43 } 44 // Always print a trailing empty line after stack trace. 45 Printf("\n"); 46 } 47 48 void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context, 49 uptr stack_top, uptr stack_bottom, 50 bool request_fast_unwind) { 51 top_frame_bp = (max_depth > 0) ? bp : 0; 52 // Avoid doing any work for small max_depth. 53 if (max_depth == 0) { 54 size = 0; 55 return; 56 } 57 if (max_depth == 1) { 58 size = 1; 59 trace_buffer[0] = pc; 60 return; 61 } 62 if (!WillUseFastUnwind(request_fast_unwind)) { 63 #if SANITIZER_CAN_SLOW_UNWIND 64 if (context) 65 SlowUnwindStackWithContext(pc, context, max_depth); 66 else 67 SlowUnwindStack(pc, max_depth); 68 #else 69 UNREACHABLE("slow unwind requested but not available"); 70 #endif 71 } else { 72 FastUnwindStack(pc, bp, stack_top, stack_bottom, max_depth); 73 } 74 } 75 76 } // namespace __sanitizer 77