Skip to content

Commit 9e66e58

Browse files
committed
tsan: print signal num in errno spoiling reports
For errno spoiling reports we only print the stack where the signal handler is invoked. And the top frame is the signal handler function, which is supposed to give the info for debugging. But in same cases the top frame can be some common thunk, which does not give much info. E.g. for Go/cgo it's always runtime.cgoSigtramp. Print the signal number. This is what we can easily gather and it may give at least some hints regarding the issue. Reviewed By: melver, vitalybuka Differential Revision: https://reviews.llvm.org/D121979
1 parent 00145bc commit 9e66e58

File tree

6 files changed

+11
-3
lines changed

6 files changed

+11
-3
lines changed

compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,13 +1964,14 @@ TSAN_INTERCEPTOR(int, pthread_sigmask, int how, const __sanitizer_sigset_t *set,
19641964

19651965
namespace __tsan {
19661966

1967-
static void ReportErrnoSpoiling(ThreadState *thr, uptr pc) {
1967+
static void ReportErrnoSpoiling(ThreadState *thr, uptr pc, int sig) {
19681968
VarSizeStackTrace stack;
19691969
// StackTrace::GetNestInstructionPc(pc) is used because return address is
19701970
// expected, OutputReport() will undo this.
19711971
ObtainCurrentStack(thr, StackTrace::GetNextInstructionPc(pc), &stack);
19721972
ThreadRegistryLock l(&ctx->thread_registry);
19731973
ScopedReport rep(ReportTypeErrnoInSignal);
1974+
rep.SetSigNum(sig);
19741975
if (!IsFiredSuppression(ctx, ReportTypeErrnoInSignal, stack)) {
19751976
rep.AddStack(stack, true);
19761977
OutputReport(thr, rep);
@@ -2037,7 +2038,7 @@ static void CallUserSignalHandler(ThreadState *thr, bool sync, bool acquire,
20372038
// signal; and it looks too fragile to intercept all ways to reraise a signal.
20382039
if (ShouldReport(thr, ReportTypeErrnoInSignal) && !sync && sig != SIGTERM &&
20392040
errno != 99)
2040-
ReportErrnoSpoiling(thr, pc);
2041+
ReportErrnoSpoiling(thr, pc, sig);
20412042
errno = saved_errno;
20422043
}
20432044

compiler-rt/lib/tsan/rtl/tsan_report.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,9 @@ void PrintReport(const ReportDesc *rep) {
306306
(int)internal_getpid());
307307
Printf("%s", d.Default());
308308

309+
if (rep->typ == ReportTypeErrnoInSignal)
310+
Printf(" Signal %u handler invoked at:\n", rep->signum);
311+
309312
if (rep->typ == ReportTypeDeadlock) {
310313
char thrbuf[kThreadBufSize];
311314
Printf(" Cycle in lock order graph: ");

compiler-rt/lib/tsan/rtl/tsan_report.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ class ReportDesc {
108108
Vector<Tid> unique_tids;
109109
ReportStack *sleep;
110110
int count;
111+
int signum = 0;
111112

112113
ReportDesc();
113114
~ReportDesc();

compiler-rt/lib/tsan/rtl/tsan_rtl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ class ScopedReportBase {
376376
void AddLocation(uptr addr, uptr size);
377377
void AddSleep(StackID stack_id);
378378
void SetCount(int count);
379+
void SetSigNum(int sig);
379380

380381
const ReportDesc *GetReport() const;
381382

compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,8 @@ void ScopedReportBase::AddSleep(StackID stack_id) {
340340

341341
void ScopedReportBase::SetCount(int count) { rep_->count = count; }
342342

343+
void ScopedReportBase::SetSigNum(int sig) { rep_->signum = sig; }
344+
343345
const ReportDesc *ScopedReportBase::GetReport() const { return rep_; }
344346

345347
ScopedReport::ScopedReport(ReportType typ, uptr tag)

compiler-rt/test/tsan/signal_errno.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ int main() {
4646
}
4747

4848
// CHECK: WARNING: ThreadSanitizer: signal handler spoils errno
49+
// CHECK: Signal 27 handler invoked at:
4950
// CHECK: #0 MyHandler(int, {{(__)?}}siginfo{{(_t)?}}*, void*) {{.*}}signal_errno.cpp
5051
// CHECK: main
5152
// CHECK: SUMMARY: ThreadSanitizer: signal handler spoils errno{{.*}}MyHandler
52-

0 commit comments

Comments
 (0)