<div dir="ltr">Hi Alexey!<div><br></div><div>This still has a memory leak: (ubsan_diag.cc)</div><div><span style="font-size:12.8000001907349px">+  if (!Info.file) {</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">+  Â  ModuleLocation MLoc(internal_strdup(Info.</span><span style="font-size:12.8000001907349px">module), Info.module_offset);</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">+  Â  Frames->ClearAll();</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">+  Â  return MLoc;</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">+  }</span><br></div><div><span style="font-size:12.8000001907349px">^^ You're doing an strdup, but later the ModuleLocation only gets used to feed a Location, which is only used when Diag calls renderLocation. After that, it gets leaked away.</span></div><div><br></div><div>One could fix this by making SourceLoc, ModuleLoc, and MemoryLoc, inside class Location (ubsan_diag.h) pointers, and clear the objects in the Location destructor.</div><div>If you're ok with this let me know and I can submit the patch, otherwise, can you fix it?</div><div>(I'm not sure about the uses in tsan and other sanitizers, so I don't know if they also leak)</div><div><br></div><div>Thanks,</div><div><div class="gmail_extra"><br clear="all"><div><div>  Filipe<br></div></div>
<br><div class="gmail_quote">On Tue, Dec 2, 2014 at 11:48 AM, Alexey Samsonov <span dir="ltr"><<a href="javascript:_e(%7B%7D,'cvml','vonosmas@gmail.com');" target="_blank">vonosmas@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: samsonov<br>
Date: Tue Dec  2 13:48:40 2014<br>
New Revision: 223145<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=223145&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=223145&view=rev</a><br>
Log:<br>
Simplify Symbolizer::SymbolizePC() interface.<br>
<br>
Return a linked list of AddressInfo objects, instead of using an array of<br>
these objects as an output parameter. This simplifies the code in callers<br>
of this function (especially TSan).<br>
<br>
Fix a few memory leaks from internal allocator, when the returned<br>
AddressInfo objects were not properly cleared.<br>
<br>
Modified:<br>
  Â  compiler-rt/trunk/lib/lsan/lsan_common.cc<br>
  Â  compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc<br>
  Â  compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc<br>
  Â  compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc<br>
  Â  compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h<br>
  Â  compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc<br>
  Â  compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h<br>
  Â  compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc<br>
  Â  compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc<br>
  Â  compiler-rt/trunk/lib/tsan/go/buildgo.sh<br>
  Â  compiler-rt/trunk/lib/tsan/go/tsan_go.cc<br>
  Â  compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc<br>
  Â  compiler-rt/trunk/lib/tsan/rtl/tsan_report.h<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/lib/tsan/rtl/tsan_suppressions.cc<br>
  Â  compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.cc<br>
  Â  compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.h<br>
  Â  compiler-rt/trunk/lib/ubsan/ubsan_diag.cc<br>
<br>
Modified: compiler-rt/trunk/lib/lsan/lsan_common.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.cc?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.cc?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/lsan/lsan_common.cc (original)<br>
+++ compiler-rt/trunk/lib/lsan/lsan_common.cc Tue Dec  2 13:48:40 2014<br>
@@ -457,30 +457,27 @@ void DoLeakCheck() {<br>
 }<br>
<br>
 static Suppression *GetSuppressionForAddr(uptr addr) {<br>
-  Suppression *s;<br>
+  Suppression *s = nullptr;<br>
<br>
  Â // Suppress by module name.<br>
  Â const char *module_name;<br>
  Â uptr module_offset;<br>
-  if (Symbolizer::GetOrInit()<br>
-  Â  Â  Â  Â  ->GetModuleNameAndOffsetForPC(addr, &module_name, &module_offset) &&<br>
+  if (Symbolizer::GetOrInit()->GetModuleNameAndOffsetForPC(addr, &module_name,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â &module_offset) &&<br>
  Â  Â  Â SuppressionContext::Get()->Match(module_name, SuppressionLeak, &s))<br>
  Â  Â return s;<br>
<br>
  Â // Suppress by file or function name.<br>
-  static const uptr kMaxAddrFrames = 16;<br>
-  InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames);<br>
-  for (uptr i = 0; i < kMaxAddrFrames; i++) new (&addr_frames[i]) AddressInfo();<br>
-  uptr addr_frames_num = Symbolizer::GetOrInit()->SymbolizePC(<br>
-  Â  Â  addr, addr_frames.data(), kMaxAddrFrames);<br>
-  for (uptr i = 0; i < addr_frames_num; i++) {<br>
-  Â  if (SuppressionContext::Get()->Match(addr_frames[i].function,<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â SuppressionLeak, &s) ||<br>
-  Â  Â  Â  SuppressionContext::Get()->Match(addr_frames[i].file, SuppressionLeak,<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â &s))<br>
-  Â  Â  return s;<br>
+  SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(addr);<br>
+  for (SymbolizedStack *cur = frames; cur; cur = cur->next) {<br>
+  Â  if (SuppressionContext::Get()->Match(cur->info.function, SuppressionLeak,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â &s) ||<br>
+  Â  Â  Â  SuppressionContext::Get()->Match(cur->info.file, SuppressionLeak, &s)) {<br>
+  Â  Â  break;<br>
+  Â  }<br>
  Â }<br>
-  return 0;<br>
+  frames->ClearAll();<br>
+  return s;<br>
 }<br>
<br>
 static Suppression *GetSuppressionForStack(u32 stack_trace_id) {<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc Tue Dec  2 13:48:40 2014<br>
@@ -52,16 +52,20 @@ void SetSandboxingCallback(void (*f)())<br>
 void ReportErrorSummary(const char *error_type, StackTrace *stack) {<br>
  Â if (!common_flags()->print_summary)<br>
  Â  Â return;<br>
-  AddressInfo ai;<br>
 #if !SANITIZER_GO<br>
  Â if (stack->size > 0 && Symbolizer::GetOrInit()->CanReturnFileLineInfo()) {<br>
  Â  Â // Currently, we include the first stack frame into the report summary.<br>
  Â  Â // Maybe sometimes we need to choose another frame (e.g. skip memcpy/etc).<br>
  Â  Â uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);<br>
-  Â  Symbolizer::GetOrInit()->SymbolizePC(pc, &ai, 1);<br>
+  Â  SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc);<br>
+  Â  const AddressInfo &ai = frame->info;<br>
+  Â  ReportErrorSummary(error_type, ai.file, ai.line, ai.function);<br>
+  Â  frame->ClearAll();<br>
  Â }<br>
-#endif<br>
+#else<br>
+  AddressInfo ai;<br>
  Â ReportErrorSummary(error_type, ai.file, ai.line, ai.function);<br>
+#endif<br>
 }<br>
<br>
 }  // namespace __sanitizer<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=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc?rev=223145&r1=223144&r2=223145&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 Tue Dec  2 13:48:40 2014<br>
@@ -24,30 +24,21 @@ void StackTrace::Print() const {<br>
  Â  Â Printf("  Â  <empty stack>\n\n");<br>
  Â  Â return;<br>
  Â }<br>
-  const int kMaxAddrFrames = 64;<br>
-  InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames);<br>
-  for (uptr i = 0; i < kMaxAddrFrames; i++)<br>
-  Â  new(&addr_frames[i]) AddressInfo();<br>
  Â InternalScopedString frame_desc(GetPageSizeCached() * 2);<br>
  Â uptr frame_num = 0;<br>
  Â for (uptr i = 0; i < size && trace[i]; i++) {<br>
  Â  Â // PCs in stack traces are actually the return addresses, that is,<br>
  Â  Â // addresses of the next instructions after the call.<br>
  Â  Â uptr pc = GetPreviousInstructionPc(trace[i]);<br>
-  Â  uptr addr_frames_num = Symbolizer::GetOrInit()->SymbolizePC(<br>
-  Â  Â  Â  pc, addr_frames.data(), kMaxAddrFrames);<br>
-  Â  if (addr_frames_num == 0) {<br>
-  Â  Â  addr_frames[0].address = pc;<br>
-  Â  Â  addr_frames_num = 1;<br>
-  Â  }<br>
-  Â  for (uptr j = 0; j < addr_frames_num; j++) {<br>
-  Â  Â  AddressInfo &info = addr_frames[j];<br>
+  Â  SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(pc);<br>
+  Â  CHECK(frames);<br>
+  Â  for (SymbolizedStack *cur = frames; cur; cur = cur->next) {<br>
  Â  Â  Â frame_desc.clear();<br>
  Â  Â  Â RenderFrame(&frame_desc, common_flags()->stack_trace_format, frame_num++,<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  info, common_flags()->strip_path_prefix);<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  cur->info, common_flags()->strip_path_prefix);<br>
  Â  Â  Â Printf("%s\n", frame_desc.data());<br>
-  Â  Â  info.Clear();<br>
  Â  Â }<br>
+  Â  frames->ClearAll();<br>
  Â }<br>
  Â // Always print a trailing empty line after stack trace.<br>
  Â Printf("\n");<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc Tue Dec  2 13:48:40 2014<br>
@@ -11,13 +11,61 @@<br>
 // run-time libraries.<br>
 //===----------------------------------------------------------------------===//<br>
<br>
+#include "sanitizer_allocator_internal.h"<br>
 #include "sanitizer_platform.h"<br>
 #include "sanitizer_internal_defs.h"<br>
+#include "sanitizer_libc.h"<br>
 #include "sanitizer_placement_new.h"<br>
 #include "sanitizer_symbolizer.h"<br>
<br>
 namespace __sanitizer {<br>
<br>
+AddressInfo::AddressInfo() {<br>
+  internal_memset(this, 0, sizeof(AddressInfo));<br>
+  function_offset = kUnknown;<br>
+}<br>
+<br>
+void AddressInfo::Clear() {<br>
+  InternalFree(module);<br>
+  InternalFree(function);<br>
+  InternalFree(file);<br>
+  internal_memset(this, 0, sizeof(AddressInfo));<br>
+  function_offset = kUnknown;<br>
+}<br>
+<br>
+void AddressInfo::FillAddressAndModuleInfo(uptr addr, const char *mod_name,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â uptr mod_offset) {<br>
+  address = addr;<br>
+  module = internal_strdup(mod_name);<br>
+  module_offset = mod_offset;<br>
+}<br>
+<br>
+SymbolizedStack::SymbolizedStack() : next(nullptr), info() {}<br>
+<br>
+SymbolizedStack *SymbolizedStack::New(uptr addr) {<br>
+  void *mem = InternalAlloc(sizeof(SymbolizedStack));<br>
+  SymbolizedStack *res = new(mem) SymbolizedStack();<br>
+  res->info.address = addr;<br>
+  return res;<br>
+}<br>
+<br>
+void SymbolizedStack::ClearAll() {<br>
+  info.Clear();<br>
+  if (next)<br>
+  Â  next->ClearAll();<br>
+  InternalFree(this);<br>
+}<br>
+<br>
+DataInfo::DataInfo() {<br>
+  internal_memset(this, 0, sizeof(DataInfo));<br>
+}<br>
+<br>
+void DataInfo::Clear() {<br>
+  InternalFree(module);<br>
+  InternalFree(name);<br>
+  internal_memset(this, 0, sizeof(DataInfo));<br>
+}<br>
+<br>
 Symbolizer *Symbolizer::symbolizer_;<br>
 StaticSpinMutex Symbolizer::init_mu_;<br>
 LowLevelAllocator Symbolizer::symbolizer_allocator_;<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h Tue Dec  2 13:48:40 2014<br>
@@ -19,13 +19,14 @@<br>
 #ifndef SANITIZER_SYMBOLIZER_H<br>
 #define SANITIZER_SYMBOLIZER_H<br>
<br>
-#include "sanitizer_allocator_internal.h"<br>
-#include "sanitizer_internal_defs.h"<br>
-#include "sanitizer_libc.h"<br>
+#include "sanitizer_common.h"<br>
+#include "sanitizer_mutex.h"<br>
<br>
 namespace __sanitizer {<br>
<br>
 struct AddressInfo {<br>
+  // Owns all the string members. Storage for them is<br>
+  // (de)allocated using sanitizer internal allocator.<br>
  Â uptr address;<br>
<br>
  Â char *module;<br>
@@ -39,45 +40,38 @@ struct AddressInfo {<br>
  Â int line;<br>
  Â int column;<br>
<br>
-  AddressInfo() {<br>
-  Â  internal_memset(this, 0, sizeof(AddressInfo));<br>
-  Â  function_offset = kUnknown;<br>
-  }<br>
-<br>
+  AddressInfo();<br>
  Â // Deletes all strings and resets all fields.<br>
-  void Clear() {<br>
-  Â  InternalFree(module);<br>
-  Â  InternalFree(function);<br>
-  Â  InternalFree(file);<br>
-  Â  internal_memset(this, 0, sizeof(AddressInfo));<br>
-  Â  function_offset = kUnknown;<br>
-  }<br>
-<br>
+  void Clear();<br>
  Â void FillAddressAndModuleInfo(uptr addr, const char *mod_name,<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  uptr mod_offset) {<br>
-  Â  address = addr;<br>
-  Â  module = internal_strdup(mod_name);<br>
-  Â  module_offset = mod_offset;<br>
-  }<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  uptr mod_offset);<br>
+};<br>
+<br>
+// Linked list of symbolized frames (each frame is described by AddressInfo).<br>
+struct SymbolizedStack {<br>
+  SymbolizedStack *next;<br>
+  AddressInfo info;<br>
+  static SymbolizedStack *New(uptr addr);<br>
+  // Deletes current, and all subsequent frames in the linked list.<br>
+  // The object cannot be accessed after the call to this function.<br>
+  void ClearAll();<br>
+<br>
+ private:<br>
+  SymbolizedStack();<br>
 };<br>
<br>
 // For now, DataInfo is used to describe global variable.<br>
 struct DataInfo {<br>
+  // Owns all the string members. Storage for them is<br>
+  // (de)allocated using sanitizer internal allocator.<br>
  Â char *module;<br>
  Â uptr module_offset;<br>
  Â char *name;<br>
  Â uptr start;<br>
  Â uptr size;<br>
<br>
-  DataInfo() {<br>
-  Â  internal_memset(this, 0, sizeof(DataInfo));<br>
-  }<br>
-<br>
-  void Clear() {<br>
-  Â  InternalFree(module);<br>
-  Â  InternalFree(name);<br>
-  Â  internal_memset(this, 0, sizeof(DataInfo));<br>
-  }<br>
+  DataInfo();<br>
+  void Clear();<br>
 };<br>
<br>
 class Symbolizer {<br>
@@ -85,11 +79,10 @@ class Symbolizer {<br>
  Â /// Initialize and return platform-specific implementation of symbolizer<br>
  Â /// (if it wasn't already initialized).<br>
  Â static Symbolizer *GetOrInit();<br>
-  // Fills at most "max_frames" elements of "frames" with descriptions<br>
-  // for a given address (in all inlined functions). Returns the number<br>
-  // of descriptions actually filled.<br>
-  virtual uptr SymbolizePC(uptr address, AddressInfo *frames, uptr max_frames) {<br>
-  Â  return 0;<br>
+  // Returns a list of symbolized frames for a given address (containing<br>
+  // all inlined functions, if necessary).<br>
+  virtual SymbolizedStack *SymbolizePC(uptr address) {<br>
+  Â  return SymbolizedStack::New(address);<br>
  Â }<br>
  Â virtual bool SymbolizeData(uptr address, DataInfo *info) {<br>
  Â  Â return false;<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc Tue Dec  2 13:48:40 2014<br>
@@ -83,44 +83,52 @@ char *CplusV3Demangle(const char *name)<br>
 }<br>
 # endif  // SANITIZER_CP_DEMANGLE<br>
<br>
-struct SymbolizeCodeData {<br>
-  AddressInfo *frames;<br>
-  uptr n_frames;<br>
-  uptr max_frames;<br>
+struct SymbolizeCodeCallbackArg {<br>
+  SymbolizedStack *first;<br>
+  SymbolizedStack *last;<br>
  Â const char *module_name;<br>
  Â uptr module_offset;<br>
+<br>
+  void append(SymbolizedStack *f) {<br>
+  Â  if (last != nullptr) {<br>
+  Â  Â  last->next = f;<br>
+  Â  Â  last = f;<br>
+  Â  } else {<br>
+  Â  Â  first = f;<br>
+  Â  Â  last = f;<br>
+  Â  }<br>
+  }<br>
 };<br>
<br>
 extern "C" {<br>
 static int SymbolizeCodePCInfoCallback(void *vdata, uintptr_t addr,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  const char *filename, int lineno,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  const char *function) {<br>
-  SymbolizeCodeData *cdata = (SymbolizeCodeData *)vdata;<br>
+  SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata;<br>
  Â if (function) {<br>
-  Â  AddressInfo *info = &cdata->frames[cdata->n_frames++];<br>
-  Â  info->Clear();<br>
+  Â  SymbolizedStack *cur = SymbolizedStack::New(addr);<br>
+  Â  cdata->append(cur);<br>
+  Â  AddressInfo *info = &cur->info;<br>
  Â  Â info->FillAddressAndModuleInfo(addr, cdata->module_name,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  cdata->module_offset);<br>
  Â  Â info->function = LibbacktraceSymbolizer::Demangle(function, true);<br>
  Â  Â if (filename)<br>
  Â  Â  Â info->file = internal_strdup(filename);<br>
  Â  Â info->line = lineno;<br>
-  Â  if (cdata->n_frames == cdata->max_frames)<br>
-  Â  Â  return 1;<br>
  Â }<br>
  Â return 0;<br>
 }<br>
<br>
 static void SymbolizeCodeCallback(void *vdata, uintptr_t addr,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â const char *symname, uintptr_t, uintptr_t) {<br>
-  SymbolizeCodeData *cdata = (SymbolizeCodeData *)vdata;<br>
+  SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata;<br>
  Â if (symname) {<br>
-  Â  AddressInfo *info = &cdata->frames[0];<br>
-  Â  info->Clear();<br>
+  Â  SymbolizedStack *cur = SymbolizedStack::New(addr);<br>
+  Â  cdata->append(cur);<br>
+  Â  AddressInfo *info = &cur->info;<br>
  Â  Â info->FillAddressAndModuleInfo(addr, cdata->module_name,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  cdata->module_offset);<br>
  Â  Â info->function = LibbacktraceSymbolizer::Demangle(symname, true);<br>
-  Â  cdata->n_frames = 1;<br>
  Â }<br>
 }<br>
<br>
@@ -148,23 +156,21 @@ LibbacktraceSymbolizer *LibbacktraceSymb<br>
  Â return new(*alloc) LibbacktraceSymbolizer(state);<br>
 }<br>
<br>
-uptr LibbacktraceSymbolizer::SymbolizeCode(uptr addr, AddressInfo *frames,<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â uptr max_frames,<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â const char *module_name,<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â uptr module_offset) {<br>
-  SymbolizeCodeData data;<br>
-  data.frames = frames;<br>
-  data.n_frames = 0;<br>
-  data.max_frames = max_frames;<br>
+SymbolizedStack *LibbacktraceSymbolizer::SymbolizeCode(uptr addr,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â const char *module_name,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â uptr module_offset) {<br>
+  SymbolizeCodeCallbackArg data;<br>
+  data.first = nullptr;<br>
+  data.last = nullptr;<br>
  Â data.module_name = module_name;<br>
  Â data.module_offset = module_offset;<br>
  Â backtrace_pcinfo((backtrace_state *)state_, addr, SymbolizeCodePCInfoCallback,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  ErrorCallback, &data);<br>
-  if (data.n_frames)<br>
-  Â  return data.n_frames;<br>
+  if (data.first)<br>
+  Â  return data.first;<br>
  Â backtrace_syminfo((backtrace_state *)state_, addr, SymbolizeCodeCallback,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â ErrorCallback, &data);<br>
-  return data.n_frames;<br>
+  return data.first;<br>
 }<br>
<br>
 bool LibbacktraceSymbolizer::SymbolizeData(DataInfo *info) {<br>
@@ -179,12 +185,11 @@ LibbacktraceSymbolizer *LibbacktraceSymb<br>
  Â return 0;<br>
 }<br>
<br>
-uptr LibbacktraceSymbolizer::SymbolizeCode(uptr addr, AddressInfo *frames,<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â uptr max_frames,<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â const char *module_name,<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â uptr module_offset) {<br>
+SymbolizedStack *LibbacktraceSymbolizer::SymbolizeCode(uptr addr,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â const char *module_name,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â uptr module_offset) {<br>
  Â (void)state_;<br>
-  return 0;<br>
+  return nullptr;<br>
 }<br>
<br>
 bool LibbacktraceSymbolizer::SymbolizeData(DataInfo *info) {<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h Tue Dec  2 13:48:40 2014<br>
@@ -32,8 +32,8 @@ class LibbacktraceSymbolizer {<br>
  public:<br>
  Â static LibbacktraceSymbolizer *get(LowLevelAllocator *alloc);<br>
<br>
-  uptr SymbolizeCode(uptr addr, AddressInfo *frames, uptr max_frames,<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â const char *module_name, uptr module_offset);<br>
+  SymbolizedStack *SymbolizeCode(uptr addr, const char *module_name,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â uptr module_offset);<br>
<br>
  Â bool SymbolizeData(DataInfo *info);<br>
<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc<br>
URL: <a href="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" target="_blank">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</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc Tue Dec  2 13:48:40 2014<br>
@@ -514,34 +514,32 @@ class POSIXSymbolizer : public Symbolize<br>
  Â  Â  Â  Â internal_symbolizer_(internal_symbolizer),<br>
  Â  Â  Â  Â libbacktrace_symbolizer_(libbacktrace_symbolizer) {}<br>
<br>
-  uptr SymbolizePC(uptr addr, AddressInfo *frames, uptr max_frames) override {<br>
+  SymbolizedStack *SymbolizePC(uptr addr) override {<br>
  Â  Â BlockingMutexLock l(&mu_);<br>
-  Â  if (max_frames == 0)<br>
-  Â  Â  return 0;<br>
  Â  Â const char *module_name;<br>
  Â  Â uptr module_offset;<br>
  Â  Â if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset))<br>
-  Â  Â  return 0;<br>
+  Â  Â  return SymbolizedStack::New(addr);<br>
  Â  Â // First, try to use libbacktrace symbolizer (if it's available).<br>
  Â  Â if (libbacktrace_symbolizer_ != 0) {<br>
  Â  Â  Â mu_.CheckLocked();<br>
-  Â  Â  uptr res = libbacktrace_symbolizer_->SymbolizeCode(<br>
-  Â  Â  Â  Â  addr, frames, max_frames, module_name, module_offset);<br>
-  Â  Â  if (res > 0)<br>
+  Â  Â  if (SymbolizedStack *res = libbacktrace_symbolizer_->SymbolizeCode(<br>
+  Â  Â  Â  Â  Â  Â  addr, module_name, module_offset))<br>
  Â  Â  Â  Â return res;<br>
  Â  Â }<br>
+  Â  // Always fill data about module name and offset.<br>
+  Â  SymbolizedStack *res = SymbolizedStack::New(addr);<br>
+  Â  res->info.FillAddressAndModuleInfo(addr, module_name, module_offset);<br>
+<br>
  Â  Â const char *str = SendCommand(false, module_name, module_offset);<br>
  Â  Â if (str == 0) {<br>
-  Â  Â  // Symbolizer was not initialized or failed. Fill only data<br>
-  Â  Â  // about module name and offset.<br>
-  Â  Â  AddressInfo *info = &frames[0];<br>
-  Â  Â  info->Clear();<br>
-  Â  Â  info->FillAddressAndModuleInfo(addr, module_name, module_offset);<br>
-  Â  Â  return 1;<br>
+  Â  Â  // Symbolizer was not initialized or failed.<br>
+  Â  Â  return res;<br>
  Â  Â }<br>
-  Â  uptr frame_id = 0;<br>
-  Â  for (frame_id = 0; frame_id < max_frames; frame_id++) {<br>
-  Â  Â  AddressInfo *info = &frames[frame_id];<br>
+<br>
+  Â  bool top_frame = true;<br>
+  Â  SymbolizedStack *last = res;<br>
+  Â  while (true) {<br>
  Â  Â  Â char *function_name = 0;<br>
  Â  Â  Â str = ExtractToken(str, "\n", &function_name);<br>
  Â  Â  Â CHECK(function_name);<br>
@@ -549,8 +547,18 @@ class POSIXSymbolizer : public Symbolize<br>
  Â  Â  Â  Â // There are no more frames.<br>
  Â  Â  Â  Â break;<br>
  Â  Â  Â }<br>
-  Â  Â  info->Clear();<br>
-  Â  Â  info->FillAddressAndModuleInfo(addr, module_name, module_offset);<br>
+  Â  Â  SymbolizedStack *cur;<br>
+  Â  Â  if (top_frame) {<br>
+  Â  Â  Â  cur = res;<br>
+  Â  Â  Â  top_frame = false;<br>
+  Â  Â  } else {<br>
+  Â  Â  Â  cur = SymbolizedStack::New(addr);<br>
+  Â  Â  Â  cur->info.FillAddressAndModuleInfo(addr, module_name, module_offset);<br>
+  Â  Â  Â  last->next = cur;<br>
+  Â  Â  Â  last = cur;<br>
+  Â  Â  }<br>
+<br>
+  Â  Â  AddressInfo *info = &cur->info;<br>
  Â  Â  Â info->function = function_name;<br>
  Â  Â  Â // Parse <file>:<line>:<column> buffer.<br>
  Â  Â  Â char *file_line_info = 0;<br>
@@ -572,14 +580,7 @@ class POSIXSymbolizer : public Symbolize<br>
  Â  Â  Â  Â info->file = 0;<br>
  Â  Â  Â }<br>
  Â  Â }<br>
-  Â  if (frame_id == 0) {<br>
-  Â  Â  // Make sure we return at least one frame.<br>
-  Â  Â  AddressInfo *info = &frames[0];<br>
-  Â  Â  info->Clear();<br>
-  Â  Â  info->FillAddressAndModuleInfo(addr, module_name, module_offset);<br>
-  Â  Â  frame_id = 1;<br>
-  Â  }<br>
-  Â  return frame_id;<br>
+  Â  return res;<br>
  Â }<br>
<br>
  Â bool SymbolizeData(uptr addr, DataInfo *info) override {<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc Tue Dec  2 13:48:40 2014<br>
@@ -26,9 +26,8 @@ class WinSymbolizer : public Symbolizer<br>
  public:<br>
  Â WinSymbolizer() : initialized_(false) {}<br>
<br>
-  uptr SymbolizePC(uptr addr, AddressInfo *frames, uptr max_frames) override {<br>
-  Â  if (max_frames == 0)<br>
-  Â  Â  return 0;<br>
+  SymbolizedStack *SymbolizePC(uptr addr) override {<br>
+  Â  SymbolizedStack *frame = SymbolizedStack::New(addr);<br>
<br>
  Â  Â BlockingMutexLock l(&dbghelp_mu_);<br>
  Â  Â if (!initialized_) {<br>
@@ -60,29 +59,27 @@ class WinSymbolizer : public Symbolizer<br>
  Â  Â BOOL got_objname = SymFromAddr(GetCurrentProcess(),<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  (DWORD64)addr, &offset, symbol);<br>
  Â  Â if (!got_objname)<br>
-  Â  Â  return 0;<br>
+  Â  Â  return frame;<br>
<br>
  Â  Â DWORD unused;<br>
  Â  Â IMAGEHLP_LINE64 line_info;<br>
  Â  Â line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE64);<br>
  Â  Â BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(), (DWORD64)addr,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  &unused, &line_info);<br>
-  Â  AddressInfo *info = &frames[0];<br>
-  Â  info->Clear();<br>
-  Â  info->function = internal_strdup(symbol->Name);<br>
-  Â  info->function_offset = (uptr)offset;<br>
+  Â  frame->info.function = internal_strdup(symbol->Name);<br>
+  Â  frame->info.function_offset = (uptr)offset;<br>
  Â  Â if (got_fileline) {<br>
-  Â  Â  info->file = internal_strdup(line_info.FileName);<br>
-  Â  Â  info->line = line_info.LineNumber;<br>
+  Â  Â  frame->info.file = internal_strdup(line_info.FileName);<br>
+  Â  Â  frame->info.line = line_info.LineNumber;<br>
  Â  Â }<br>
<br>
  Â  Â IMAGEHLP_MODULE64 mod_info;<br>
  Â  Â internal_memset(&mod_info, 0, sizeof(mod_info));<br>
  Â  Â mod_info.SizeOfStruct = sizeof(mod_info);<br>
  Â  Â if (SymGetModuleInfo64(GetCurrentProcess(), addr, &mod_info))<br>
-  Â  Â  info->FillAddressAndModuleInfo(addr, mod_info.ImageName,<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â addr - (uptr)mod_info.BaseOfImage);<br>
-  Â  return 1;<br>
+  Â  Â  frame->info.FillAddressAndModuleInfo(addr, mod_info.ImageName,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â addr - (uptr)mod_info.BaseOfImage);<br>
+  Â  return frame;<br>
  Â }<br>
<br>
  Â bool CanReturnFileLineInfo() override {<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/go/buildgo.sh<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/go/buildgo.sh?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/go/buildgo.sh?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/go/buildgo.sh (original)<br>
+++ compiler-rt/trunk/lib/tsan/go/buildgo.sh Tue Dec  2 13:48:40 2014<br>
@@ -27,6 +27,7 @@ SRCS="<br>
  Â  Â  Â  ../../sanitizer_common/sanitizer_thread_registry.cc<br>
  Â  Â  Â  ../../sanitizer_common/sanitizer_stackdepot.cc<br>
  Â  Â  Â  ../../sanitizer_common/sanitizer_stacktrace.cc<br>
+  Â  Â  Â ../../sanitizer_common/sanitizer_symbolizer.cc<br>
 "<br>
<br>
 if [ "`uname -a | grep Linux`" != "" ]; then<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/go/tsan_go.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/go/tsan_go.cc?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/go/tsan_go.cc?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/go/tsan_go.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/go/tsan_go.cc Tue Dec  2 13:48:40 2014<br>
@@ -59,18 +59,19 @@ struct SymbolizeContext {<br>
 // Callback into Go.<br>
 static void (*symbolize_cb)(SymbolizeContext *ctx);<br>
<br>
-ReportStack *SymbolizeCode(uptr addr) {<br>
-  ReportStack *s = ReportStack::New(addr);<br>
+SymbolizedStack *SymbolizeCode(uptr addr) {<br>
+  SymbolizedStack *s = SymbolizedStack::New(addr);<br>
  Â SymbolizeContext ctx;<br>
  Â internal_memset(&ctx, 0, sizeof(ctx));<br>
  Â ctx.pc = addr;<br>
  Â symbolize_cb(&ctx);<br>
  Â if (ctx.res) {<br>
-  Â  s->info.module_offset = ctx.off;<br>
-  Â  s->info.function = internal_strdup(ctx.func ? ctx.func : "??");<br>
-  Â  s->info.file = internal_strdup(ctx.file ? ctx.file : "-");<br>
-  Â  s->info.line = ctx.line;<br>
-  Â  s->info.column = 0;<br>
+  Â  AddressInfo &info = s->info;<br>
+  Â  info.module_offset = ctx.off;<br>
+  Â  info.function = internal_strdup(ctx.func ? ctx.func : "??");<br>
+  Â  info.file = internal_strdup(ctx.file ? ctx.file : "-");<br>
+  Â  info.line = ctx.line;<br>
+  Â  info.column = 0;<br>
  Â }<br>
  Â return s;<br>
 }<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=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=223145&r1=223144&r2=223145&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 Tue Dec  2 13:48:40 2014<br>
@@ -19,13 +19,11 @@<br>
<br>
 namespace __tsan {<br>
<br>
-ReportStack::ReportStack() : next(nullptr), info(), suppressable(false) {}<br>
+ReportStack::ReportStack() : frames(nullptr), suppressable(false) {}<br>
<br>
-ReportStack *ReportStack::New(uptr addr) {<br>
+ReportStack *ReportStack::New() {<br>
  Â void *mem = internal_alloc(MBlockReportStack, sizeof(ReportStack));<br>
-  ReportStack *res = new(mem) ReportStack();<br>
-  res->info.address = addr;<br>
-  return res;<br>
+  return new(mem) ReportStack();<br>
 }<br>
<br>
 ReportLocation::ReportLocation(ReportLocationType type)<br>
@@ -114,13 +112,14 @@ static const char *ReportTypeString(Repo<br>
 }<br>
<br>
 void PrintStack(const ReportStack *ent) {<br>
-  if (ent == 0) {<br>
+  if (ent == 0 || ent->frames == 0) {<br>
  Â  Â Printf("  Â  [failed to restore the stack]\n\n");<br>
  Â  Â return;<br>
  Â }<br>
-  for (int i = 0; ent && ent->info.address; ent = ent->next, i++) {<br>
+  SymbolizedStack *frame = ent->frames;<br>
+  for (int i = 0; frame && frame->info.address; frame = frame->next, i++) {<br>
  Â  Â InternalScopedString res(2 * GetPageSizeCached());<br>
-  Â  RenderFrame(&res, common_flags()->stack_trace_format, i, ent->info,<br>
+  Â  RenderFrame(&res, common_flags()->stack_trace_format, i, frame->info,<br>
  Â  Â  Â  Â  Â  Â  Â  Â common_flags()->strip_path_prefix, "__interceptor_");<br>
  Â  Â Printf("%s\n", res.data());<br>
  Â }<br>
@@ -252,10 +251,20 @@ static ReportStack *ChooseSummaryStack(c<br>
  Â return 0;<br>
 }<br>
<br>
-ReportStack *SkipTsanInternalFrames(ReportStack *ent) {<br>
-  while (FrameIsInternal(ent) && ent->next)<br>
-  Â  ent = ent->next;<br>
-  return ent;<br>
+static bool FrameIsInternal(const SymbolizedStack *frame) {<br>
+  if (frame == 0)<br>
+  Â  return false;<br>
+  const char *file = frame->info.file;<br>
+  return file != 0 &&<br>
+  Â  Â  Â  Â (internal_strstr(file, "tsan_interceptors.cc") ||<br>
+  Â  Â  Â  Â  internal_strstr(file, "sanitizer_common_interceptors.inc") ||<br>
+  Â  Â  Â  Â  internal_strstr(file, "tsan_interface_"));<br>
+}<br>
+<br>
+static SymbolizedStack *SkipTsanInternalFrames(SymbolizedStack *frames) {<br>
+  while (FrameIsInternal(frames) && frames->next)<br>
+  Â  frames = frames->next;<br>
+  return frames;<br>
 }<br>
<br>
 void PrintReport(const ReportDesc *rep) {<br>
@@ -325,9 +334,11 @@ void PrintReport(const ReportDesc *rep)<br>
  Â if (rep->typ == ReportTypeThreadLeak && rep->count > 1)<br>
  Â  Â Printf("  And %d more similar thread leaks.\n\n", rep->count - 1);<br>
<br>
-  if (ReportStack *ent = SkipTsanInternalFrames(ChooseSummaryStack(rep))) {<br>
-  Â  const AddressInfo &info = ent->info;<br>
-  Â  ReportErrorSummary(rep_typ_str, info.file, info.line, info.function);<br>
+  if (ReportStack *stack = ChooseSummaryStack(rep)) {<br>
+  Â  if (SymbolizedStack *frame = SkipTsanInternalFrames(stack->frames)) {<br>
+  Â  Â  const AddressInfo &info = frame->info;<br>
+  Â  Â  ReportErrorSummary(rep_typ_str, info.file, info.line, info.function);<br>
+  Â  }<br>
  Â }<br>
<br>
  Â Printf("==================\n");<br>
@@ -338,12 +349,13 @@ void PrintReport(const ReportDesc *rep)<br>
 const int kMainThreadId = 1;<br>
<br>
 void PrintStack(const ReportStack *ent) {<br>
-  if (ent == 0) {<br>
+  if (ent == 0 || ent->frames == 0) {<br>
  Â  Â Printf("  [failed to restore the stack]\n");<br>
  Â  Â return;<br>
  Â }<br>
-  for (int i = 0; ent; ent = ent->next, i++) {<br>
-  Â  const AddressInfo &info = ent->info;<br>
+  SymbolizedStack *frame = ent->frames;<br>
+  for (int i = 0; frame; frame = frame->next, i++) {<br>
+  Â  const AddressInfo &info = frame->info;<br>
  Â  Â Printf("  %s()\n  Â  Â  %s:%d +0x%zx\n", info.function, info.file, info.line,<br>
  Â  Â  Â  Â  Â  (void *)info.module_offset);<br>
  Â }<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.h?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.h?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.h (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.h Tue Dec  2 13:48:40 2014<br>
@@ -36,10 +36,9 @@ enum ReportType {<br>
 };<br>
<br>
 struct ReportStack {<br>
-  ReportStack *next;<br>
-  AddressInfo info;<br>
+  SymbolizedStack *frames;<br>
  Â bool suppressable;<br>
-  static ReportStack *New(uptr addr);<br>
+  static ReportStack *New();<br>
<br>
  private:<br>
  Â ReportStack();<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=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=223145&r1=223144&r2=223145&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 Tue Dec  2 13:48:40 2014<br>
@@ -568,8 +568,6 @@ bool IsFiredSuppression(Context *ctx, co<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â StackTrace trace);<br>
 bool IsExpectedReport(uptr addr, uptr size);<br>
 void PrintMatchedBenignRaces();<br>
-bool FrameIsInternal(const ReportStack *frame);<br>
-ReportStack *SkipTsanInternalFrames(ReportStack *ent);<br>
<br>
 #if defined(TSAN_DEBUG_OUTPUT) && TSAN_DEBUG_OUTPUT >= 1<br>
 # define DPrintf Printf<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=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=223145&r1=223144&r2=223145&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 Tue Dec  2 13:48:40 2014<br>
@@ -56,40 +56,43 @@ bool WEAK OnReport(const ReportDesc *rep<br>
 }<br>
 #endif<br>
<br>
-static void StackStripMain(ReportStack *stack) {<br>
-  ReportStack *last_frame = 0;<br>
-  ReportStack *last_frame2 = 0;<br>
-  for (ReportStack *ent = stack; ent; ent = ent->next) {<br>
+static void StackStripMain(SymbolizedStack *frames) {<br>
+  SymbolizedStack *last_frame = nullptr;<br>
+  SymbolizedStack *last_frame2 = nullptr;<br>
+  for (SymbolizedStack *cur = frames; cur; cur = cur->next) {<br>
  Â  Â last_frame2 = last_frame;<br>
-  Â  last_frame = ent;<br>
+  Â  last_frame = cur;<br>
  Â }<br>
<br>
  Â if (last_frame2 == 0)<br>
  Â  Â return;<br>
-  const char *last = last_frame->info.function;<br>
 #ifndef TSAN_GO<br>
+  const char *last = last_frame->info.function;<br>
  Â const char *last2 = last_frame2->info.function;<br>
  Â // Strip frame above 'main'<br>
  Â if (last2 && 0 == internal_strcmp(last2, "main")) {<br>
-  Â  last_frame2->next = 0;<br>
+  Â  last_frame->ClearAll();<br>
+  Â  last_frame2->next = nullptr;<br>
  Â // Strip our internal thread start routine.<br>
  Â } else if (last && 0 == internal_strcmp(last, "__tsan_thread_start_func")) {<br>
-  Â  last_frame2->next = 0;<br>
+  Â  last_frame->ClearAll();<br>
+  Â  last_frame2->next = nullptr;<br>
  Â // Strip global ctors init.<br>
  Â } else if (last && 0 == internal_strcmp(last, "__do_global_ctors_aux")) {<br>
-  Â  last_frame2->next = 0;<br>
+  Â  last_frame->ClearAll();<br>
+  Â  last_frame2->next = nullptr;<br>
  Â // If both are 0, then we probably just failed to symbolize.<br>
  Â } else if (last || last2) {<br>
  Â  Â // Ensure that we recovered stack completely. Trimmed stack<br>
  Â  Â // can actually happen if we do not instrument some code,<br>
  Â  Â // so it's only a debug print. However we must try hard to not miss it<br>
  Â  Â // due to our fault.<br>
-  Â  DPrintf("Bottom stack frame of stack %zx is missed\n", stack->pc);<br>
+  Â  DPrintf("Bottom stack frame of stack %zx is missed\n", stack->info.address);<br>
  Â }<br>
 #else<br>
  Â // The last frame always point into runtime (gosched0, goexit0, runtime.main).<br>
-  last_frame2->next = 0;<br>
-  (void)last;<br>
+  last_frame->ClearAll();<br>
+  last_frame2->next = nullptr;<br>
 #endif<br>
 }<br>
<br>
@@ -105,12 +108,12 @@ ReportStack *SymbolizeStackId(u32 stack_<br>
 static ReportStack *SymbolizeStack(StackTrace trace) {<br>
  Â if (trace.size == 0)<br>
  Â  Â return 0;<br>
-  ReportStack *stack = 0;<br>
+  SymbolizedStack *top = nullptr;<br>
  Â for (uptr si = 0; si < trace.size; si++) {<br>
  Â  Â const uptr pc = trace.trace[si];<br>
 #ifndef TSAN_GO<br>
-  Â  // We obtain the return address, that is, address of the next instruction,<br>
-  Â  // so offset it by 1 byte.<br>
+  Â  // We obtain the return address, but we're interested in the previous<br>
+  Â  // instruction.<br>
  Â  Â const uptr pc1 = StackTrace::GetPreviousInstructionPc(pc);<br>
 #else<br>
  Â  Â // FIXME(dvyukov): Go sometimes uses address of a function as top pc.<br>
@@ -118,18 +121,21 @@ static ReportStack *SymbolizeStack(Stack<br>
  Â  Â if (si != trace.size - 1)<br>
  Â  Â  Â pc1 -= 1;<br>
 #endif<br>
-  Â  ReportStack *ent = SymbolizeCode(pc1);<br>
+  Â  SymbolizedStack *ent = SymbolizeCode(pc1);<br>
  Â  Â CHECK_NE(ent, 0);<br>
-  Â  ReportStack *last = ent;<br>
+  Â  SymbolizedStack *last = ent;<br>
  Â  Â while (last->next) {<br>
  Â  Â  Â last->info.address = pc;  // restore original pc for report<br>
  Â  Â  Â last = last->next;<br>
  Â  Â }<br>
  Â  Â last->info.address = pc;  // restore original pc for report<br>
-  Â  last->next = stack;<br>
-  Â  stack = ent;<br>
+  Â  last->next = top;<br>
+  Â  top = ent;<br>
  Â }<br>
-  StackStripMain(stack);<br>
+  StackStripMain(top);<br>
+<br>
+  ReportStack *stack = ReportStack::New();<br>
+  stack->frames = top;<br>
  Â return stack;<br>
 }<br>
<br>
@@ -547,16 +553,6 @@ static bool IsFiredSuppression(Context *<br>
  Â return false;<br>
 }<br>
<br>
-bool FrameIsInternal(const ReportStack *frame) {<br>
-  if (frame == 0)<br>
-  Â  return false;<br>
-  const char *file = frame->info.file;<br>
-  return file != 0 &&<br>
-  Â  Â  Â  Â (internal_strstr(file, "tsan_interceptors.cc") ||<br>
-  Â  Â  Â  Â  internal_strstr(file, "sanitizer_common_interceptors.inc") ||<br>
-  Â  Â  Â  Â  internal_strstr(file, "tsan_interface_"));<br>
-}<br>
-<br>
 static bool RaceBetweenAtomicAndFree(ThreadState *thr) {<br>
  Â Shadow s0(thr->racy_state[0]);<br>
  Â Shadow s1(thr->racy_state[1]);<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc Tue Dec  2 13:48:40 2014<br>
@@ -92,7 +92,8 @@ uptr IsSuppressed(ReportType typ, const<br>
  Â if (stype == SuppressionNone)<br>
  Â  Â return 0;<br>
  Â Suppression *s;<br>
-  for (const ReportStack *frame = stack; frame; frame = frame->next) {<br>
+  for (const SymbolizedStack *frame = stack->frames; frame;<br>
+  Â  Â  Â frame = frame->next) {<br>
  Â  Â const AddressInfo &info = frame->info;<br>
  Â  Â if (SuppressionContext::Get()->Match(info.function, stype, &s) ||<br>
  Â  Â  Â  Â SuppressionContext::Get()->Match(info.file, stype, &s) ||<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.cc?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.cc?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.cc Tue Dec  2 13:48:40 2014<br>
@@ -55,7 +55,7 @@ bool __tsan_symbolize_external(uptr pc,<br>
  Â return false;<br>
 }<br>
<br>
-ReportStack *SymbolizeCode(uptr addr) {<br>
+SymbolizedStack *SymbolizeCode(uptr addr) {<br>
  Â // Check if PC comes from non-native land.<br>
  Â if (addr & kExternalPCBit) {<br>
  Â  Â // Declare static to not consume too much stack space.<br>
@@ -63,36 +63,17 @@ ReportStack *SymbolizeCode(uptr addr) {<br>
  Â  Â static char func_buf[1024];<br>
  Â  Â static char file_buf[1024];<br>
  Â  Â int line, col;<br>
-  Â  ReportStack *ent = ReportStack::New(addr);<br>
-  Â  if (!__tsan_symbolize_external(addr, func_buf, sizeof(func_buf),<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  file_buf, sizeof(file_buf), &line, &col))<br>
-  Â  Â  return ent;<br>
-  Â  ent->info.function = internal_strdup(func_buf);<br>
-  Â  ent->info.file = internal_strdup(file_buf);<br>
-  Â  ent->info.line = line;<br>
-  Â  ent->info.column = col;<br>
-  Â  return ent;<br>
+  Â  SymbolizedStack *frame = SymbolizedStack::New(addr);<br>
+  Â  if (__tsan_symbolize_external(addr, func_buf, sizeof(func_buf), file_buf,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  sizeof(file_buf), &line, &col)) {<br>
+  Â  Â  frame->info.function = internal_strdup(func_buf);<br>
+  Â  Â  frame->info.file = internal_strdup(file_buf);<br>
+  Â  Â  frame->info.line = line;<br>
+  Â  Â  frame->info.column = col;<br>
+  Â  }<br>
+  Â  return frame;<br>
  Â }<br>
-  static const uptr kMaxAddrFrames = 16;<br>
-  InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames);<br>
-  for (uptr i = 0; i < kMaxAddrFrames; i++)<br>
-  Â  new(&addr_frames[i]) AddressInfo();<br>
-  uptr addr_frames_num = Symbolizer::GetOrInit()->SymbolizePC(<br>
-  Â  Â  addr, addr_frames.data(), kMaxAddrFrames);<br>
-  if (addr_frames_num == 0)<br>
-  Â  return ReportStack::New(addr);<br>
-  ReportStack *top = 0;<br>
-  ReportStack *bottom = 0;<br>
-  for (uptr i = 0; i < addr_frames_num; i++) {<br>
-  Â  ReportStack *cur_entry = ReportStack::New(addr);<br>
-  Â  cur_entry->info = addr_frames[i];<br>
-  Â  if (i == 0)<br>
-  Â  Â  top = cur_entry;<br>
-  Â  else<br>
-  Â  Â  bottom->next = cur_entry;<br>
-  Â  bottom = cur_entry;<br>
-  }<br>
-  return top;<br>
+  return Symbolizer::GetOrInit()->SymbolizePC(addr);<br>
 }<br>
<br>
 ReportLocation *SymbolizeData(uptr addr) {<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.h?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.h?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.h (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_symbolize.h Tue Dec  2 13:48:40 2014<br>
@@ -20,7 +20,7 @@ namespace __tsan {<br>
<br>
 void EnterSymbolizer();<br>
 void ExitSymbolizer();<br>
-ReportStack *SymbolizeCode(uptr addr);<br>
+SymbolizedStack *SymbolizeCode(uptr addr);<br>
 ReportLocation *SymbolizeData(uptr addr);<br>
 void SymbolizeFlush();<br>
<br>
<br>
Modified: compiler-rt/trunk/lib/ubsan/ubsan_diag.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_diag.cc?rev=223145&r1=223144&r2=223145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_diag.cc?rev=223145&r1=223144&r2=223145&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/ubsan/ubsan_diag.cc (original)<br>
+++ compiler-rt/trunk/lib/ubsan/ubsan_diag.cc Tue Dec  2 13:48:40 2014<br>
@@ -79,18 +79,26 @@ Location __ubsan::getFunctionLocation(up<br>
  Â  Â return Location();<br>
  Â InitIfNecessary();<br>
<br>
-  AddressInfo Info;<br>
-  if (!Symbolizer::GetOrInit()->SymbolizePC(Loc, &Info, 1) || !Info.module ||<br>
-  Â  Â  !*Info.module)<br>
+  SymbolizedStack *Frames = Symbolizer::GetOrInit()->SymbolizePC(Loc);<br>
+  const AddressInfo &Info = Frames->info;<br>
+<br>
+  if (!Info.module) {<br>
+  Â  Frames->ClearAll();<br>
  Â  Â return Location(Loc);<br>
+  }<br>
<br>
  Â if (FName && Info.function)<br>
-  Â  *FName = Info.function;<br>
+  Â  *FName = internal_strdup(Info.function);<br>
<br>
-  if (!Info.file)<br>
-  Â  return ModuleLocation(Info.module, Info.module_offset);<br>
+  if (!Info.file) {<br>
+  Â  ModuleLocation MLoc(internal_strdup(Info.module), Info.module_offset);<br>
+  Â  Frames->ClearAll();<br>
+  Â  return MLoc;<br>
+  }<br>
<br>
-  return SourceLocation(Info.file, Info.line, Info.column);<br>
+  SourceLocation SLoc(internal_strdup(Info.file), Info.line, Info.column);<br>
+  Frames->ClearAll();<br>
+  return SLoc;<br>
 }<br>
<br>
 Diag &Diag::operator<<(const TypeDescriptor &V) {<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="javascript:_e(%7B%7D,'cvml','llvm-commits@cs.uiuc.edu');" target="_blank">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></div></div>
<br><br>-- <br>  F<br><br>