namespace __sanitizer {
+uptr StackTrace::GetNextInstructionPc(uptr pc) {
+#if defined(__sparc__) || defined(__mips__)
+ return pc + 8;
+#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__)
+ return pc + 4;
+#elif SANITIZER_RISCV64
+ // Current check order is 4 -> 2 -> 6 -> 8
+ u8 InsnByte = *(u8 *)(pc);
+ if (((InsnByte & 0x3) == 0x3) && ((InsnByte & 0x1c) != 0x1c)) {
+ // xxxxxxxxxxxbbb11 | 32 bit | bbb != 111
+ return pc + 4;
+ }
+ if ((InsnByte & 0x3) != 0x3) {
+ // xxxxxxxxxxxxxxaa | 16 bit | aa != 11
+ return pc + 2;
+ }
+ // RISC-V encoding allows instructions to be up to 8 bytes long
+ if ((InsnByte & 0x3f) == 0x1f) {
+ // xxxxxxxxxx011111 | 48 bit |
+ return pc + 6;
+ }
+ if ((InsnByte & 0x7f) == 0x3f) {
+ // xxxxxxxxx0111111 | 64 bit |
+ return pc + 8;
+ }
+ // bail-out if could not figure out the instruction size
+ return 0;
+#else
+ return pc + 1;
+#endif
+}
+
uptr StackTrace::GetCurrentPc() {
return GET_CALLER_PC();
}
#endif
}
-ALWAYS_INLINE
-uptr StackTrace::GetNextInstructionPc(uptr pc) {
-#if defined(__sparc__) || defined(__mips__)
- return pc + 8;
-#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__)
- return pc + 4;
-#elif SANITIZER_RISCV64
- // Current check order is 4 -> 2 -> 6 -> 8
- u8 InsnByte = *(u8 *)(pc);
- if (((InsnByte & 0x3) == 0x3) && ((InsnByte & 0x1c) != 0x1c)) {
- // xxxxxxxxxxxbbb11 | 32 bit | bbb != 111
- return pc + 4;
- }
- if ((InsnByte & 0x3) != 0x3) {
- // xxxxxxxxxxxxxxaa | 16 bit | aa != 11
- return pc + 2;
- }
- // RISC-V encoding allows instructions to be up to 8 bytes long
- if ((InsnByte & 0x3f) == 0x1f) {
- // xxxxxxxxxx011111 | 48 bit |
- return pc + 6;
- }
- if ((InsnByte & 0x7f) == 0x3f) {
- // xxxxxxxxx0111111 | 64 bit |
- return pc + 8;
- }
- // bail-out if could not figure out the instruction size
- return 0;
-#else
- return pc + 1;
-#endif
-}
-
// StackTrace that owns the buffer used to store the addresses.
struct BufferedStackTrace : public StackTrace {
uptr trace_buffer[kStackTraceMax];
uptr local_stack; \
uptr sp = (uptr)&local_stack
-#define GET_CURRENT_PC() \
- ({ \
- this_pc: \
- StackTrace::GetNextInstructionPc((uptr) && this_pc); \
- })
#endif // SANITIZER_STACKTRACE_H
} // namespace __tsan
-#define SCOPED_INTERCEPTOR_RAW(func, ...) \
- cur_thread_init(); \
- ThreadState *thr = cur_thread(); \
- const uptr caller_pc = GET_CALLER_PC(); \
- ScopedInterceptor si(thr, #func, caller_pc); \
- const uptr pc = GET_CURRENT_PC(); \
- (void)pc; \
- /**/
+#define SCOPED_INTERCEPTOR_RAW(func, ...) \
+ cur_thread_init(); \
+ ThreadState *thr = cur_thread(); \
+ const uptr caller_pc = GET_CALLER_PC(); \
+ ScopedInterceptor si(thr, #func, caller_pc); \
+ const uptr pc = StackTrace::GetCurrentPc(); \
+ (void)pc; \
+/**/
#define SCOPED_TSAN_INTERCEPTOR(func, ...) \
SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
if (in_symbolizer())
return;
ThreadState *thr = cur_thread();
- const uptr pc = GET_CURRENT_PC();
+ const uptr pc = StackTrace::GetCurrentPc();
ForkBefore(thr, pc);
}
if (in_symbolizer())
return;
ThreadState *thr = cur_thread();
- const uptr pc = GET_CURRENT_PC();
+ const uptr pc = StackTrace::GetCurrentPc();
ForkParentAfter(thr, pc);
}
if (in_symbolizer())
return;
ThreadState *thr = cur_thread();
- const uptr pc = GET_CURRENT_PC();
+ const uptr pc = StackTrace::GetCurrentPc();
ForkChildAfter(thr, pc);
FdOnFork(thr, pc);
}
(void)rep;
}
-bool InternalFrame(const char *func) {
- static const char *frames[] = {
- "__tsan::ScopedInterceptor",
- "__sanitizer::StackTrace",
- };
- for (auto frame : frames) {
- if (!internal_strncmp(func, frame, internal_strlen(frame)))
- return true;
- }
- return false;
-}
-
-static SymbolizedStack *StackStripMain(SymbolizedStack *frames) {
- for (; frames && frames->info.function; frames = frames->next) {
- // Remove top inlined frames from our interceptors.
- if (!InternalFrame(frames->info.function))
- break;
- }
+static void StackStripMain(SymbolizedStack *frames) {
SymbolizedStack *last_frame = nullptr;
SymbolizedStack *last_frame2 = nullptr;
for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
}
if (last_frame2 == 0)
- return frames;
+ return;
#if !SANITIZER_GO
const char *last = last_frame->info.function;
const char *last2 = last_frame2->info.function;
last_frame->ClearAll();
last_frame2->next = nullptr;
// Strip global ctors init.
- } else if (last && (0 == internal_strcmp(last, "__do_global_ctors_aux") ||
- 0 == internal_strcmp(last, "__libc_csu_init"))) {
+ } else if (last && 0 == internal_strcmp(last, "__do_global_ctors_aux")) {
last_frame->ClearAll();
last_frame2->next = nullptr;
// If both are 0, then we probably just failed to symbolize.
last_frame->ClearAll();
last_frame2->next = nullptr;
#endif
- return frames;
}
ReportStack *SymbolizeStackId(u32 stack_id) {
last->next = top;
top = ent;
}
+ StackStripMain(top);
+
ReportStack *stack = ReportStack::New();
- stack->frames = StackStripMain(top);
+ stack->frames = top;
return stack;
}