[compiler-rt] r223145 - Simplify Symbolizer::SymbolizePC() interface.

Alexey Samsonov vonosmas at gmail.com
Tue Dec 2 11:48:40 PST 2014


Author: samsonov
Date: Tue Dec  2 13:48:40 2014
New Revision: 223145

URL: http://llvm.org/viewvc/llvm-project?rev=223145&view=rev
Log:
Simplify Symbolizer::SymbolizePC() interface.

Return a linked list of AddressInfo objects, instead of using an array of
these objects as an output parameter. This simplifies the code in callers
of this function (especially TSan).

Fix a few memory leaks from internal allocator, when the returned
AddressInfo objects were not properly cleared.

Modified:
    compiler-rt/trunk/lib/lsan/lsan_common.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc
    compiler-rt/trunk/lib/tsan/go/buildgo.sh
    compiler-rt/trunk/lib/tsan/go/tsan_go.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.h
    compiler-rt/trunk/lib/ubsan/ubsan_diag.cc

Modified: compiler-rt/trunk/lib/lsan/lsan_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_common.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_common.cc Tue Dec  2 13:48:40 2014
@@ -457,30 +457,27 @@ void DoLeakCheck() {
 }
 
 static Suppression *GetSuppressionForAddr(uptr addr) {
-  Suppression *s;
+  Suppression *s = nullptr;
 
   // Suppress by module name.
   const char *module_name;
   uptr module_offset;
-  if (Symbolizer::GetOrInit()
-          ->GetModuleNameAndOffsetForPC(addr, &module_name, &module_offset) &&
+  if (Symbolizer::GetOrInit()->GetModuleNameAndOffsetForPC(addr, &module_name,
+                                                           &module_offset) &&
       SuppressionContext::Get()->Match(module_name, SuppressionLeak, &s))
     return s;
 
   // Suppress by file or function name.
-  static const uptr kMaxAddrFrames = 16;
-  InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames);
-  for (uptr i = 0; i < kMaxAddrFrames; i++) new (&addr_frames[i]) AddressInfo();
-  uptr addr_frames_num = Symbolizer::GetOrInit()->SymbolizePC(
-      addr, addr_frames.data(), kMaxAddrFrames);
-  for (uptr i = 0; i < addr_frames_num; i++) {
-    if (SuppressionContext::Get()->Match(addr_frames[i].function,
-                                         SuppressionLeak, &s) ||
-        SuppressionContext::Get()->Match(addr_frames[i].file, SuppressionLeak,
-                                         &s))
-      return s;
+  SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(addr);
+  for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
+    if (SuppressionContext::Get()->Match(cur->info.function, SuppressionLeak,
+                                         &s) ||
+        SuppressionContext::Get()->Match(cur->info.file, SuppressionLeak, &s)) {
+      break;
+    }
   }
-  return 0;
+  frames->ClearAll();
+  return s;
 }
 
 static Suppression *GetSuppressionForStack(u32 stack_trace_id) {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc Tue Dec  2 13:48:40 2014
@@ -52,16 +52,20 @@ void SetSandboxingCallback(void (*f)())
 void ReportErrorSummary(const char *error_type, StackTrace *stack) {
   if (!common_flags()->print_summary)
     return;
-  AddressInfo ai;
 #if !SANITIZER_GO
   if (stack->size > 0 && Symbolizer::GetOrInit()->CanReturnFileLineInfo()) {
     // Currently, we include the first stack frame into the report summary.
     // Maybe sometimes we need to choose another frame (e.g. skip memcpy/etc).
     uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);
-    Symbolizer::GetOrInit()->SymbolizePC(pc, &ai, 1);
+    SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc);
+    const AddressInfo &ai = frame->info;
+    ReportErrorSummary(error_type, ai.file, ai.line, ai.function);
+    frame->ClearAll();
   }
-#endif
+#else
+  AddressInfo ai;
   ReportErrorSummary(error_type, ai.file, ai.line, ai.function);
+#endif
 }
 
 }  // namespace __sanitizer

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc Tue Dec  2 13:48:40 2014
@@ -24,30 +24,21 @@ void StackTrace::Print() const {
     Printf("    <empty stack>\n\n");
     return;
   }
-  const int kMaxAddrFrames = 64;
-  InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames);
-  for (uptr i = 0; i < kMaxAddrFrames; i++)
-    new(&addr_frames[i]) AddressInfo();
   InternalScopedString frame_desc(GetPageSizeCached() * 2);
   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]);
-    uptr addr_frames_num = Symbolizer::GetOrInit()->SymbolizePC(
-        pc, addr_frames.data(), kMaxAddrFrames);
-    if (addr_frames_num == 0) {
-      addr_frames[0].address = pc;
-      addr_frames_num = 1;
-    }
-    for (uptr j = 0; j < addr_frames_num; j++) {
-      AddressInfo &info = addr_frames[j];
+    SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(pc);
+    CHECK(frames);
+    for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
       frame_desc.clear();
       RenderFrame(&frame_desc, common_flags()->stack_trace_format, frame_num++,
-                  info, common_flags()->strip_path_prefix);
+                  cur->info, common_flags()->strip_path_prefix);
       Printf("%s\n", frame_desc.data());
-      info.Clear();
     }
+    frames->ClearAll();
   }
   // Always print a trailing empty line after stack trace.
   Printf("\n");

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc Tue Dec  2 13:48:40 2014
@@ -11,13 +11,61 @@
 // run-time libraries.
 //===----------------------------------------------------------------------===//
 
+#include "sanitizer_allocator_internal.h"
 #include "sanitizer_platform.h"
 #include "sanitizer_internal_defs.h"
+#include "sanitizer_libc.h"
 #include "sanitizer_placement_new.h"
 #include "sanitizer_symbolizer.h"
 
 namespace __sanitizer {
 
+AddressInfo::AddressInfo() {
+  internal_memset(this, 0, sizeof(AddressInfo));
+  function_offset = kUnknown;
+}
+
+void AddressInfo::Clear() {
+  InternalFree(module);
+  InternalFree(function);
+  InternalFree(file);
+  internal_memset(this, 0, sizeof(AddressInfo));
+  function_offset = kUnknown;
+}
+
+void AddressInfo::FillAddressAndModuleInfo(uptr addr, const char *mod_name,
+                                           uptr mod_offset) {
+  address = addr;
+  module = internal_strdup(mod_name);
+  module_offset = mod_offset;
+}
+
+SymbolizedStack::SymbolizedStack() : next(nullptr), info() {}
+
+SymbolizedStack *SymbolizedStack::New(uptr addr) {
+  void *mem = InternalAlloc(sizeof(SymbolizedStack));
+  SymbolizedStack *res = new(mem) SymbolizedStack();
+  res->info.address = addr;
+  return res;
+}
+
+void SymbolizedStack::ClearAll() {
+  info.Clear();
+  if (next)
+    next->ClearAll();
+  InternalFree(this);
+}
+
+DataInfo::DataInfo() {
+  internal_memset(this, 0, sizeof(DataInfo));
+}
+
+void DataInfo::Clear() {
+  InternalFree(module);
+  InternalFree(name);
+  internal_memset(this, 0, sizeof(DataInfo));
+}
+
 Symbolizer *Symbolizer::symbolizer_;
 StaticSpinMutex Symbolizer::init_mu_;
 LowLevelAllocator Symbolizer::symbolizer_allocator_;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h Tue Dec  2 13:48:40 2014
@@ -19,13 +19,14 @@
 #ifndef SANITIZER_SYMBOLIZER_H
 #define SANITIZER_SYMBOLIZER_H
 
-#include "sanitizer_allocator_internal.h"
-#include "sanitizer_internal_defs.h"
-#include "sanitizer_libc.h"
+#include "sanitizer_common.h"
+#include "sanitizer_mutex.h"
 
 namespace __sanitizer {
 
 struct AddressInfo {
+  // Owns all the string members. Storage for them is
+  // (de)allocated using sanitizer internal allocator.
   uptr address;
 
   char *module;
@@ -39,45 +40,38 @@ struct AddressInfo {
   int line;
   int column;
 
-  AddressInfo() {
-    internal_memset(this, 0, sizeof(AddressInfo));
-    function_offset = kUnknown;
-  }
-
+  AddressInfo();
   // Deletes all strings and resets all fields.
-  void Clear() {
-    InternalFree(module);
-    InternalFree(function);
-    InternalFree(file);
-    internal_memset(this, 0, sizeof(AddressInfo));
-    function_offset = kUnknown;
-  }
-
+  void Clear();
   void FillAddressAndModuleInfo(uptr addr, const char *mod_name,
-                                uptr mod_offset) {
-    address = addr;
-    module = internal_strdup(mod_name);
-    module_offset = mod_offset;
-  }
+                                uptr mod_offset);
+};
+
+// Linked list of symbolized frames (each frame is described by AddressInfo).
+struct SymbolizedStack {
+  SymbolizedStack *next;
+  AddressInfo info;
+  static SymbolizedStack *New(uptr addr);
+  // Deletes current, and all subsequent frames in the linked list.
+  // The object cannot be accessed after the call to this function.
+  void ClearAll();
+
+ private:
+  SymbolizedStack();
 };
 
 // For now, DataInfo is used to describe global variable.
 struct DataInfo {
+  // Owns all the string members. Storage for them is
+  // (de)allocated using sanitizer internal allocator.
   char *module;
   uptr module_offset;
   char *name;
   uptr start;
   uptr size;
 
-  DataInfo() {
-    internal_memset(this, 0, sizeof(DataInfo));
-  }
-
-  void Clear() {
-    InternalFree(module);
-    InternalFree(name);
-    internal_memset(this, 0, sizeof(DataInfo));
-  }
+  DataInfo();
+  void Clear();
 };
 
 class Symbolizer {
@@ -85,11 +79,10 @@ class Symbolizer {
   /// Initialize and return platform-specific implementation of symbolizer
   /// (if it wasn't already initialized).
   static Symbolizer *GetOrInit();
-  // Fills at most "max_frames" elements of "frames" with descriptions
-  // for a given address (in all inlined functions). Returns the number
-  // of descriptions actually filled.
-  virtual uptr SymbolizePC(uptr address, AddressInfo *frames, uptr max_frames) {
-    return 0;
+  // Returns a list of symbolized frames for a given address (containing
+  // all inlined functions, if necessary).
+  virtual SymbolizedStack *SymbolizePC(uptr address) {
+    return SymbolizedStack::New(address);
   }
   virtual bool SymbolizeData(uptr address, DataInfo *info) {
     return false;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc Tue Dec  2 13:48:40 2014
@@ -83,44 +83,52 @@ char *CplusV3Demangle(const char *name)
 }
 # endif  // SANITIZER_CP_DEMANGLE
 
-struct SymbolizeCodeData {
-  AddressInfo *frames;
-  uptr n_frames;
-  uptr max_frames;
+struct SymbolizeCodeCallbackArg {
+  SymbolizedStack *first;
+  SymbolizedStack *last;
   const char *module_name;
   uptr module_offset;
+
+  void append(SymbolizedStack *f) {
+    if (last != nullptr) {
+      last->next = f;
+      last = f;
+    } else {
+      first = f;
+      last = f;
+    }
+  }
 };
 
 extern "C" {
 static int SymbolizeCodePCInfoCallback(void *vdata, uintptr_t addr,
                                        const char *filename, int lineno,
                                        const char *function) {
-  SymbolizeCodeData *cdata = (SymbolizeCodeData *)vdata;
+  SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata;
   if (function) {
-    AddressInfo *info = &cdata->frames[cdata->n_frames++];
-    info->Clear();
+    SymbolizedStack *cur = SymbolizedStack::New(addr);
+    cdata->append(cur);
+    AddressInfo *info = &cur->info;
     info->FillAddressAndModuleInfo(addr, cdata->module_name,
                                    cdata->module_offset);
     info->function = LibbacktraceSymbolizer::Demangle(function, true);
     if (filename)
       info->file = internal_strdup(filename);
     info->line = lineno;
-    if (cdata->n_frames == cdata->max_frames)
-      return 1;
   }
   return 0;
 }
 
 static void SymbolizeCodeCallback(void *vdata, uintptr_t addr,
                                   const char *symname, uintptr_t, uintptr_t) {
-  SymbolizeCodeData *cdata = (SymbolizeCodeData *)vdata;
+  SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata;
   if (symname) {
-    AddressInfo *info = &cdata->frames[0];
-    info->Clear();
+    SymbolizedStack *cur = SymbolizedStack::New(addr);
+    cdata->append(cur);
+    AddressInfo *info = &cur->info;
     info->FillAddressAndModuleInfo(addr, cdata->module_name,
                                    cdata->module_offset);
     info->function = LibbacktraceSymbolizer::Demangle(symname, true);
-    cdata->n_frames = 1;
   }
 }
 
@@ -148,23 +156,21 @@ LibbacktraceSymbolizer *LibbacktraceSymb
   return new(*alloc) LibbacktraceSymbolizer(state);
 }
 
-uptr LibbacktraceSymbolizer::SymbolizeCode(uptr addr, AddressInfo *frames,
-                                           uptr max_frames,
-                                           const char *module_name,
-                                           uptr module_offset) {
-  SymbolizeCodeData data;
-  data.frames = frames;
-  data.n_frames = 0;
-  data.max_frames = max_frames;
+SymbolizedStack *LibbacktraceSymbolizer::SymbolizeCode(uptr addr,
+                                                       const char *module_name,
+                                                       uptr module_offset) {
+  SymbolizeCodeCallbackArg data;
+  data.first = nullptr;
+  data.last = nullptr;
   data.module_name = module_name;
   data.module_offset = module_offset;
   backtrace_pcinfo((backtrace_state *)state_, addr, SymbolizeCodePCInfoCallback,
                    ErrorCallback, &data);
-  if (data.n_frames)
-    return data.n_frames;
+  if (data.first)
+    return data.first;
   backtrace_syminfo((backtrace_state *)state_, addr, SymbolizeCodeCallback,
                     ErrorCallback, &data);
-  return data.n_frames;
+  return data.first;
 }
 
 bool LibbacktraceSymbolizer::SymbolizeData(DataInfo *info) {
@@ -179,12 +185,11 @@ LibbacktraceSymbolizer *LibbacktraceSymb
   return 0;
 }
 
-uptr LibbacktraceSymbolizer::SymbolizeCode(uptr addr, AddressInfo *frames,
-                                           uptr max_frames,
-                                           const char *module_name,
-                                           uptr module_offset) {
+SymbolizedStack *LibbacktraceSymbolizer::SymbolizeCode(uptr addr,
+                                                       const char *module_name,
+                                                       uptr module_offset) {
   (void)state_;
-  return 0;
+  return nullptr;
 }
 
 bool LibbacktraceSymbolizer::SymbolizeData(DataInfo *info) {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h Tue Dec  2 13:48:40 2014
@@ -32,8 +32,8 @@ class LibbacktraceSymbolizer {
  public:
   static LibbacktraceSymbolizer *get(LowLevelAllocator *alloc);
 
-  uptr SymbolizeCode(uptr addr, AddressInfo *frames, uptr max_frames,
-                     const char *module_name, uptr module_offset);
+  SymbolizedStack *SymbolizeCode(uptr addr, const char *module_name,
+                                 uptr module_offset);
 
   bool SymbolizeData(DataInfo *info);
 

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc Tue Dec  2 13:48:40 2014
@@ -514,34 +514,32 @@ class POSIXSymbolizer : public Symbolize
         internal_symbolizer_(internal_symbolizer),
         libbacktrace_symbolizer_(libbacktrace_symbolizer) {}
 
-  uptr SymbolizePC(uptr addr, AddressInfo *frames, uptr max_frames) override {
+  SymbolizedStack *SymbolizePC(uptr addr) override {
     BlockingMutexLock l(&mu_);
-    if (max_frames == 0)
-      return 0;
     const char *module_name;
     uptr module_offset;
     if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset))
-      return 0;
+      return SymbolizedStack::New(addr);
     // First, try to use libbacktrace symbolizer (if it's available).
     if (libbacktrace_symbolizer_ != 0) {
       mu_.CheckLocked();
-      uptr res = libbacktrace_symbolizer_->SymbolizeCode(
-          addr, frames, max_frames, module_name, module_offset);
-      if (res > 0)
+      if (SymbolizedStack *res = libbacktrace_symbolizer_->SymbolizeCode(
+              addr, module_name, module_offset))
         return res;
     }
+    // Always fill data about module name and offset.
+    SymbolizedStack *res = SymbolizedStack::New(addr);
+    res->info.FillAddressAndModuleInfo(addr, module_name, module_offset);
+
     const char *str = SendCommand(false, module_name, module_offset);
     if (str == 0) {
-      // Symbolizer was not initialized or failed. Fill only data
-      // about module name and offset.
-      AddressInfo *info = &frames[0];
-      info->Clear();
-      info->FillAddressAndModuleInfo(addr, module_name, module_offset);
-      return 1;
+      // Symbolizer was not initialized or failed.
+      return res;
     }
-    uptr frame_id = 0;
-    for (frame_id = 0; frame_id < max_frames; frame_id++) {
-      AddressInfo *info = &frames[frame_id];
+
+    bool top_frame = true;
+    SymbolizedStack *last = res;
+    while (true) {
       char *function_name = 0;
       str = ExtractToken(str, "\n", &function_name);
       CHECK(function_name);
@@ -549,8 +547,18 @@ class POSIXSymbolizer : public Symbolize
         // There are no more frames.
         break;
       }
-      info->Clear();
-      info->FillAddressAndModuleInfo(addr, module_name, module_offset);
+      SymbolizedStack *cur;
+      if (top_frame) {
+        cur = res;
+        top_frame = false;
+      } else {
+        cur = SymbolizedStack::New(addr);
+        cur->info.FillAddressAndModuleInfo(addr, module_name, module_offset);
+        last->next = cur;
+        last = cur;
+      }
+
+      AddressInfo *info = &cur->info;
       info->function = function_name;
       // Parse <file>:<line>:<column> buffer.
       char *file_line_info = 0;
@@ -572,14 +580,7 @@ class POSIXSymbolizer : public Symbolize
         info->file = 0;
       }
     }
-    if (frame_id == 0) {
-      // Make sure we return at least one frame.
-      AddressInfo *info = &frames[0];
-      info->Clear();
-      info->FillAddressAndModuleInfo(addr, module_name, module_offset);
-      frame_id = 1;
-    }
-    return frame_id;
+    return res;
   }
 
   bool SymbolizeData(uptr addr, DataInfo *info) override {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc Tue Dec  2 13:48:40 2014
@@ -26,9 +26,8 @@ class WinSymbolizer : public Symbolizer
  public:
   WinSymbolizer() : initialized_(false) {}
 
-  uptr SymbolizePC(uptr addr, AddressInfo *frames, uptr max_frames) override {
-    if (max_frames == 0)
-      return 0;
+  SymbolizedStack *SymbolizePC(uptr addr) override {
+    SymbolizedStack *frame = SymbolizedStack::New(addr);
 
     BlockingMutexLock l(&dbghelp_mu_);
     if (!initialized_) {
@@ -60,29 +59,27 @@ class WinSymbolizer : public Symbolizer
     BOOL got_objname = SymFromAddr(GetCurrentProcess(),
                                    (DWORD64)addr, &offset, symbol);
     if (!got_objname)
-      return 0;
+      return frame;
 
     DWORD unused;
     IMAGEHLP_LINE64 line_info;
     line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
     BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(), (DWORD64)addr,
                                              &unused, &line_info);
-    AddressInfo *info = &frames[0];
-    info->Clear();
-    info->function = internal_strdup(symbol->Name);
-    info->function_offset = (uptr)offset;
+    frame->info.function = internal_strdup(symbol->Name);
+    frame->info.function_offset = (uptr)offset;
     if (got_fileline) {
-      info->file = internal_strdup(line_info.FileName);
-      info->line = line_info.LineNumber;
+      frame->info.file = internal_strdup(line_info.FileName);
+      frame->info.line = line_info.LineNumber;
     }
 
     IMAGEHLP_MODULE64 mod_info;
     internal_memset(&mod_info, 0, sizeof(mod_info));
     mod_info.SizeOfStruct = sizeof(mod_info);
     if (SymGetModuleInfo64(GetCurrentProcess(), addr, &mod_info))
-      info->FillAddressAndModuleInfo(addr, mod_info.ImageName,
-                                     addr - (uptr)mod_info.BaseOfImage);
-    return 1;
+      frame->info.FillAddressAndModuleInfo(addr, mod_info.ImageName,
+                                           addr - (uptr)mod_info.BaseOfImage);
+    return frame;
   }
 
   bool CanReturnFileLineInfo() override {

Modified: compiler-rt/trunk/lib/tsan/go/buildgo.sh
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/go/buildgo.sh?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/go/buildgo.sh (original)
+++ compiler-rt/trunk/lib/tsan/go/buildgo.sh Tue Dec  2 13:48:40 2014
@@ -27,6 +27,7 @@ SRCS="
 	../../sanitizer_common/sanitizer_thread_registry.cc
 	../../sanitizer_common/sanitizer_stackdepot.cc
 	../../sanitizer_common/sanitizer_stacktrace.cc
+	../../sanitizer_common/sanitizer_symbolizer.cc
 "
 
 if [ "`uname -a | grep Linux`" != "" ]; then

Modified: compiler-rt/trunk/lib/tsan/go/tsan_go.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/go/tsan_go.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/go/tsan_go.cc (original)
+++ compiler-rt/trunk/lib/tsan/go/tsan_go.cc Tue Dec  2 13:48:40 2014
@@ -59,18 +59,19 @@ struct SymbolizeContext {
 // Callback into Go.
 static void (*symbolize_cb)(SymbolizeContext *ctx);
 
-ReportStack *SymbolizeCode(uptr addr) {
-  ReportStack *s = ReportStack::New(addr);
+SymbolizedStack *SymbolizeCode(uptr addr) {
+  SymbolizedStack *s = SymbolizedStack::New(addr);
   SymbolizeContext ctx;
   internal_memset(&ctx, 0, sizeof(ctx));
   ctx.pc = addr;
   symbolize_cb(&ctx);
   if (ctx.res) {
-    s->info.module_offset = ctx.off;
-    s->info.function = internal_strdup(ctx.func ? ctx.func : "??");
-    s->info.file = internal_strdup(ctx.file ? ctx.file : "-");
-    s->info.line = ctx.line;
-    s->info.column = 0;
+    AddressInfo &info = s->info;
+    info.module_offset = ctx.off;
+    info.function = internal_strdup(ctx.func ? ctx.func : "??");
+    info.file = internal_strdup(ctx.file ? ctx.file : "-");
+    info.line = ctx.line;
+    info.column = 0;
   }
   return s;
 }

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc Tue Dec  2 13:48:40 2014
@@ -19,13 +19,11 @@
 
 namespace __tsan {
 
-ReportStack::ReportStack() : next(nullptr), info(), suppressable(false) {}
+ReportStack::ReportStack() : frames(nullptr), suppressable(false) {}
 
-ReportStack *ReportStack::New(uptr addr) {
+ReportStack *ReportStack::New() {
   void *mem = internal_alloc(MBlockReportStack, sizeof(ReportStack));
-  ReportStack *res = new(mem) ReportStack();
-  res->info.address = addr;
-  return res;
+  return new(mem) ReportStack();
 }
 
 ReportLocation::ReportLocation(ReportLocationType type)
@@ -114,13 +112,14 @@ static const char *ReportTypeString(Repo
 }
 
 void PrintStack(const ReportStack *ent) {
-  if (ent == 0) {
+  if (ent == 0 || ent->frames == 0) {
     Printf("    [failed to restore the stack]\n\n");
     return;
   }
-  for (int i = 0; ent && ent->info.address; ent = ent->next, i++) {
+  SymbolizedStack *frame = ent->frames;
+  for (int i = 0; frame && frame->info.address; frame = frame->next, i++) {
     InternalScopedString res(2 * GetPageSizeCached());
-    RenderFrame(&res, common_flags()->stack_trace_format, i, ent->info,
+    RenderFrame(&res, common_flags()->stack_trace_format, i, frame->info,
                 common_flags()->strip_path_prefix, "__interceptor_");
     Printf("%s\n", res.data());
   }
@@ -252,10 +251,20 @@ static ReportStack *ChooseSummaryStack(c
   return 0;
 }
 
-ReportStack *SkipTsanInternalFrames(ReportStack *ent) {
-  while (FrameIsInternal(ent) && ent->next)
-    ent = ent->next;
-  return ent;
+static bool FrameIsInternal(const SymbolizedStack *frame) {
+  if (frame == 0)
+    return false;
+  const char *file = frame->info.file;
+  return file != 0 &&
+         (internal_strstr(file, "tsan_interceptors.cc") ||
+          internal_strstr(file, "sanitizer_common_interceptors.inc") ||
+          internal_strstr(file, "tsan_interface_"));
+}
+
+static SymbolizedStack *SkipTsanInternalFrames(SymbolizedStack *frames) {
+  while (FrameIsInternal(frames) && frames->next)
+    frames = frames->next;
+  return frames;
 }
 
 void PrintReport(const ReportDesc *rep) {
@@ -325,9 +334,11 @@ void PrintReport(const ReportDesc *rep)
   if (rep->typ == ReportTypeThreadLeak && rep->count > 1)
     Printf("  And %d more similar thread leaks.\n\n", rep->count - 1);
 
-  if (ReportStack *ent = SkipTsanInternalFrames(ChooseSummaryStack(rep))) {
-    const AddressInfo &info = ent->info;
-    ReportErrorSummary(rep_typ_str, info.file, info.line, info.function);
+  if (ReportStack *stack = ChooseSummaryStack(rep)) {
+    if (SymbolizedStack *frame = SkipTsanInternalFrames(stack->frames)) {
+      const AddressInfo &info = frame->info;
+      ReportErrorSummary(rep_typ_str, info.file, info.line, info.function);
+    }
   }
 
   Printf("==================\n");
@@ -338,12 +349,13 @@ void PrintReport(const ReportDesc *rep)
 const int kMainThreadId = 1;
 
 void PrintStack(const ReportStack *ent) {
-  if (ent == 0) {
+  if (ent == 0 || ent->frames == 0) {
     Printf("  [failed to restore the stack]\n");
     return;
   }
-  for (int i = 0; ent; ent = ent->next, i++) {
-    const AddressInfo &info = ent->info;
+  SymbolizedStack *frame = ent->frames;
+  for (int i = 0; frame; frame = frame->next, i++) {
+    const AddressInfo &info = frame->info;
     Printf("  %s()\n      %s:%d +0x%zx\n", info.function, info.file, info.line,
            (void *)info.module_offset);
   }

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.h?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.h Tue Dec  2 13:48:40 2014
@@ -36,10 +36,9 @@ enum ReportType {
 };
 
 struct ReportStack {
-  ReportStack *next;
-  AddressInfo info;
+  SymbolizedStack *frames;
   bool suppressable;
-  static ReportStack *New(uptr addr);
+  static ReportStack *New();
 
  private:
   ReportStack();

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Tue Dec  2 13:48:40 2014
@@ -568,8 +568,6 @@ bool IsFiredSuppression(Context *ctx, co
                         StackTrace trace);
 bool IsExpectedReport(uptr addr, uptr size);
 void PrintMatchedBenignRaces();
-bool FrameIsInternal(const ReportStack *frame);
-ReportStack *SkipTsanInternalFrames(ReportStack *ent);
 
 #if defined(TSAN_DEBUG_OUTPUT) && TSAN_DEBUG_OUTPUT >= 1
 # define DPrintf Printf

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc Tue Dec  2 13:48:40 2014
@@ -56,40 +56,43 @@ bool WEAK OnReport(const ReportDesc *rep
 }
 #endif
 
-static void StackStripMain(ReportStack *stack) {
-  ReportStack *last_frame = 0;
-  ReportStack *last_frame2 = 0;
-  for (ReportStack *ent = stack; ent; ent = ent->next) {
+static void StackStripMain(SymbolizedStack *frames) {
+  SymbolizedStack *last_frame = nullptr;
+  SymbolizedStack *last_frame2 = nullptr;
+  for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
     last_frame2 = last_frame;
-    last_frame = ent;
+    last_frame = cur;
   }
 
   if (last_frame2 == 0)
     return;
-  const char *last = last_frame->info.function;
 #ifndef TSAN_GO
+  const char *last = last_frame->info.function;
   const char *last2 = last_frame2->info.function;
   // Strip frame above 'main'
   if (last2 && 0 == internal_strcmp(last2, "main")) {
-    last_frame2->next = 0;
+    last_frame->ClearAll();
+    last_frame2->next = nullptr;
   // Strip our internal thread start routine.
   } else if (last && 0 == internal_strcmp(last, "__tsan_thread_start_func")) {
-    last_frame2->next = 0;
+    last_frame->ClearAll();
+    last_frame2->next = nullptr;
   // Strip global ctors init.
   } else if (last && 0 == internal_strcmp(last, "__do_global_ctors_aux")) {
-    last_frame2->next = 0;
+    last_frame->ClearAll();
+    last_frame2->next = nullptr;
   // If both are 0, then we probably just failed to symbolize.
   } else if (last || last2) {
     // Ensure that we recovered stack completely. Trimmed stack
     // can actually happen if we do not instrument some code,
     // so it's only a debug print. However we must try hard to not miss it
     // due to our fault.
-    DPrintf("Bottom stack frame of stack %zx is missed\n", stack->pc);
+    DPrintf("Bottom stack frame of stack %zx is missed\n", stack->info.address);
   }
 #else
   // The last frame always point into runtime (gosched0, goexit0, runtime.main).
-  last_frame2->next = 0;
-  (void)last;
+  last_frame->ClearAll();
+  last_frame2->next = nullptr;
 #endif
 }
 
@@ -105,12 +108,12 @@ ReportStack *SymbolizeStackId(u32 stack_
 static ReportStack *SymbolizeStack(StackTrace trace) {
   if (trace.size == 0)
     return 0;
-  ReportStack *stack = 0;
+  SymbolizedStack *top = nullptr;
   for (uptr si = 0; si < trace.size; si++) {
     const uptr pc = trace.trace[si];
 #ifndef TSAN_GO
-    // We obtain the return address, that is, address of the next instruction,
-    // so offset it by 1 byte.
+    // We obtain the return address, but we're interested in the previous
+    // instruction.
     const uptr pc1 = StackTrace::GetPreviousInstructionPc(pc);
 #else
     // FIXME(dvyukov): Go sometimes uses address of a function as top pc.
@@ -118,18 +121,21 @@ static ReportStack *SymbolizeStack(Stack
     if (si != trace.size - 1)
       pc1 -= 1;
 #endif
-    ReportStack *ent = SymbolizeCode(pc1);
+    SymbolizedStack *ent = SymbolizeCode(pc1);
     CHECK_NE(ent, 0);
-    ReportStack *last = ent;
+    SymbolizedStack *last = ent;
     while (last->next) {
       last->info.address = pc;  // restore original pc for report
       last = last->next;
     }
     last->info.address = pc;  // restore original pc for report
-    last->next = stack;
-    stack = ent;
+    last->next = top;
+    top = ent;
   }
-  StackStripMain(stack);
+  StackStripMain(top);
+
+  ReportStack *stack = ReportStack::New();
+  stack->frames = top;
   return stack;
 }
 
@@ -547,16 +553,6 @@ static bool IsFiredSuppression(Context *
   return false;
 }
 
-bool FrameIsInternal(const ReportStack *frame) {
-  if (frame == 0)
-    return false;
-  const char *file = frame->info.file;
-  return file != 0 &&
-         (internal_strstr(file, "tsan_interceptors.cc") ||
-          internal_strstr(file, "sanitizer_common_interceptors.inc") ||
-          internal_strstr(file, "tsan_interface_"));
-}
-
 static bool RaceBetweenAtomicAndFree(ThreadState *thr) {
   Shadow s0(thr->racy_state[0]);
   Shadow s1(thr->racy_state[1]);

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc Tue Dec  2 13:48:40 2014
@@ -92,7 +92,8 @@ uptr IsSuppressed(ReportType typ, const
   if (stype == SuppressionNone)
     return 0;
   Suppression *s;
-  for (const ReportStack *frame = stack; frame; frame = frame->next) {
+  for (const SymbolizedStack *frame = stack->frames; frame;
+       frame = frame->next) {
     const AddressInfo &info = frame->info;
     if (SuppressionContext::Get()->Match(info.function, stype, &s) ||
         SuppressionContext::Get()->Match(info.file, stype, &s) ||

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.cc Tue Dec  2 13:48:40 2014
@@ -55,7 +55,7 @@ bool __tsan_symbolize_external(uptr pc,
   return false;
 }
 
-ReportStack *SymbolizeCode(uptr addr) {
+SymbolizedStack *SymbolizeCode(uptr addr) {
   // Check if PC comes from non-native land.
   if (addr & kExternalPCBit) {
     // Declare static to not consume too much stack space.
@@ -63,36 +63,17 @@ ReportStack *SymbolizeCode(uptr addr) {
     static char func_buf[1024];
     static char file_buf[1024];
     int line, col;
-    ReportStack *ent = ReportStack::New(addr);
-    if (!__tsan_symbolize_external(addr, func_buf, sizeof(func_buf),
-                                  file_buf, sizeof(file_buf), &line, &col))
-      return ent;
-    ent->info.function = internal_strdup(func_buf);
-    ent->info.file = internal_strdup(file_buf);
-    ent->info.line = line;
-    ent->info.column = col;
-    return ent;
+    SymbolizedStack *frame = SymbolizedStack::New(addr);
+    if (__tsan_symbolize_external(addr, func_buf, sizeof(func_buf), file_buf,
+                                  sizeof(file_buf), &line, &col)) {
+      frame->info.function = internal_strdup(func_buf);
+      frame->info.file = internal_strdup(file_buf);
+      frame->info.line = line;
+      frame->info.column = col;
+    }
+    return frame;
   }
-  static const uptr kMaxAddrFrames = 16;
-  InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames);
-  for (uptr i = 0; i < kMaxAddrFrames; i++)
-    new(&addr_frames[i]) AddressInfo();
-  uptr addr_frames_num = Symbolizer::GetOrInit()->SymbolizePC(
-      addr, addr_frames.data(), kMaxAddrFrames);
-  if (addr_frames_num == 0)
-    return ReportStack::New(addr);
-  ReportStack *top = 0;
-  ReportStack *bottom = 0;
-  for (uptr i = 0; i < addr_frames_num; i++) {
-    ReportStack *cur_entry = ReportStack::New(addr);
-    cur_entry->info = addr_frames[i];
-    if (i == 0)
-      top = cur_entry;
-    else
-      bottom->next = cur_entry;
-    bottom = cur_entry;
-  }
-  return top;
+  return Symbolizer::GetOrInit()->SymbolizePC(addr);
 }
 
 ReportLocation *SymbolizeData(uptr addr) {

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.h?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.h Tue Dec  2 13:48:40 2014
@@ -20,7 +20,7 @@ namespace __tsan {
 
 void EnterSymbolizer();
 void ExitSymbolizer();
-ReportStack *SymbolizeCode(uptr addr);
+SymbolizedStack *SymbolizeCode(uptr addr);
 ReportLocation *SymbolizeData(uptr addr);
 void SymbolizeFlush();
 

Modified: compiler-rt/trunk/lib/ubsan/ubsan_diag.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_diag.cc?rev=223145&r1=223144&r2=223145&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_diag.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_diag.cc Tue Dec  2 13:48:40 2014
@@ -79,18 +79,26 @@ Location __ubsan::getFunctionLocation(up
     return Location();
   InitIfNecessary();
 
-  AddressInfo Info;
-  if (!Symbolizer::GetOrInit()->SymbolizePC(Loc, &Info, 1) || !Info.module ||
-      !*Info.module)
+  SymbolizedStack *Frames = Symbolizer::GetOrInit()->SymbolizePC(Loc);
+  const AddressInfo &Info = Frames->info;
+
+  if (!Info.module) {
+    Frames->ClearAll();
     return Location(Loc);
+  }
 
   if (FName && Info.function)
-    *FName = Info.function;
+    *FName = internal_strdup(Info.function);
 
-  if (!Info.file)
-    return ModuleLocation(Info.module, Info.module_offset);
+  if (!Info.file) {
+    ModuleLocation MLoc(internal_strdup(Info.module), Info.module_offset);
+    Frames->ClearAll();
+    return MLoc;
+  }
 
-  return SourceLocation(Info.file, Info.line, Info.column);
+  SourceLocation SLoc(internal_strdup(Info.file), Info.line, Info.column);
+  Frames->ClearAll();
+  return SLoc;
 }
 
 Diag &Diag::operator<<(const TypeDescriptor &V) {





More information about the llvm-commits mailing list