diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp @@ -26,12 +26,17 @@ InternalScopedString frame_desc(GetPageSizeCached() * 2); InternalScopedString dedup_token(GetPageSizeCached()); int dedup_frames = common_flags()->dedup_token_length; + bool symbolize = RenderNeedsSymbolization(common_flags()->stack_trace_format); uptr frame_num = 0; for (uptr i = 0; i < size && trace[i]; i++) { // PCs in stack traces are actually the return addresses, that is, // addresses of the next instructions after the call. uptr pc = GetPreviousInstructionPc(trace[i]); - SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(pc); + SymbolizedStack *frames; + if (symbolize) + frames = Symbolizer::GetOrInit()->SymbolizePC(pc); + else + frames = SymbolizedStack::New(pc); CHECK(frames); for (SymbolizedStack *cur = frames; cur; cur = cur->next) { frame_desc.clear(); @@ -108,7 +113,11 @@ uptr out_buf_size) { if (!out_buf_size) return; pc = StackTrace::GetPreviousInstructionPc(pc); - SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc); + SymbolizedStack *frame; + if (RenderNeedsSymbolization(fmt)) + frame = Symbolizer::GetOrInit()->SymbolizePC(pc); + else + frame = SymbolizedStack::New(pc); if (!frame) { internal_strncpy(out_buf, "", out_buf_size); out_buf[out_buf_size - 1] = 0; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h @@ -51,6 +51,8 @@ const char *strip_path_prefix = "", const char *strip_func_prefix = ""); +bool RenderNeedsSymbolization(const char *format); + void RenderSourceLocation(InternalScopedString *buffer, const char *file, int line, int column, bool vs_style, const char *strip_path_prefix); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp @@ -200,6 +200,29 @@ } } +bool RenderNeedsSymbolization(const char *format) { + if (0 == internal_strcmp(format, "DEFAULT")) + format = kDefaultFormat; + for (const char *p = format; *p != '\0'; p++) { + if (*p != '%') + continue; + p++; + switch (*p) { + case '%': + break; + case 'n': + // frame_no + break; + case 'p': + // address + break; + default: + return true; + } + } + return false; +} + void RenderData(InternalScopedString *buffer, const char *format, const DataInfo *DI, const char *strip_path_prefix) { for (const char *p = format; *p != '\0'; p++) { diff --git a/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace.cpp b/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace.cpp --- a/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace.cpp @@ -2,6 +2,7 @@ // RUN: %clangxx -O3 %s -o %t && %env_tool_opts=stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s // RUN: %env_tool_opts=stack_trace_format=frame%n_lineno%l %run %t 2>&1 | FileCheck %s --check-prefix=CUSTOM // RUN: %env_tool_opts=symbolize_inline_frames=false:stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s --check-prefix=NOINLINE +// RUN: %env_tool_opts=stack_trace_format='"frame:%n address:%%p"' %run %t 2>&1 | FileCheck %s --check-prefix=NOSYMBOLIZE // UNSUPPORTED: darwin @@ -27,3 +28,7 @@ // NOINLINE: #0 0x{{.*}} in __sanitizer_print_stack_trace // NOINLINE: #1 0x{{.*}} in main{{.*}}print-stack-trace.cpp:[[@LINE-15]] + +// NOSYMBOLIZE: frame:0 address:{{0x.*}} +// NOSYMBOLIZE: frame:1 address:{{0x.*}} +// NOSYMBOLIZE: frame:2 address:{{0x.*}}