forked from OSchip/llvm-project
tsan: consistently use return pc as top frame pc
always substract 1 from the top pc this allows to get correct stacks with -O2 llvm-svn: 184112
This commit is contained in:
parent
7648aa3558
commit
5cf581a8d4
|
@ -181,8 +181,7 @@ ScopedInterceptor::~ScopedInterceptor() {
|
|||
StatInc(thr, StatInt_##func); \
|
||||
const uptr caller_pc = GET_CALLER_PC(); \
|
||||
ScopedInterceptor si(thr, #func, caller_pc); \
|
||||
const uptr pc = __sanitizer::StackTrace::GetPreviousInstructionPc( \
|
||||
__sanitizer::StackTrace::GetCurrentPc()); \
|
||||
const uptr pc = __sanitizer::StackTrace::GetCurrentPc(); \
|
||||
(void)pc; \
|
||||
/**/
|
||||
|
||||
|
@ -1882,6 +1881,7 @@ void ProcessPendingSignals(ThreadState *thr) {
|
|||
uptr pc = signal->sigaction ?
|
||||
(uptr)sigactions[sig].sa_sigaction :
|
||||
(uptr)sigactions[sig].sa_handler;
|
||||
pc += 1; // return address is expected, OutputReport() will undo this
|
||||
stack.Init(&pc, 1);
|
||||
ThreadRegistryLock l(ctx->thread_registry);
|
||||
ScopedReport rep(ReportTypeErrnoInSignal);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "sanitizer_common/sanitizer_libc.h"
|
||||
#include "sanitizer_common/sanitizer_internal_defs.h"
|
||||
#include "sanitizer_common/sanitizer_placement_new.h"
|
||||
#include "sanitizer_common/sanitizer_stacktrace.h"
|
||||
#include "tsan_interface_ann.h"
|
||||
#include "tsan_mutex.h"
|
||||
#include "tsan_report.h"
|
||||
|
@ -229,12 +230,12 @@ using namespace __tsan; // NOLINT
|
|||
extern "C" {
|
||||
void INTERFACE_ATTRIBUTE AnnotateHappensBefore(char *f, int l, uptr addr) {
|
||||
SCOPED_ANNOTATION(AnnotateHappensBefore);
|
||||
Release(cur_thread(), CALLERPC, addr);
|
||||
Release(cur_thread(), pc, addr);
|
||||
}
|
||||
|
||||
void INTERFACE_ATTRIBUTE AnnotateHappensAfter(char *f, int l, uptr addr) {
|
||||
SCOPED_ANNOTATION(AnnotateHappensAfter);
|
||||
Acquire(cur_thread(), CALLERPC, addr);
|
||||
Acquire(cur_thread(), pc, addr);
|
||||
}
|
||||
|
||||
void INTERFACE_ATTRIBUTE AnnotateCondVarSignal(char *f, int l, uptr cv) {
|
||||
|
|
|
@ -30,7 +30,6 @@ using namespace __tsan; // NOLINT
|
|||
#define SCOPED_ATOMIC(func, ...) \
|
||||
const uptr callpc = (uptr)__builtin_return_address(0); \
|
||||
uptr pc = __sanitizer::StackTrace::GetCurrentPc(); \
|
||||
pc = __sanitizer::StackTrace::GetPreviousInstructionPc(pc); \
|
||||
mo = ConvertOrder(mo); \
|
||||
mo = flags()->force_seq_cst_atomics ? (morder)mo_seq_cst : mo; \
|
||||
ThreadState *const thr = cur_thread(); \
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "sanitizer_common/sanitizer_internal_defs.h"
|
||||
#include "sanitizer_common/sanitizer_common.h"
|
||||
#include "sanitizer_common/sanitizer_placement_new.h"
|
||||
#include "sanitizer_common/sanitizer_stacktrace.h"
|
||||
|
||||
using namespace __tsan; // NOLINT
|
||||
|
||||
|
@ -157,7 +158,7 @@ SyncVar* GetAndRemoveJavaSync(ThreadState *thr, uptr pc, uptr addr) {
|
|||
#define SCOPED_JAVA_FUNC(func) \
|
||||
ThreadState *thr = cur_thread(); \
|
||||
const uptr caller_pc = GET_CALLER_PC(); \
|
||||
const uptr pc = (uptr)&func; \
|
||||
const uptr pc = __sanitizer::StackTrace::GetCurrentPc(); \
|
||||
(void)pc; \
|
||||
ScopedJavaFunc scoped(thr, caller_pc); \
|
||||
/**/
|
||||
|
|
|
@ -106,17 +106,25 @@ static ReportStack *SymbolizeStack(const StackTrace& trace) {
|
|||
return 0;
|
||||
ReportStack *stack = 0;
|
||||
for (uptr si = 0; si < trace.Size(); si++) {
|
||||
const uptr pc = trace.Get(si);
|
||||
#ifndef TSAN_GO
|
||||
// We obtain the return address, that is, address of the next instruction,
|
||||
// so offset it by 1 byte.
|
||||
bool is_last = (si == trace.Size() - 1);
|
||||
ReportStack *ent = SymbolizeCode(trace.Get(si) - !is_last);
|
||||
const uptr pc1 = __sanitizer::StackTrace::GetPreviousInstructionPc(pc);
|
||||
#else
|
||||
// FIXME(dvyukov): Go sometimes uses address of a function as top pc.
|
||||
uptr pc1 = pc;
|
||||
if (si != trace.Size() - 1)
|
||||
pc1 -= 1;
|
||||
#endif
|
||||
ReportStack *ent = SymbolizeCode(pc1);
|
||||
CHECK_NE(ent, 0);
|
||||
ReportStack *last = ent;
|
||||
while (last->next) {
|
||||
last->pc += !is_last;
|
||||
last->pc = pc; // restore original pc for report
|
||||
last = last->next;
|
||||
}
|
||||
last->pc += !is_last;
|
||||
last->pc = pc; // restore original pc for report
|
||||
last->next = stack;
|
||||
stack = ent;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue