<div dir="ltr">Excellent! <div>Don't forget to document this :) </div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Nov 6, 2014 at 10:43 AM, Alexey Samsonov <span dir="ltr"><<a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: samsonov<br>
Date: Thu Nov  6 12:43:45 2014<br>
New Revision: 221469<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=221469&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=221469&view=rev</a><br>
Log:<br>
[Sanitizer] Introduce "stack_trace_format" runtime flag.<br>
<br>
This flag can be used to specify the format of stack frames - user<br>
can now provide a string with placeholders, which should be printed<br>
for each stack frame with placeholders replaced with actual data.<br>
For example "%p" will be replaced by PC, "%s" will be replaced by<br>
the source file name etc.<br>
<br>
"DEFAULT" value enforces default stack trace format currently used in<br>
all the sanitizers except TSan.<br>
<br>
This change also implements __sanitizer_print_stack_trace interface<br>
function in TSan.<br>
<br>
Modified:<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc<br>
    compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc<br>
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc<br>
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h<br>
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc<br>
    compiler-rt/trunk/test/sanitizer_common/TestCases/print-stack-trace.cc<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc?rev=221469&r1=221468&r2=221469&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc?rev=221469&r1=221468&r2=221469&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc Thu Nov  6 12:43:45 2014<br>
@@ -68,6 +68,7 @@ void SetCommonFlagsDefaults(CommonFlags<br>
   f->print_suppressions = true;<br>
   f->disable_coredump = (SANITIZER_WORDSIZE == 64);<br>
   f->symbolize_inline_frames = true;<br>
+  f->stack_trace_format = "DEFAULT";<br>
 }<br>
<br>
 void ParseCommonFlagsFromString(CommonFlags *f, const char *str) {<br>
@@ -161,6 +162,10 @@ void ParseCommonFlagsFromString(CommonFl<br>
       "default and for sanitizers that don't reserve lots of virtual memory.");<br>
   ParseFlag(str, &f->symbolize_inline_frames, "symbolize_inline_frames",<br>
             "Print inlined frames in stacktraces. Defaults to true.");<br>
+  ParseFlag(str, &f->stack_trace_format, "stack_trace_format",<br>
+            "Format string used to render stack frames. "<br>
+            "See sanitizer_stacktrace_printer.h for the format description. "<br>
+            "Use DEFAULT to get default format.");<br>
<br>
   // Do a sanity check for certain flags.<br>
   if (f->malloc_context_size < 1)<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h?rev=221469&r1=221468&r2=221469&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h?rev=221469&r1=221468&r2=221469&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h Thu Nov  6 12:43:45 2014<br>
@@ -62,6 +62,7 @@ struct CommonFlags {<br>
   bool print_suppressions;<br>
   bool disable_coredump;<br>
   bool symbolize_inline_frames;<br>
+  const char *stack_trace_format;<br>
 };<br>
<br>
 inline CommonFlags *common_flags() {<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc?rev=221469&r1=221468&r2=221469&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc?rev=221469&r1=221468&r2=221469&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc Thu Nov  6 12:43:45 2014<br>
@@ -43,8 +43,8 @@ void StackTrace::Print() const {<br>
     for (uptr j = 0; j < addr_frames_num; j++) {<br>
       AddressInfo &info = addr_frames[j];<br>
       frame_desc.clear();<br>
-      RenderFrame(&frame_desc, "DEFAULT", frame_num++, info,<br>
-                  common_flags()->strip_path_prefix);<br>
+      RenderFrame(&frame_desc, common_flags()->stack_trace_format, frame_num++,<br>
+                  info, common_flags()->strip_path_prefix);<br>
       Printf("%s\n", frame_desc.data());<br>
       info.Clear();<br>
     }<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc?rev=221469&r1=221468&r2=221469&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc?rev=221469&r1=221468&r2=221469&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc Thu Nov  6 12:43:45 2014<br>
@@ -99,6 +99,7 @@ void InitializeFlags(Flags *f, const cha<br>
   cf->allow_addr2line = true;<br>
   cf->detect_deadlocks = true;<br>
   cf->print_suppressions = false;<br>
+  cf->stack_trace_format = "    #%n %f %S %M";<br>
<br>
   // Let a frontend override.<br>
   ParseFlags(f, __tsan_default_options());<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=221469&r1=221468&r2=221469&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=221469&r1=221468&r2=221469&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc Thu Nov  6 12:43:45 2014<br>
@@ -118,9 +118,9 @@ void PrintStack(const ReportStack *ent)<br>
     Printf("    [failed to restore the stack]\n\n");<br>
     return;<br>
   }<br>
-  for (int i = 0; ent; ent = ent->next, i++) {<br>
+  for (int i = 0; ent && ent->info.address; ent = ent->next, i++) {<br>
     InternalScopedString res(2 * GetPageSizeCached());<br>
-    RenderFrame(&res, "    #%n %f %S %M", i, ent->info,<br>
+    RenderFrame(&res, common_flags()->stack_trace_format, i, ent->info,<br>
                 common_flags()->strip_path_prefix, "__interceptor_");<br>
     Printf("%s\n", res.data());<br>
   }<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=221469&r1=221468&r2=221469&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=221469&r1=221468&r2=221469&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Thu Nov  6 12:43:45 2014<br>
@@ -586,7 +586,7 @@ ReportStack *SkipTsanInternalFrames(Repo<br>
 u32 CurrentStackId(ThreadState *thr, uptr pc);<br>
 ReportStack *SymbolizeStackId(u32 stack_id);<br>
 void PrintCurrentStack(ThreadState *thr, uptr pc);<br>
-void PrintCurrentStackSlow();  // uses libunwind<br>
+void PrintCurrentStackSlow(uptr pc);  // uses libunwind<br>
<br>
 void Initialize(ThreadState *thr);<br>
 int Finalize(ThreadState *thr);<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=221469&r1=221468&r2=221469&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=221469&r1=221468&r2=221469&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc Thu Nov  6 12:43:45 2014<br>
@@ -41,7 +41,7 @@ void TsanCheckFailed(const char *file, i<br>
   Printf("FATAL: ThreadSanitizer CHECK failed: "<br>
          "%s:%d \"%s\" (0x%zx, 0x%zx)\n",<br>
          file, line, cond, (uptr)v1, (uptr)v2);<br>
-  PrintCurrentStackSlow();<br>
+  PrintCurrentStackSlow(StackTrace::GetCurrentPc());<br>
   Die();<br>
 }<br>
<br>
@@ -668,12 +668,12 @@ void PrintCurrentStack(ThreadState *thr,<br>
   PrintStack(SymbolizeStack(trace));<br>
 }<br>
<br>
-void PrintCurrentStackSlow() {<br>
+void PrintCurrentStackSlow(uptr pc) {<br>
 #ifndef TSAN_GO<br>
   BufferedStackTrace *ptrace =<br>
       new(internal_alloc(MBlockStackTrace, sizeof(BufferedStackTrace)))<br>
           BufferedStackTrace();<br>
-  ptrace->Unwind(kStackTraceMax, StackTrace::GetCurrentPc(), 0, 0, 0, 0, false);<br>
+  ptrace->Unwind(kStackTraceMax, pc, 0, 0, 0, 0, false);<br>
   for (uptr i = 0; i < ptrace->size / 2; i++) {<br>
     uptr tmp = ptrace->trace_buffer[i];<br>
     ptrace->trace_buffer[i] = ptrace->trace_buffer[ptrace->size - i - 1];<br>
@@ -684,3 +684,12 @@ void PrintCurrentStackSlow() {<br>
 }<br>
<br>
 }  // namespace __tsan<br>
+<br>
+using namespace __tsan;<br>
+<br>
+extern "C" {<br>
+SANITIZER_INTERFACE_ATTRIBUTE<br>
+void __sanitizer_print_stack_trace() {<br>
+  PrintCurrentStackSlow(StackTrace::GetCurrentPc());<br>
+}<br>
+}  // extern "C"<br>
<br>
Modified: compiler-rt/trunk/test/sanitizer_common/TestCases/print-stack-trace.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/print-stack-trace.cc?rev=221469&r1=221468&r2=221469&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/print-stack-trace.cc?rev=221469&r1=221468&r2=221469&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/test/sanitizer_common/TestCases/print-stack-trace.cc (original)<br>
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/print-stack-trace.cc Thu Nov  6 12:43:45 2014<br>
@@ -1,10 +1,7 @@<br>
-// RUN: %clangxx -O0 %s -o %t && %run %t 2>&1 | FileCheck %s<br>
-// RUN: %clangxx -O3 %s -o %t && %run %t 2>&1 | FileCheck %s<br>
-// RUN: %tool_options=symbolize_inline_frames=false %run %t 2>&1 | FileCheck %s --check-prefix=NOINLINE<br>
-<br>
-// Not yet implemented for TSan.<br>
-// <a href="https://code.google.com/p/address-sanitizer/issues/detail?id=243" target="_blank">https://code.google.com/p/address-sanitizer/issues/detail?id=243</a><br>
-// XFAIL: tsan<br>
+// RUN: %clangxx -O0 %s -o %t && %tool_options=stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s<br>
+// RUN: %clangxx -O3 %s -o %t && %tool_options=stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s<br>
+// RUN: %tool_options='stack_trace_format="frame:%n lineno:%l"' %run %t 2>&1 | FileCheck %s --check-prefix=CUSTOM<br>
+// RUN: %tool_options=symbolize_inline_frames=false:stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s --check-prefix=NOINLINE<br>
<br>
 #include <sanitizer/common_interface_defs.h><br>
<br>
@@ -17,8 +14,11 @@ int main() {<br>
   return 0;<br>
 }<br>
 // CHECK: {{    #0 0x.* in __sanitizer_print_stack_trace}}<br>
-// CHECK: {{    #1 0x.* in FooBarBaz(\(\))? .*print-stack-trace.cc:12}}<br>
-// CHECK: {{    #2 0x.* in main.*print-stack-trace.cc:16}}<br>
+// CHECK: {{    #1 0x.* in FooBarBaz(\(\))? .*print-stack-trace.cc:9}}<br>
+// CHECK: {{    #2 0x.* in main.*print-stack-trace.cc:13}}<br>
+<br>
+// CUSTOM: frame:1 lineno:9<br>
+// CUSTOM: frame:2 lineno:13<br>
<br>
 // NOINLINE: #0 0x{{.*}} in __sanitizer_print_stack_trace<br>
-// NOINLINE: #1 0x{{.*}} in main{{.*}}print-stack-trace.cc:12<br>
+// NOINLINE: #1 0x{{.*}} in main{{.*}}print-stack-trace.cc:9<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>