[compiler-rt] r223145 - Simplify Symbolizer::SymbolizePC() interface.
Filipe Cabecinhas
filcab at gmail.com
Tue Feb 10 16:46:23 PST 2015
Thanks for working on this!
Filipe
On Tue, Feb 10, 2015 at 4:39 PM, Alexey Samsonov <vonosmas at gmail.com> wrote:
> 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/520598bf/attachment.html>
More information about the llvm-commits
mailing list