diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2018-03-21 08:44:14 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2018-03-21 08:44:14 +0000 |
commit | 6f6e03a3c09e31ff6fda4ad9f215ca0c6d495d34 (patch) | |
tree | 41ef242b0459054369f95a04a80ed6ac4f7bdbec /lib/tsan | |
parent | def0ac6300d4511350d7abbb883f42faf708a132 (diff) |
tsan: support inlined frames in external symbolization
New API passes a callback function to the external symbolizer,
allowing it to add multiple frames to the traceback. Note that
the old interface API will be still supported until the clients
migrate to the new one.
Author: asmundak (Alexander Smundak)
Reviewed in: https://reviews.llvm.org/D44714
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@328079 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan')
-rw-r--r-- | lib/tsan/rtl/tsan_rtl_report.cc | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_symbolize.cc | 42 |
2 files changed, 44 insertions, 2 deletions
diff --git a/lib/tsan/rtl/tsan_rtl_report.cc b/lib/tsan/rtl/tsan_rtl_report.cc index cc582ab50..febb6cef2 100644 --- a/lib/tsan/rtl/tsan_rtl_report.cc +++ b/lib/tsan/rtl/tsan_rtl_report.cc @@ -649,8 +649,8 @@ void ReportRace(ThreadState *thr) { // callback. Most likely, TraceTopPC will now return a EventTypeFuncExit // event. Later we subtract -1 from it (in GetPreviousInstructionPc) // and the resulting PC has kExternalPCBit set, so we pass it to - // __tsan_symbolize_external. __tsan_symbolize_external is within its rights - // to crash since the PC is completely bogus. + // __tsan_symbolize_external_ex. __tsan_symbolize_external_ex is within its + // rights to crash since the PC is completely bogus. // test/tsan/double_race.cc contains a test case for this. toppc = 0; } diff --git a/lib/tsan/rtl/tsan_symbolize.cc b/lib/tsan/rtl/tsan_symbolize.cc index b24239517..de50c4eb3 100644 --- a/lib/tsan/rtl/tsan_symbolize.cc +++ b/lib/tsan/rtl/tsan_symbolize.cc @@ -36,6 +36,7 @@ void ExitSymbolizer() { thr->ignore_interceptors--; } +// Legacy API. // May be overriden by JIT/JAVA/etc, // whatever produces PCs marked with kExternalPCBit. SANITIZER_WEAK_DEFAULT_IMPL @@ -45,9 +46,50 @@ bool __tsan_symbolize_external(uptr pc, char *func_buf, uptr func_siz, return false; } +// New API: call __tsan_symbolize_external_ex only when it exists. +// Once old clients are gone, provide dummy implementation. +extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE +void __tsan_symbolize_external_ex(uptr pc, + void (*add_frame)(void *, const char *, + const char *, int, int), + void *ctx); + +struct SymbolizedStackBuilder { + SymbolizedStack *head; + SymbolizedStack *tail; + uptr addr; +}; + +static void AddFrame(void *ctx, const char *function_name, const char *file, + int line, int column) { + SymbolizedStackBuilder *ssb = (struct SymbolizedStackBuilder *)ctx; + if (ssb->tail) { + ssb->tail->next = SymbolizedStack::New(ssb->addr); + ssb->tail = ssb->tail->next; + } else { + ssb->head = ssb->tail = SymbolizedStack::New(ssb->addr); + } + AddressInfo *info = &ssb->tail->info; + if (function_name) { + info->function = internal_strdup(function_name); + } + if (file) { + info->file = internal_strdup(file); + } + info->line = line; + info->column = column; +} + SymbolizedStack *SymbolizeCode(uptr addr) { // Check if PC comes from non-native land. if (addr & kExternalPCBit) { + if (__tsan_symbolize_external_ex) { + SymbolizedStackBuilder ssb = {nullptr, nullptr, addr}; + __tsan_symbolize_external_ex(addr, AddFrame, &ssb); + return ssb.head ? ssb.head : SymbolizedStack::New(addr); + } + // Legacy code: remove along with the declaration above + // once all clients using this API are gone. // Declare static to not consume too much stack space. // We symbolize reports in a single thread, so this is fine. static char func_buf[1024]; |