[compiler-rt] r223145 - Simplify Symbolizer::SymbolizePC() interface.
Alexey Samsonov
vonosmas at gmail.com
Tue Feb 10 16:39:34 PST 2015
Hi,
On Fri, Feb 6, 2015 at 2:44 PM, Filipe Cabecinhas <filcab at gmail.com> wrote:
> Hi Alexey,
>
> On Fri, Feb 6, 2015 at 1:17 PM, Alexey Samsonov <vonosmas at gmail.com>
> wrote:
>
>> Hi Filipe,
>>
>> First of all, did you notice it by code inspection, or actually observed
>> noticable memory leak in your program?
>>
> It was reported to us after we shipped UBSan for testing. Programs just
> crash.
> This makes sense if you take into account that you might have errors in
> each frame of a game, which runs at 60fps. Memory usage grows rapidly :-)
>
Right, I meant that ideally we should call leaky getCallerLocation() /
getFunctionLocation() only once per each error report we print, and we try
to deduplicate
reports based on their source locations (file/line/column of invalid
operation). I took a closer look, and it turned out to not be the case:
I've submitted r228732 and
r228772 to improve the situtation here. The remaining important case is
float-cast-overflow, for which we don't provide the source locations now.
>
> I remember this problem, and it wasn't fixed until now, because this
>> memory leak happens during error reporting, and can only be noticed if your
>> program has a significant
>> number of different UBSan error reports. That said, we should of course
>> fix it :)
>>
> That was the idea I had after seeing the code :-)
>
> I don't really understand your suggestion, though. Location destructor
>> already calls destructor for MemoryLocation. The problem is
>> ModuleLocation::ModuleName (and, similar SourceLocation::Filename):
>>
> Yes. The “clear the objects” would be the freeing of whatever we could,
> which is what's missing (ModuleName and Filename).
>
>
>> they can point to either constant string literals, or global data, or
>> dynamically allocated strings (e.g. via internal_strdup). We should only
>> call InternalFree() on these string buffers in the latter case.
>>
> Ah, I forgot about the string literal case.
> I wonder if it's more worth it to make the SourceLocation (and friends)
> class manage their strings a bit better, or if it would be worth it to have
> the StackFrames objects not fully free each of the module's names (We're
> leaking because we generate a FallbackLoc with the module name).
>
> Any clues on where it would be better to start? You know much more about
> what you need for location info outside of ubsan.
>
I hope to refactor this code and plug the memory leaks this week. Thanks
for bringing this issue to attention!
>
> Thank you,
>
> Filipe
>
>
> On Thu, Feb 5, 2015 at 7:02 PM, Filipe Cabecinhas <filcab at gmail.com>
>> wrote:
>>
>>> Hi Alexey!
>>>
>>> This still has a memory leak: (ubsan_diag.cc)
>>> + if (!Info.file) {
>>> + ModuleLocation MLoc(internal_strdup(Info.module),
>>> Info.module_offset);
>>> + Frames->ClearAll();
>>> + return MLoc;
>>> + }
>>> ^^ 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.
>>>
>>> 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.
>>> If you're ok with this let me know and I can submit the patch,
>>> otherwise, can you fix it?
>>> (I'm not sure about the uses in tsan and other sanitizers, so I don't
>>> know if they also leak)
>>>
>>> Thanks,
>>>
>>> Filipe
>>>
>>> On Tue, Dec 2, 2014 at 11:48 AM, Alexey Samsonov <vonosmas at gmail.com>
>>> wrote:
>>>
>>>> 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) {
>>>>
>>>>
>>>> _______________________________________________
>>>> llvm-commits mailing list
>>>> llvm-commits at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>>
>>>
>>>
>>>
>>> --
>>> F
>>>
>>>
>>
>>
>> --
>> Alexey Samsonov
>> vonosmas at gmail.com
>>
>
>
--
Alexey Samsonov
vonosmas at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150210/12d97257/attachment.html>
More information about the llvm-commits
mailing list