Skip to content

Commit 2f0a523

Browse files
authored
restore non-freebsd-unix fix for profiling (#57249)
Restores #57035, undo #57089 for non-FreeBSD. While I suggested doing this change for all platforms, I forgot that means non-FreeBSD platforms become vulnerable again to the very deadlock problems that #57035 was required to prevent. That fix seems to not be viable on FreeBSD due to known libc implementation problems on that platform. However, upon closer inspection of the questionable design implementation decisions they seem to have made here, the platform is likely not currently vulnerable to this libunwind bug in the first place: https://github.com/lattera/freebsd/blob/master/libexec/rtld-elf/rtld_lock.c#L120
1 parent daf865e commit 2f0a523

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

src/signals-unix.c

+25-5
Original file line numberDiff line numberDiff line change
@@ -310,14 +310,34 @@ int exc_reg_is_write_fault(uintptr_t esr) {
310310
#include <sys/eventfd.h>
311311
#include <link.h>
312312

313+
#ifndef _OS_FREEBSD_
314+
typedef struct {
315+
void (*f)(void*) JL_NOTSAFEPOINT;
316+
void *ctx;
317+
} callback_t;
318+
static int with_dl_iterate_phdr_lock(struct dl_phdr_info *info, size_t size, void *data)
319+
{
320+
jl_lock_profile();
321+
callback_t *callback = (callback_t*)data;
322+
callback->f(callback->ctx);
323+
jl_unlock_profile();
324+
return 1; // only call this once
325+
}
326+
#endif
327+
313328
void jl_with_stackwalk_lock(void (*f)(void*), void *ctx)
314329
{
315-
sigset_t sset, oset;
316-
sigemptyset(&sset);
317-
sigaddset(&sset, SIGUSR2);
318-
pthread_sigmask(SIG_BLOCK, &sset, &oset);
330+
#ifndef _OS_FREEBSD_
331+
callback_t callback = {f, ctx};
332+
dl_iterate_phdr(with_dl_iterate_phdr_lock, &callback);
333+
#else
334+
// FreeBSD makes the questionable decisions to use a terrible implementation of a spin
335+
// lock and to block all signals while a lock is held. However, that also means it is
336+
// not currently vulnerable to this libunwind bug that other platforms can encounter.
337+
jl_lock_profile();
319338
f(ctx);
320-
pthread_sigmask(SIG_SETMASK, &oset, NULL);
339+
jl_unlock_profile();
340+
#endif
321341
}
322342

323343
#if defined(_OS_LINUX_) && (defined(_CPU_X86_64_) || defined(_CPU_X86_))

0 commit comments

Comments
 (0)