Alexey Samsonov | bc12f5d | 2012-07-05 07:18:29 +0000 | [diff] [blame] | 1 | //===-- tsan_symbolize.cc -------------------------------------------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file is a part of ThreadSanitizer (TSan), a race detector. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #include "tsan_symbolize.h" |
| 15 | |
| 16 | #include "sanitizer_common/sanitizer_common.h" |
| 17 | #include "sanitizer_common/sanitizer_placement_new.h" |
| 18 | #include "sanitizer_common/sanitizer_symbolizer.h" |
| 19 | #include "tsan_flags.h" |
| 20 | #include "tsan_report.h" |
Dmitry Vyukov | 4e81d0e | 2013-01-29 13:03:07 +0000 | [diff] [blame] | 21 | #include "tsan_rtl.h" |
Alexey Samsonov | bc12f5d | 2012-07-05 07:18:29 +0000 | [diff] [blame] | 22 | |
| 23 | namespace __tsan { |
| 24 | |
Alexey Samsonov | 66d91e3 | 2013-10-31 21:44:07 +0000 | [diff] [blame] | 25 | void EnterSymbolizer() { |
| 26 | ThreadState *thr = cur_thread(); |
| 27 | CHECK(!thr->in_symbolizer); |
| 28 | thr->in_symbolizer = true; |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 29 | thr->ignore_interceptors++; |
Alexey Samsonov | 66d91e3 | 2013-10-31 21:44:07 +0000 | [diff] [blame] | 30 | } |
Dmitry Vyukov | 4e81d0e | 2013-01-29 13:03:07 +0000 | [diff] [blame] | 31 | |
Alexey Samsonov | 66d91e3 | 2013-10-31 21:44:07 +0000 | [diff] [blame] | 32 | void ExitSymbolizer() { |
| 33 | ThreadState *thr = cur_thread(); |
| 34 | CHECK(thr->in_symbolizer); |
| 35 | thr->in_symbolizer = false; |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 36 | thr->ignore_interceptors--; |
Alexey Samsonov | 66d91e3 | 2013-10-31 21:44:07 +0000 | [diff] [blame] | 37 | } |
Dmitry Vyukov | 4e81d0e | 2013-01-29 13:03:07 +0000 | [diff] [blame] | 38 | |
Dmitry Vyukov | 2d2dc46 | 2013-09-22 00:14:57 +0000 | [diff] [blame] | 39 | // May be overriden by JIT/JAVA/etc, |
| 40 | // whatever produces PCs marked with kExternalPCBit. |
| 41 | extern "C" bool __tsan_symbolize_external(uptr pc, |
| 42 | char *func_buf, uptr func_siz, |
| 43 | char *file_buf, uptr file_siz, |
| 44 | int *line, int *col) |
| 45 | SANITIZER_WEAK_ATTRIBUTE; |
| 46 | |
| 47 | bool __tsan_symbolize_external(uptr pc, |
| 48 | char *func_buf, uptr func_siz, |
| 49 | char *file_buf, uptr file_siz, |
| 50 | int *line, int *col) { |
| 51 | return false; |
| 52 | } |
| 53 | |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 54 | SymbolizedStack *SymbolizeCode(uptr addr) { |
Dmitry Vyukov | 2d2dc46 | 2013-09-22 00:14:57 +0000 | [diff] [blame] | 55 | // Check if PC comes from non-native land. |
| 56 | if (addr & kExternalPCBit) { |
| 57 | // Declare static to not consume too much stack space. |
| 58 | // We symbolize reports in a single thread, so this is fine. |
| 59 | static char func_buf[1024]; |
| 60 | static char file_buf[1024]; |
| 61 | int line, col; |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 62 | SymbolizedStack *frame = SymbolizedStack::New(addr); |
| 63 | if (__tsan_symbolize_external(addr, func_buf, sizeof(func_buf), file_buf, |
| 64 | sizeof(file_buf), &line, &col)) { |
| 65 | frame->info.function = internal_strdup(func_buf); |
| 66 | frame->info.file = internal_strdup(file_buf); |
| 67 | frame->info.line = line; |
| 68 | frame->info.column = col; |
| 69 | } |
| 70 | return frame; |
Dmitry Vyukov | 2d2dc46 | 2013-09-22 00:14:57 +0000 | [diff] [blame] | 71 | } |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 72 | return Symbolizer::GetOrInit()->SymbolizePC(addr); |
Alexey Samsonov | bc12f5d | 2012-07-05 07:18:29 +0000 | [diff] [blame] | 73 | } |
| 74 | |
Dmitry Vyukov | 5a1f233 | 2013-01-11 07:23:51 +0000 | [diff] [blame] | 75 | ReportLocation *SymbolizeData(uptr addr) { |
Dmitry Vyukov | 5a1f233 | 2013-01-11 07:23:51 +0000 | [diff] [blame] | 76 | DataInfo info; |
Stephen Hines | 6d18623 | 2014-11-26 17:56:19 -0800 | [diff] [blame] | 77 | if (!Symbolizer::GetOrInit()->SymbolizeData(addr, &info)) |
Dmitry Vyukov | 5a1f233 | 2013-01-11 07:23:51 +0000 | [diff] [blame] | 78 | return 0; |
Stephen Hines | 6d18623 | 2014-11-26 17:56:19 -0800 | [diff] [blame] | 79 | ReportLocation *ent = ReportLocation::New(ReportLocationGlobal); |
| 80 | ent->global = info; |
Dmitry Vyukov | 5a1f233 | 2013-01-11 07:23:51 +0000 | [diff] [blame] | 81 | return ent; |
Alexey Samsonov | bc12f5d | 2012-07-05 07:18:29 +0000 | [diff] [blame] | 82 | } |
| 83 | |
Dmitry Vyukov | 723e24f | 2013-03-19 10:24:01 +0000 | [diff] [blame] | 84 | void SymbolizeFlush() { |
Stephen Hines | 6d18623 | 2014-11-26 17:56:19 -0800 | [diff] [blame] | 85 | Symbolizer::GetOrInit()->Flush(); |
Dmitry Vyukov | 723e24f | 2013-03-19 10:24:01 +0000 | [diff] [blame] | 86 | } |
| 87 | |
Alexey Samsonov | bc12f5d | 2012-07-05 07:18:29 +0000 | [diff] [blame] | 88 | } // namespace __tsan |