Skip to content

Commit

Permalink
restore non-freebsd-unix fix for profiling (#57249)
Browse files Browse the repository at this point in the history
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

(cherry picked from commit 2f0a523)
  • Loading branch information
vtjnash authored and KristofferC committed Feb 6, 2025
1 parent 033492e commit 171ce73
Showing 1 changed file with 25 additions and 5 deletions.
30 changes: 25 additions & 5 deletions src/signals-unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,14 +310,34 @@ int exc_reg_is_write_fault(uintptr_t esr) {
#include <sys/eventfd.h>
#include <link.h>

#ifndef _OS_FREEBSD_
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
}
#endif

void jl_with_stackwalk_lock(void (*f)(void*), void *ctx)
{
sigset_t sset, oset;
sigemptyset(&sset);
sigaddset(&sset, SIGUSR2);
pthread_sigmask(SIG_BLOCK, &sset, &oset);
#ifndef _OS_FREEBSD_
callback_t callback = {f, ctx};
dl_iterate_phdr(with_dl_iterate_phdr_lock, &callback);
#else
// FreeBSD makes the questionable decisions to use a terrible implementation of a spin
// lock and to block all signals while a lock is held. However, that also means it is
// not currently vulnerable to this libunwind bug that other platforms can encounter.
jl_lock_profile();
f(ctx);
pthread_sigmask(SIG_SETMASK, &oset, NULL);
jl_unlock_profile();
#endif
}

#if defined(_OS_LINUX_) && (defined(_CPU_X86_64_) || defined(_CPU_X86_))
Expand Down

0 comments on commit 171ce73

Please sign in to comment.