From 17402876ec235dd66452983a39f8521f9ff62936 Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Fri, 17 Jan 2025 23:33:23 -0800 Subject: [PATCH] Block thread from receiving profile signal with stackwalk lock (#57089) This is Jameson's proposed amendment to the changes made in #57035 that introduced a deadlock on FreeBSD, amusingly in service of fixing a deadlock on Linux. On Linux and (non-macOS) BSD, instead of acquiring and releasing a lock on the profiler in `jl_with_stackwalk_lock`, we're just blocking the thread from receiving the profiler's `SIGUSR2` signal at all. This should fix #57058; I don't get the deadlock locally on FreeBSD with this change, but it's AArch64 instead of x86-64 like on CI, so let's see if this also makes CI happy. If so, closes #57059. Co-authored-by: Jameson Nash --- src/signals-unix.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/signals-unix.c b/src/signals-unix.c index 91d3378068f84..788539b1f5096 100644 --- a/src/signals-unix.c +++ b/src/signals-unix.c @@ -310,23 +310,14 @@ int exc_reg_is_write_fault(uintptr_t esr) { #include #include -typedef struct { - void (*f)(void*) JL_NOTSAFEPOINT; - void *ctx; -} callback_t; -static int with_dl_iterate_phdr_lock(struct dl_phdr_info *info, size_t size, void *data) -{ - jl_lock_profile(); - callback_t *callback = (callback_t*)data; - callback->f(callback->ctx); - jl_unlock_profile(); - return 1; // only call this once -} - void jl_with_stackwalk_lock(void (*f)(void*), void *ctx) { - callback_t callback = {f, ctx}; - dl_iterate_phdr(with_dl_iterate_phdr_lock, &callback); + sigset_t sset, oset; + sigemptyset(&sset); + sigaddset(&sset, SIGUSR2); + pthread_sigmask(SIG_BLOCK, &sset, &oset); + f(ctx); + pthread_sigmask(SIG_SETMASK, &oset, NULL); } #if defined(_OS_LINUX_) && (defined(_CPU_X86_64_) || defined(_CPU_X86_))