tsan_symbolize.cc revision c1a1ed62228288155459d39194995a36aca4a8a6
1caee0dccffb77a003681345ab3281bcf8684526cChris Lattner//===-- tsan_symbolize.cc -------------------------------------------------===// 2caee0dccffb77a003681345ab3281bcf8684526cChris Lattner// 3caee0dccffb77a003681345ab3281bcf8684526cChris Lattner// The LLVM Compiler Infrastructure 4caee0dccffb77a003681345ab3281bcf8684526cChris Lattner// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7caee0dccffb77a003681345ab3281bcf8684526cChris Lattner// 8caee0dccffb77a003681345ab3281bcf8684526cChris Lattner//===----------------------------------------------------------------------===// 9caee0dccffb77a003681345ab3281bcf8684526cChris Lattner// 10caee0dccffb77a003681345ab3281bcf8684526cChris Lattner// This file is a part of ThreadSanitizer (TSan), a race detector. 11caee0dccffb77a003681345ab3281bcf8684526cChris Lattner// 12caee0dccffb77a003681345ab3281bcf8684526cChris Lattner//===----------------------------------------------------------------------===// 13caee0dccffb77a003681345ab3281bcf8684526cChris Lattner 14caee0dccffb77a003681345ab3281bcf8684526cChris Lattner#include "tsan_symbolize.h" 15caee0dccffb77a003681345ab3281bcf8684526cChris Lattner 16caee0dccffb77a003681345ab3281bcf8684526cChris Lattner#include "sanitizer_common/sanitizer_common.h" 17caee0dccffb77a003681345ab3281bcf8684526cChris Lattner#include "sanitizer_common/sanitizer_placement_new.h" 18eaf42abab6d465c38891345d999255871cf03943Devang Patel#include "sanitizer_common/sanitizer_symbolizer.h" 19522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner#include "tsan_flags.h" 20efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif#include "tsan_report.h" 2148f848716e80d01619b239111db48bfac77baad1Chris Lattner#include "tsan_rtl.h" 2247f96bf24687b5068aec7166cb8b3ac33ae964aeChris Lattner 2348f848716e80d01619b239111db48bfac77baad1Chris Lattnernamespace __tsan { 24caee0dccffb77a003681345ab3281bcf8684526cChris Lattner 25caee0dccffb77a003681345ab3281bcf8684526cChris Lattnerstruct ScopedInSymbolizer { 26caee0dccffb77a003681345ab3281bcf8684526cChris Lattner ScopedInSymbolizer() { 27c453f76e2b4d7fd1e042b5b6d4c20556779186dfChris Lattner ThreadState *thr = cur_thread(); 28522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner CHECK(!thr->in_symbolizer); 29efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif thr->in_symbolizer = true; 30efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif } 31efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif 32efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif ~ScopedInSymbolizer() { 33522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner ThreadState *thr = cur_thread(); 34efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif CHECK(thr->in_symbolizer); 35ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner thr->in_symbolizer = false; 36ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner } 37ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner}; 38ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner 39ea693dfab48ee6fc07cc21abc20f487df5057a6bChris LattnerReportStack *NewReportStackEntry(uptr addr) { 40ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner ReportStack *ent = (ReportStack*)internal_alloc(MBlockReportStack, 41ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner sizeof(ReportStack)); 42ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner internal_memset(ent, 0, sizeof(*ent)); 43ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner ent->pc = addr; 44ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner return ent; 45522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner} 46efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif 47efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif// Strip module path to make output shorter. 48ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattnerstatic char *StripModuleName(const char *module) { 49ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner if (module == 0) 50ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner return 0; 51efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif const char *short_module_name = internal_strrchr(module, '/'); 52efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif if (short_module_name) 53efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif short_module_name += 1; 54efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif else 55522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner short_module_name = module; 56522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner return internal_strdup(short_module_name); 57efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif} 58522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner 59efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greifstatic ReportStack *NewReportStackEntry(const AddressInfo &info) { 60efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif ReportStack *ent = NewReportStackEntry(info.address); 61efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif ent->module = StripModuleName(info.module); 62efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif ent->offset = info.module_offset; 63522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner if (info.function) 64522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner ent->func = internal_strdup(info.function); 65b348bb81253a1105d23ab1a1771f8d2a6546aa1bChris Lattner if (info.file) 66ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner ent->file = internal_strdup(info.file); 67efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif ent->line = info.line; 68efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif ent->col = info.column; 69b348bb81253a1105d23ab1a1771f8d2a6546aa1bChris Lattner return ent; 70b348bb81253a1105d23ab1a1771f8d2a6546aa1bChris Lattner} 71522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner 72522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner 73efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif ReportStack *next; 74efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif char *module; 75522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner uptr offset; 76198f34ac359c48018c6e1f784cf3770ead63b253Chris Lattner uptr pc; 77980e5aad4cfaa32e13b297f4201eb1088ca96cc4Chris Lattner char *func; 78efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif char *file; 79efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif int line; 80198f34ac359c48018c6e1f784cf3770ead63b253Chris Lattner int col; 81522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner 82522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner 83522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner// Denotes fake PC values that come from JIT/JAVA/etc. 84a7c49aac984fafa5dfdfcc2762d4d51b26788e38Chris Lattner// For such PC values __tsan_symbolize_external() will be called. 85a7c49aac984fafa5dfdfcc2762d4d51b26788e38Chris Lattnerconst uptr kExternalPCBit = 1ULL << 60; 86a7c49aac984fafa5dfdfcc2762d4d51b26788e38Chris Lattner 87a7c49aac984fafa5dfdfcc2762d4d51b26788e38Chris Lattner// May be overriden by JIT/JAVA/etc, 88a7c49aac984fafa5dfdfcc2762d4d51b26788e38Chris Lattner// whatever produces PCs marked with kExternalPCBit. 89a7c49aac984fafa5dfdfcc2762d4d51b26788e38Chris Lattnerextern "C" bool __tsan_symbolize_external(uptr pc, 90ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner char *func_buf, uptr func_siz, 91ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner char *file_buf, uptr file_siz, 92ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner int *line, int *col) 93ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner SANITIZER_WEAK_ATTRIBUTE; 94ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner 95ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattnerbool __tsan_symbolize_external(uptr pc, 96ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner char *func_buf, uptr func_siz, 97ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner char *file_buf, uptr file_siz, 98ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner int *line, int *col) { 99ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner return false; 100ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner} 101a7c49aac984fafa5dfdfcc2762d4d51b26788e38Chris Lattner 102a7c49aac984fafa5dfdfcc2762d4d51b26788e38Chris LattnerReportStack *SymbolizeCode(uptr addr) { 103a7c49aac984fafa5dfdfcc2762d4d51b26788e38Chris Lattner // Check if PC comes from non-native land. 104a7c49aac984fafa5dfdfcc2762d4d51b26788e38Chris Lattner if (addr & kExternalPCBit) { 105a7c49aac984fafa5dfdfcc2762d4d51b26788e38Chris Lattner // Declare static to not consume too much stack space. 106ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner // We symbolize reports in a single thread, so this is fine. 107ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner static char func_buf[1024]; 108ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner static char file_buf[1024]; 109ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner int line, col; 110a7c49aac984fafa5dfdfcc2762d4d51b26788e38Chris Lattner if (!__tsan_symbolize_external(addr, func_buf, sizeof(func_buf), 111522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner file_buf, sizeof(file_buf), &line, &col)) 112efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif return NewReportStackEntry(addr); 113efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif ReportStack *ent = NewReportStackEntry(addr); 114efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif ent->module = 0; 115efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif ent->offset = 0; 116efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif ent->func = internal_strdup(func_buf); 1176c80c381601b17207b6b8f898cfe273a37584d52Gabor Greif ent->file = internal_strdup(file_buf); 118522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner ent->line = line; 119522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner ent->col = col; 120efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif return ent; 121efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif } 122ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner if (!Symbolizer::Get()->IsAvailable()) 123ea693dfab48ee6fc07cc21abc20f487df5057a6bChris Lattner return SymbolizeCodeAddr2Line(addr); 124efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif ScopedInSymbolizer in_symbolizer; 125efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif static const uptr kMaxAddrFrames = 16; 126efe65369a74871c3140a540a6c95ce5d1f080954Gabor Greif InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames); 127caee0dccffb77a003681345ab3281bcf8684526cChris Lattner for (uptr i = 0; i < kMaxAddrFrames; i++) 128caee0dccffb77a003681345ab3281bcf8684526cChris Lattner new(&addr_frames[i]) AddressInfo(); 129c453f76e2b4d7fd1e042b5b6d4c20556779186dfChris Lattner uptr addr_frames_num = Symbolizer::Get()->SymbolizeCode( 13048f848716e80d01619b239111db48bfac77baad1Chris Lattner addr, addr_frames.data(), kMaxAddrFrames); 13148f848716e80d01619b239111db48bfac77baad1Chris Lattner if (addr_frames_num == 0) 132caee0dccffb77a003681345ab3281bcf8684526cChris Lattner return NewReportStackEntry(addr); 133caee0dccffb77a003681345ab3281bcf8684526cChris Lattner ReportStack *top = 0; 134caee0dccffb77a003681345ab3281bcf8684526cChris Lattner ReportStack *bottom = 0; 135522b7b104c864da81c19d8b16c43b7a1f6a2fc40Chris Lattner for (uptr i = 0; i < addr_frames_num; i++) { 136e16504eb4ef8f09611cdf6e9a0be9eb886b4ed89Chris Lattner ReportStack *cur_entry = NewReportStackEntry(addr_frames[i]); 13707d98b4afbdcbb4eed048400d9116de1ec83e866Chris Lattner CHECK(cur_entry); 13848f848716e80d01619b239111db48bfac77baad1Chris Lattner addr_frames[i].Clear(); 13919c874638d9478a5d5028854817a5ee72293bb2bDevang Patel if (i == 0) 14048c85b84c1b66fb6a1b0d2afddf33da5bd82960dChris Lattner top = cur_entry; 14148c85b84c1b66fb6a1b0d2afddf33da5bd82960dChris Lattner else 14219c874638d9478a5d5028854817a5ee72293bb2bDevang Patel bottom->next = cur_entry; 14348c85b84c1b66fb6a1b0d2afddf33da5bd82960dChris Lattner bottom = cur_entry; 144980e5aad4cfaa32e13b297f4201eb1088ca96cc4Chris Lattner } 145980e5aad4cfaa32e13b297f4201eb1088ca96cc4Chris Lattner return top; 146980e5aad4cfaa32e13b297f4201eb1088ca96cc4Chris Lattner} 147980e5aad4cfaa32e13b297f4201eb1088ca96cc4Chris Lattner 14848f848716e80d01619b239111db48bfac77baad1Chris LattnerReportLocation *SymbolizeData(uptr addr) { 14948f848716e80d01619b239111db48bfac77baad1Chris Lattner if (!Symbolizer::Get()->IsAvailable()) 15048f848716e80d01619b239111db48bfac77baad1Chris Lattner return 0; 1516994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth ScopedInSymbolizer in_symbolizer; 1526994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth DataInfo info; 1536994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (!Symbolizer::Get()->SymbolizeData(addr, &info)) 1546994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth return 0; 1556994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth ReportLocation *ent = (ReportLocation*)internal_alloc(MBlockReportStack, 15648f848716e80d01619b239111db48bfac77baad1Chris Lattner sizeof(ReportLocation)); 15748f848716e80d01619b239111db48bfac77baad1Chris Lattner internal_memset(ent, 0, sizeof(*ent)); 15848f848716e80d01619b239111db48bfac77baad1Chris Lattner ent->type = ReportLocationGlobal; 15948f848716e80d01619b239111db48bfac77baad1Chris Lattner ent->module = StripModuleName(info.module); 16048f848716e80d01619b239111db48bfac77baad1Chris Lattner ent->offset = info.module_offset; 16148f848716e80d01619b239111db48bfac77baad1Chris Lattner if (info.name) 16248f848716e80d01619b239111db48bfac77baad1Chris Lattner ent->name = internal_strdup(info.name); 16348f848716e80d01619b239111db48bfac77baad1Chris Lattner ent->addr = info.start; 16448f848716e80d01619b239111db48bfac77baad1Chris Lattner ent->size = info.size; 165caee0dccffb77a003681345ab3281bcf8684526cChris Lattner return ent; 166950a4c40b823cd4f09dc71be635229246dfd6cacDan Gohman} 167950a4c40b823cd4f09dc71be635229246dfd6cacDan Gohman 16848f848716e80d01619b239111db48bfac77baad1Chris Lattnervoid SymbolizeFlush() { 16948f848716e80d01619b239111db48bfac77baad1Chris Lattner if (!Symbolizer::Get()->IsAvailable()) 170b348bb81253a1105d23ab1a1771f8d2a6546aa1bChris Lattner return; 171b348bb81253a1105d23ab1a1771f8d2a6546aa1bChris Lattner ScopedInSymbolizer in_symbolizer; 172b348bb81253a1105d23ab1a1771f8d2a6546aa1bChris Lattner Symbolizer::Get()->Flush(); 173caee0dccffb77a003681345ab3281bcf8684526cChris Lattner} 174b348bb81253a1105d23ab1a1771f8d2a6546aa1bChris Lattner 175c453f76e2b4d7fd1e042b5b6d4c20556779186dfChris Lattner} // namespace __tsan 176c453f76e2b4d7fd1e042b5b6d4c20556779186dfChris Lattner