};
#endif
+ struct __sanitizer_siginfo {
+ // The size is determined by looking at sizeof of real siginfo_t on linux.
+ u64 opaque[128 / sizeof(u64)];
+ };
+
// Linux system headers define the 'sa_handler' and 'sa_sigaction' macros.
#if SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 64)
struct __sanitizer_sigaction {
unsigned sa_flags;
union {
- void (*sigaction)(int sig, void *siginfo, void *uctx);
+ void (*sigaction)(int sig, __sanitizer_siginfo *siginfo, void *uctx);
void (*handler)(int sig);
};
__sanitizer_sigset_t sa_mask;
struct __sanitizer_sigaction {
unsigned sa_flags;
union {
- void (*sigaction)(int sig, void *siginfo, void *uctx);
+ void (*sigaction)(int sig, __sanitizer_siginfo *siginfo, void *uctx);
void (*handler)(int sig);
};
__sanitizer_sigset_t sa_mask;
#elif SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32)
struct __sanitizer_sigaction {
union {
- void (*sigaction)(int sig, void *siginfo, void *uctx);
+ void (*sigaction)(int sig, __sanitizer_siginfo *siginfo, void *uctx);
void (*handler)(int sig);
};
__sanitizer_sigset_t sa_mask;
unsigned int sa_flags;
#endif
union {
- void (*sigaction)(int sig, void *siginfo, void *uctx);
+ void (*sigaction)(int sig, __sanitizer_siginfo *siginfo, void *uctx);
void (*handler)(int sig);
};
#if SANITIZER_FREEBSD
unsigned int sa_flags;
union {
void (*handler)(int signo);
- void (*sigaction)(int signo, void *info, void *ctx);
+ void (*sigaction)(int signo, __sanitizer_siginfo *info, void *ctx);
};
__sanitizer_kernel_sigset_t sa_mask;
void (*sa_restorer)(void);
struct __sanitizer_kernel_sigaction_t {
union {
void (*handler)(int signo);
- void (*sigaction)(int signo, void *info, void *ctx);
+ void (*sigaction)(int signo, __sanitizer_siginfo *info, void *ctx);
};
unsigned long sa_flags;
void (*sa_restorer)(void);
const int kSigCount = 65;
#endif
-struct my_siginfo_t {
- // The size is determined by looking at sizeof of real siginfo_t on linux.
- u64 opaque[128 / sizeof(u64)];
-};
-
#ifdef __mips__
struct ucontext_t {
u64 opaque[768 / sizeof(u64) + 1];
# define F_TEST 3 /* Test a region for other processes locks. */
typedef void (*sighandler_t)(int sig);
-typedef void (*sigactionhandler_t)(int sig, my_siginfo_t *siginfo, void *uctx);
-
-#if SANITIZER_ANDROID
-struct sigaction_t {
- u32 sa_flags;
- union {
- sighandler_t sa_handler;
- sigactionhandler_t sa_sigaction;
- };
- __sanitizer_sigset_t sa_mask;
- void (*sa_restorer)();
-};
-#elif SANITIZER_NETBSD
-struct sigaction_t {
- union {
- sighandler_t sa_handler;
- sigactionhandler_t sa_sigaction;
- };
- __sanitizer_sigset_t sa_mask;
- int sa_flags;
-};
-#else
-struct sigaction_t {
-#ifdef __mips__
- u32 sa_flags;
-#endif
- union {
- sighandler_t sa_handler;
- sigactionhandler_t sa_sigaction;
- };
-#if SANITIZER_FREEBSD
- int sa_flags;
- __sanitizer_sigset_t sa_mask;
-#elif SANITIZER_MAC
- __sanitizer_sigset_t sa_mask;
- int sa_flags;
-#else
- __sanitizer_sigset_t sa_mask;
-#ifndef __mips__
- int sa_flags;
-#endif
- void (*sa_restorer)();
-#endif
-};
-#endif
+typedef void (*sigactionhandler_t)(int sig, __sanitizer_siginfo *siginfo,
+ void *uctx);
const sighandler_t SIG_DFL = (sighandler_t)0;
const sighandler_t SIG_IGN = (sighandler_t)1;
struct SignalDesc {
bool armed;
bool sigaction;
- my_siginfo_t siginfo;
+ __sanitizer_siginfo siginfo;
ucontext_t ctx;
};
// The object is 64-byte aligned, because we want hot data to be located
// in a single cache line if possible (it's accessed in every interceptor).
ALIGNED(64) LibIgnore libignore;
- sigaction_t sigactions[kSigCount];
+ __sanitizer_sigaction sigactions[kSigCount];
#if !SANITIZER_MAC && !SANITIZER_NETBSD
unsigned finalize_key;
#endif
namespace __tsan {
static void CallUserSignalHandler(ThreadState *thr, bool sync, bool acquire,
- bool sigact, int sig, my_siginfo_t *info, void *uctx) {
- sigaction_t *sigactions = interceptor_ctx()->sigactions;
+ bool sigact, int sig,
+ __sanitizer_siginfo *info, void *uctx) {
+ __sanitizer_sigaction *sigactions = interceptor_ctx()->sigactions;
if (acquire)
Acquire(thr, 0, (uptr)&sigactions[sig]);
// Signals are generally asynchronous, so if we receive a signals when
// This code races with sigaction. Be careful to not read sa_sigaction twice.
// Also need to remember pc for reporting before the call,
// because the handler can reset it.
- volatile uptr pc = sigact ?
- (uptr)sigactions[sig].sa_sigaction :
- (uptr)sigactions[sig].sa_handler;
+ volatile uptr pc =
+ sigact ? (uptr)sigactions[sig].sigaction : (uptr)sigactions[sig].handler;
if (pc != (uptr)SIG_DFL && pc != (uptr)SIG_IGN) {
if (sigact)
((sigactionhandler_t)pc)(sig, info, uctx);
}
void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig,
- my_siginfo_t *info, void *ctx) {
+ __sanitizer_siginfo *info,
+ void *ctx) {
ThreadState *thr = cur_thread();
ThreadSignalContext *sctx = SigCtx(thr);
if (sig < 0 || sig >= kSigCount) {
rtl_generic_sighandler(false, sig, 0, 0);
}
-static void rtl_sigaction(int sig, my_siginfo_t *info, void *ctx) {
+static void rtl_sigaction(int sig, __sanitizer_siginfo *info, void *ctx) {
rtl_generic_sighandler(true, sig, info, ctx);
}
-TSAN_INTERCEPTOR(int, sigaction, int sig, sigaction_t *act, sigaction_t *old) {
+TSAN_INTERCEPTOR(int, sigaction, int sig, __sanitizer_sigaction *act,
+ __sanitizer_sigaction *old) {
// Note: if we call REAL(sigaction) directly for any reason without proxying
// the signal handler through rtl_sigaction, very bad things will happen.
// The handler will run synchronously and corrupt tsan per-thread state.
SCOPED_INTERCEPTOR_RAW(sigaction, sig, act, old);
- sigaction_t *sigactions = interceptor_ctx()->sigactions;
+ __sanitizer_sigaction *sigactions = interceptor_ctx()->sigactions;
if (old)
internal_memcpy(old, &sigactions[sig], sizeof(*old));
if (act == 0)
// Copy act into sigactions[sig].
// Can't use struct copy, because compiler can emit call to memcpy.
// Can't use internal_memcpy, because it copies byte-by-byte,
- // and signal handler reads the sa_handler concurrently. It it can read
+ // and signal handler reads the handler concurrently. It it can read
// some bytes from old value and some bytes from new value.
// Use volatile to prevent insertion of memcpy.
- sigactions[sig].sa_handler = *(volatile sighandler_t*)&act->sa_handler;
+ sigactions[sig].handler = *(volatile sighandler_t *)&act->handler;
sigactions[sig].sa_flags = *(volatile int*)&act->sa_flags;
internal_memcpy(&sigactions[sig].sa_mask, &act->sa_mask,
sizeof(sigactions[sig].sa_mask));
#if !SANITIZER_FREEBSD && !SANITIZER_MAC && !SANITIZER_NETBSD
sigactions[sig].sa_restorer = act->sa_restorer;
#endif
- sigaction_t newact;
+ __sanitizer_sigaction newact;
internal_memcpy(&newact, act, sizeof(newact));
internal_sigfillset(&newact.sa_mask);
- if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL) {
+ if (act->handler != SIG_IGN && act->handler != SIG_DFL) {
if (newact.sa_flags & SA_SIGINFO)
- newact.sa_sigaction = rtl_sigaction;
+ newact.sigaction = rtl_sigaction;
else
- newact.sa_handler = rtl_sighandler;
+ newact.handler = rtl_sighandler;
}
ReleaseStore(thr, pc, (uptr)&sigactions[sig]);
int res = REAL(sigaction)(sig, &newact, 0);
}
TSAN_INTERCEPTOR(sighandler_t, signal, int sig, sighandler_t h) {
- sigaction_t act;
- act.sa_handler = h;
+ __sanitizer_sigaction act;
+ act.handler = h;
internal_memset(&act.sa_mask, -1, sizeof(act.sa_mask));
act.sa_flags = 0;
- sigaction_t old;
+ __sanitizer_sigaction old;
int res = sigaction(sig, &act, &old);
if (res)
return SIG_ERR;
- return old.sa_handler;
+ return old.handler;
}
TSAN_INTERCEPTOR(int, raise, int sig) {