[compiler-rt] r223145 - Simplify Symbolizer::SymbolizePC() interface.
Filipe Cabecinhas
filcab at gmail.com
Thu Feb 5 19:02:07 PST 2015
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
<javascript:_e(%7B%7D,'cvml','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
> <javascript:_e(%7B%7D,'cvml','llvm-commits at cs.uiuc.edu');>
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
--
F
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150205/2ee1f6a1/attachment.html>
More information about the llvm-commits
mailing list