Skip to content

Commit 266a8d5

Browse files
committed
[tsan] Fix sigaction interceptor after D107186
Set SA_SIGINFO only if we set sighandler, or we can set the flag, and return it as 'old' without actual sigaction set. Reviewed By: melver Differential Revision: https://reviews.llvm.org/D108616
1 parent 4c418c1 commit 266a8d5

File tree

2 files changed

+70
-2
lines changed

2 files changed

+70
-2
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2459,9 +2459,11 @@ int sigaction_impl(int sig, const __sanitizer_sigaction *act,
24592459
#endif
24602460
internal_memcpy(&newact, act, sizeof(newact));
24612461
internal_sigfillset(&newact.sa_mask);
2462-
newact.sa_flags |= SA_SIGINFO;
2463-
if ((uptr)act->handler != sig_ign && (uptr)act->handler != sig_dfl)
2462+
if ((act->sa_flags & SA_SIGINFO) ||
2463+
((uptr)act->handler != sig_ign && (uptr)act->handler != sig_dfl)) {
2464+
newact.sa_flags |= SA_SIGINFO;
24642465
newact.sigaction = sighandler;
2466+
}
24652467
ReleaseStore(thr, pc, (uptr)&sigactions[sig]);
24662468
act = &newact;
24672469
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// RUN: %clangxx -std=c++11 -O0 -g %s -o %t && %run %t
2+
3+
#include <assert.h>
4+
#include <signal.h>
5+
#include <unistd.h>
6+
7+
static bool sahandler_done;
8+
static bool sasigaction_done;
9+
10+
static void sahandler(int) { sahandler_done = true; }
11+
12+
static void sasigaction(int, siginfo_t *, void *) { sasigaction_done = true; }
13+
14+
template <typename T> void install(T *handler, struct sigaction *prev) {
15+
bool siginfo = handler == (T *)&sasigaction;
16+
struct sigaction act = {};
17+
if (siginfo) {
18+
act.sa_flags = SA_SIGINFO;
19+
act.sa_sigaction = (decltype(act.sa_sigaction))handler;
20+
} else {
21+
act.sa_handler = (decltype(act.sa_handler))handler;
22+
}
23+
int ret = sigaction(SIGHUP, &act, prev);
24+
assert(ret == 0);
25+
26+
if (handler == (T *)&sahandler) {
27+
sahandler_done = false;
28+
raise(SIGHUP);
29+
assert(sahandler_done);
30+
}
31+
32+
if (handler == (T *)&sasigaction) {
33+
sasigaction_done = false;
34+
raise(SIGHUP);
35+
assert(sasigaction_done);
36+
}
37+
}
38+
39+
template <typename T1, typename T2> void test(T1 *from, T2 *to) {
40+
install(from, nullptr);
41+
struct sigaction prev = {};
42+
install(to, &prev);
43+
44+
bool siginfo_from = (from == (T1 *)&sasigaction);
45+
if (siginfo_from) {
46+
assert(prev.sa_flags & SA_SIGINFO);
47+
assert(prev.sa_sigaction == (decltype(prev.sa_sigaction))from);
48+
} else {
49+
assert((prev.sa_flags & SA_SIGINFO) == 0);
50+
assert(prev.sa_handler == (decltype(prev.sa_handler))from);
51+
}
52+
}
53+
54+
template <typename T> void testAll(T *to) {
55+
test(&sahandler, to);
56+
test(&sasigaction, to);
57+
test(SIG_IGN, to);
58+
test(SIG_DFL, to);
59+
}
60+
61+
int main(void) {
62+
testAll(&sahandler);
63+
testAll(&sasigaction);
64+
testAll(SIG_IGN);
65+
testAll(SIG_DFL);
66+
}

0 commit comments

Comments
 (0)