Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,40 @@ else
LIBLMDB := $(build_libdir)/liblmdb.a
endif

# framehop-backed unwinder (opt-in via USE_FRAMEHOP=1). When enabled on a supported
# (os, arch), this defines JL_ENABLE_FRAMEHOP (so stackwalk.c routes the backtrace cursor
# to framehop) and links the libframehopunwind built by deps/framehopunwind.mk. libunwind
# stays linked (task.c context switching + proc-info still use it). The arch is further
# gated by the JL_USE_FRAMEHOP predicate in julia_internal.h (x86_64/aarch64 only).
# DO NOT MERGE: default USE_FRAMEHOP to 1 on supported platforms so every CI
# pipeline exercises the framehop unwinder. Unsupported combinations keep 0 so
# they don't trip the $(error) gates below; musl is skipped because
# LibFramehopUnwind_jll has no *-linux-musl artifact yet.
ifneq ($(filter $(OS),Linux FreeBSD Darwin),)
ifneq ($(filter $(ARCH),x86_64 aarch64),)
ifeq ($(DISABLE_LIBUNWIND), 0)
ifeq (,$(findstring musl,$(shell $(CC) -dumpmachine 2>/dev/null)))
USE_FRAMEHOP ?= 1
endif
endif
endif
endif
USE_FRAMEHOP ?= 0
FRAMEHOPUNWIND :=
ifeq ($(USE_FRAMEHOP), 1)
ifneq ($(DISABLE_LIBUNWIND), 0)
$(error USE_FRAMEHOP=1 requires libunwind (framehop replaces only the backtrace cursor; task.c context switching still uses libunwind) — unset DISABLE_LIBUNWIND)
endif
ifeq ($(findstring $(OS),Linux FreeBSD Darwin),)
$(error USE_FRAMEHOP=1 is not supported on OS=$(OS) (supported: Linux, FreeBSD, Darwin))
endif
ifeq ($(filter $(ARCH),x86_64 aarch64),)
$(error USE_FRAMEHOP=1 is not supported on ARCH=$(ARCH) (supported: x86_64, aarch64))
endif
FRAMEHOPUNWIND := -lframehopunwind
JCPPFLAGS += -DJL_ENABLE_FRAMEHOP
endif

ifeq ($(origin LLVM_CONFIG), undefined)
ifeq ($(USE_SYSTEM_LLVM), 1)
LLVM_CONFIG := llvm-config$(EXE)
Expand Down Expand Up @@ -1504,7 +1538,7 @@ CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.35|GLIBCXX_3\.5\.|GLIBCXX_4\.
# Note: we explicitly _do not_ define `CSL` here, since it requires some more
# advanced techniques to decide whether it should be installed from a BB source
# or not. See `deps/csl.mk` for more detail.
BB_PROJECTS := BLASTRAMPOLINE OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP OPENSSL LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB ZSTD P7ZIP LLD LIBTRACYCLIENT BOLT
BB_PROJECTS := BLASTRAMPOLINE OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP OPENSSL LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB ZSTD P7ZIP LLD LIBTRACYCLIENT BOLT FRAMEHOPUNWIND

define SET_BB_DEFAULT
# First, check to see if BB is disabled on a global setting
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,10 @@ ifeq ($(WITH_TRACY),1)
JL_PRIVATE_LIBS-0 += libTracyClient
endif

ifeq ($(USE_FRAMEHOP),1)
# libjulia-internal and libjulia-codegen link against this.
JL_PRIVATE_LIBS-0 += libframehopunwind
endif

ifeq ($(OS),Darwin)
ifeq ($(USE_SYSTEM_BLAS),1)
Expand Down
2 changes: 1 addition & 1 deletion contrib/refresh_checksums.mk
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ CLANG_TRIPLETS=$(filter %-darwin %-freebsd,$(TRIPLETS))
NON_CLANG_TRIPLETS=$(filter-out %-darwin %-freebsd,$(TRIPLETS))

# These are the projects currently using BinaryBuilder; both GCC-expanded and non-GCC-expanded:
BB_PROJECTS=openssl libssh2 nghttp2 mpfr curl libgit2 pcre libuv unwind llvmunwind dsfmt objconv p7zip zlib zstd libsuitesparse openlibm blastrampoline libtracyclient mmtk_julia compilerrt
BB_PROJECTS=openssl libssh2 nghttp2 mpfr curl libgit2 pcre libuv unwind llvmunwind dsfmt objconv p7zip zlib zstd libsuitesparse openlibm blastrampoline libtracyclient mmtk_julia compilerrt framehopunwind
BB_GCC_EXPANDED_PROJECTS=openblas csl
BB_CXX_EXPANDED_PROJECTS=gmp llvm clang llvm-tools lld
# These are non-BB source-only deps
Expand Down
9 changes: 8 additions & 1 deletion deps/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ endif

DEP_LIBS += cpufeatures

# framehop-backed unwinder (opt-in via USE_FRAMEHOP=1; LibFramehopUnwind_jll by default,
# source build with cargo via USE_BINARYBUILDER_FRAMEHOPUNWIND=0).
ifeq ($(USE_FRAMEHOP), 1)
DEP_LIBS += framehopunwind
endif

ifeq ($(USE_SYSTEM_LLVM), 0)
DEP_LIBS += llvm
endif
Expand Down Expand Up @@ -213,7 +219,7 @@ DEP_LIBS_STAGED_ALL := llvm llvm-tools clang llvmunwind unwind libuv pcre \
openlibm dsfmt blastrampoline openblas lapack gmp mpfr patchelf utf8proc \
objconv openssl libssh2 nghttp2 curl libgit2 libwhich zlib zstd lmdb p7zip csl \
sanitizers libsuitesparse lld libtracyclient ittapi nvtx \
terminfo cpufeatures
terminfo cpufeatures framehopunwind
DEP_LIBS_ALL := $(DEP_LIBS_STAGED_ALL)

ifneq ($(USE_BINARYBUILDER_OPENBLAS),0)
Expand Down Expand Up @@ -286,6 +292,7 @@ include $(SRCDIR)/gmp.mk
include $(SRCDIR)/mpfr.mk
include $(SRCDIR)/patchelf.mk
include $(SRCDIR)/cpufeatures.mk
include $(SRCDIR)/framehopunwind.mk
include $(SRCDIR)/openssl.mk
include $(SRCDIR)/libssh2.mk
include $(SRCDIR)/nghttp2.mk
Expand Down
14 changes: 14 additions & 0 deletions deps/checksums/framehopunwind
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
LibFramehopUnwind.v0.1.2+0.aarch64-apple-darwin.tar.gz/md5/ca44618652f2a2037e081d0e0e901555
LibFramehopUnwind.v0.1.2+0.aarch64-apple-darwin.tar.gz/sha512/f91a5e250c0fc6aec87839f07071e49d1d75733c820fc46e0dc78fcd0f31bb997f9be559e2bf07e978f866a151fb77030fc9c1323f564df12d3ed1e4987c904a
LibFramehopUnwind.v0.1.2+0.aarch64-linux-gnu.tar.gz/md5/b04a9940cee25cba410e05d07bc3d369
LibFramehopUnwind.v0.1.2+0.aarch64-linux-gnu.tar.gz/sha512/91cc159091fa7a967b790ae5885fa70148b4efae8be238d7e74ed96f2ea94c6da9ebb05fa23d5f0b2111e003b6f030f8f5d9882c3ba48c430c1cf158702c6dfe
LibFramehopUnwind.v0.1.2+0.x86_64-apple-darwin.tar.gz/md5/21b4754af5503f32de51550b14c681c3
LibFramehopUnwind.v0.1.2+0.x86_64-apple-darwin.tar.gz/sha512/929ebe9b82f9226558662028a5fcc8adc067339f202f1e6f4ab5b8f64c6a5d8661aa6ce7692688605ac4fda16ad8a8e4b3ada8fd03b24517591faedba8ca1970
LibFramehopUnwind.v0.1.2+0.x86_64-linux-gnu.tar.gz/md5/617fe7b5deb83a5c2d496fd79ace49c2
LibFramehopUnwind.v0.1.2+0.x86_64-linux-gnu.tar.gz/sha512/590459efaaffdbf19b1d2d6b8d98c6a7b088b86fef85ccb7fdbcaffe98f4f70865ab2e0422491b3d4255e2d863d465fe167b065bc3423ed4decac33ae2920552
LibFramehopUnwind.v0.1.2+0.x86_64-unknown-freebsd.tar.gz/md5/7e5942d2d0cd0cdfdabc3e3df41ad29c
LibFramehopUnwind.v0.1.2+0.x86_64-unknown-freebsd.tar.gz/sha512/85e646fee117834e1d35cf360a8ad14efeadc4a85981a2cddcc75ff26fabfbc46c2ac9d01b165f193c2c803c0d5c8d45bbee6d3607f4de95b49cfd758235e487
LibFramehopUnwind.v0.1.2+0.x86_64-w64-mingw32.tar.gz/md5/51963cac6b098ddd0b96b97eaac4c54a
LibFramehopUnwind.v0.1.2+0.x86_64-w64-mingw32.tar.gz/sha512/a0ce67e4472b4df8803c3a162bdac2eae50ccde2188c47f9e261c7da7b50892fdc6e6500b97032f30bcd8a0964f1436a8bfd937217ee4ddcf93c924ce8516113
framehopunwind-745330dc336f4237cac36db79b5c9b6bc15c0232.tar.gz/md5/dd7ce5830b11aa9d1caca8fda8735b64
framehopunwind-745330dc336f4237cac36db79b5c9b6bc15c0232.tar.gz/sha512/64a190d24ed7e899b4b2288f6b17ecd6f8483fa777416e21f06fd36de07a325c0a7fd20b478abe03f8e89c95cd0ceec78d6111723dbd2919978f353324551884
62 changes: 62 additions & 0 deletions deps/framehopunwind.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
## FRAMEHOPUNWIND ##
# framehop-backed, libunwind-compatible unwinder. Replaces libunwind's *backtrace* path.
# Default: the prebuilt LibFramehopUnwind_jll artifact (bb-install). Source build
# (USE_BINARYBUILDER_FRAMEHOPUNWIND=0) needs a Rust toolchain, like mmtk_julia.

ifneq ($(USE_BINARYBUILDER_FRAMEHOPUNWIND),1)

FRAMEHOPUNWIND_GIT_URL := https://github.com/gbaraldi/framehopunwind.git
FRAMEHOPUNWIND_TAR_URL = https://api.github.com/repos/gbaraldi/framehopunwind/tarball/$1
$(eval $(call git-external,framehopunwind,FRAMEHOPUNWIND,,,$(BUILDDIR)))

FRAMEHOPUNWIND_BUILDDIR := $(BUILDDIR)/$(FRAMEHOPUNWIND_SRC_DIR)

# Rust toolchain (override CARGO in Make.user if it is not on PATH).
CARGO ?= cargo

ifeq ($(USE_FRAMEHOP), 1)
ifneq ($(XC_HOST),)
$(error the framehopunwind source build does not support cross-compilation (cargo builds for the host triple); use USE_BINARYBUILDER_FRAMEHOPUNWIND=1)
endif
endif

# NB: the first build fetches the crates.io deps (pinned via --locked); a fully-offline
# build needs vendored crates or the jll. The `+` hands make's jobserver to cargo.
$(FRAMEHOPUNWIND_BUILDDIR)/build-compiled: $(FRAMEHOPUNWIND_BUILDDIR)/source-extracted
@command -v $(CARGO) >/dev/null 2>&1 || { \
echo "ERROR: building framehopunwind from source requires a Rust toolchain (cargo >= 1.88)." >&2; \
echo " Install one via https://rustup.rs, set CARGO in Make.user, or use" >&2; \
echo " USE_BINARYBUILDER_FRAMEHOPUNWIND=1 for the prebuilt artifact." >&2; \
exit 1; }
+cd $(dir $<) && \
$(CARGO) build --release --locked --offline 2>/dev/null || \
$(CARGO) build --release --locked
echo 1 > $@

define FRAMEHOPUNWIND_INSTALL
mkdir -p $2/$$(build_includedir)
mkdir -p $2/$$(build_shlibdir)
cp $1/include/framehopunwind.h $2/$$(build_includedir)/
cp $1/target/release/libframehopunwind.$$(SHLIB_EXT) $2/$$(build_shlibdir)/
endef
$(eval $(call staged-install, \
framehopunwind,$(FRAMEHOPUNWIND_SRC_DIR), \
FRAMEHOPUNWIND_INSTALL,,, \
$$(INSTALL_NAME_CMD)libframehopunwind.$$(SHLIB_EXT) $$(build_shlibdir)/libframehopunwind.$$(SHLIB_EXT)))

clean-framehopunwind:
-rm -f $(FRAMEHOPUNWIND_BUILDDIR)/build-compiled
-rm -rf $(FRAMEHOPUNWIND_BUILDDIR)/target

get-framehopunwind: $(FRAMEHOPUNWIND_SRC_FILE)
extract-framehopunwind: $(FRAMEHOPUNWIND_BUILDDIR)/source-extracted
configure-framehopunwind: extract-framehopunwind
compile-framehopunwind: $(FRAMEHOPUNWIND_BUILDDIR)/build-compiled
fastcheck-framehopunwind: check-framehopunwind
check-framehopunwind: compile-framehopunwind

else

$(eval $(call bb-install,framehopunwind,FRAMEHOPUNWIND,false))

endif # USE_BINARYBUILDER_FRAMEHOPUNWIND
9 changes: 9 additions & 0 deletions deps/framehopunwind.version
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# -*- makefile -*-

## jll artifact (JuliaBinaryWrappers/LibFramehopUnwind_jll.jl; built from the SHA1 below) ##
FRAMEHOPUNWIND_JLL_NAME := LibFramehopUnwind
FRAMEHOPUNWIND_JLL_VER := 0.1.2+0

## source build ##
FRAMEHOPUNWIND_BRANCH=main
FRAMEHOPUNWIND_SHA1=745330dc336f4237cac36db79b5c9b6bc15c0232
8 changes: 8 additions & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,14 @@ RT_LIBS := $(call whole_archive,$(LIBUV)) $(call whole_archive,$(LIBUTF8PROC)) $
CG_LIBS := $(LIBUNWIND) $(CG_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI) $(LIBLMDB)
endif

# framehop-backed unwinder: link the deps-built libframehopunwind into both
# libjulia-internal (stackwalk.c) and libjulia-codegen (debuginfo.cpp register_eh_frames),
# which both call into framehop and so must share its single loaded instance. The header
# is found via -I$(build_includedir) and the .so via COMMON_LIBPATHS. $(FRAMEHOPUNWIND) is
# set by Make.inc (empty unless USE_FRAMEHOP=1 on a supported os/arch).
RT_LIBS += $(FRAMEHOPUNWIND)
CG_LIBS += $(FRAMEHOPUNWIND)

ifeq ($(USEGCC),1)
ifeq ($(USE_RT_STATIC_LIBGCC),1)
RT_LIBS += -static-libgcc
Expand Down
26 changes: 25 additions & 1 deletion src/debuginfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1370,13 +1370,21 @@ void register_eh_frames(uint8_t *Addr, size_t Size)
processFDEs((char*)Addr, Size, [](const char *Entry) JL_NOTSAFEPOINT {
getJITDebugRegistry().libc_frames.libc_register_frame(Entry);
});
#ifdef JL_USE_FRAMEHOP
// Also register the JIT .eh_frame with framehop (the backtrace unwinder). The code
// range is derived from the FDEs; bytes are copied, so Addr may be freed later.
fh_register_jit_auto(Addr, Size);
#endif
}

void deregister_eh_frames(uint8_t *Addr, size_t Size)
{
processFDEs((char*)Addr, Size, [](const char *Entry) JL_NOTSAFEPOINT {
getJITDebugRegistry().libc_frames.libc_deregister_frame(Entry);
});
#ifdef JL_USE_FRAMEHOP
fh_deregister_jit_eh_frame(Addr);
#endif
}

#elif (defined(_OS_LINUX_) || defined(_OS_FREEBSD_)) && \
Expand Down Expand Up @@ -1560,7 +1568,8 @@ static DW_EH_PE parseCIE(const uint8_t *Addr, const uint8_t *End) JL_NOTSAFEPOIN

void register_eh_frames(uint8_t *Addr, size_t Size)
{
// System unwinder
// System unwinder (used by C++ exception handling) — register regardless of which
// backtrace unwinder we use.
jl_profile_atomic([&]() JL_NOTSAFEPOINT {
__register_frame(Addr);
});
Expand Down Expand Up @@ -1692,6 +1701,15 @@ void register_eh_frames(uint8_t *Addr, size_t Size)
jl_profile_atomic([&]() JL_NOTSAFEPOINT {
_U_dyn_register(di);
});

#ifdef JL_USE_FRAMEHOP
// Also register with framehop (the backtrace unwinder). [start_ip, end_ip) is the code
// range already computed above; the .eh_frame bytes are copied internally, so Julia may
// free its buffer after deregistration.
jl_profile_atomic([&]() JL_NOTSAFEPOINT {
fh_register_jit(Addr, Size, (uint64_t)start_ip, (uint64_t)end_ip);
});
#endif
}

void deregister_eh_frames(uint8_t *Addr, size_t Size)
Expand All @@ -1702,6 +1720,12 @@ void deregister_eh_frames(uint8_t *Addr, size_t Size)
// Deregistering with our unwinder (_U_dyn_cancel) requires a lookup table
// to find the allocated entry above (or looking into libunwind's internal
// data structures).
#ifdef JL_USE_FRAMEHOP
// framehop keys JIT modules by .eh_frame address, so Addr is enough to deregister.
jl_profile_atomic([&]() JL_NOTSAFEPOINT {
fh_deregister_jit_eh_frame(Addr);
});
#endif
}

#else
Expand Down
13 changes: 12 additions & 1 deletion src/dlload.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ JL_NO_SANITIZE void *jl_dlopen(const char *filename, unsigned flags)
struct link_map *map = (struct link_map*)hnd;
if (filename && map)
ForEachMappedRegion(map, __msan_unpoison);
#endif
#ifdef JL_USE_FRAMEHOP
// A newly-loaded object means new modules to unwind through; re-scan (off-signal).
if (hnd && !(flags & JL_RTLD_NOLOAD))
fh_modules_refresh();
#endif
return hnd;
}
Expand Down Expand Up @@ -309,7 +314,13 @@ int jl_dlclose(void *handle)
dlerror(); /* Reset error status. */
return -1;
}
return dlclose(handle);
int rc = dlclose(handle);
#ifdef JL_USE_FRAMEHOP
// Mirror the jl_dlopen hook so unloaded ranges are not unwound with stale info.
if (rc == 0)
fh_modules_refresh();
#endif
return rc;
#endif
}

Expand Down
5 changes: 5 additions & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,11 @@ JL_DLLEXPORT void jl_init_(jl_image_buf_t sysimage)
jl_init_engine();
jl_init_threading();
jl_init_threadinginfra();
#ifdef JL_USE_FRAMEHOP
// Bring up framehop before signal handlers are installed so early crashes get
// native backtraces. Idempotent; thread 0 registers in jl_init_threadtls below.
fh_init(0);
#endif
if (jl_options.handle_signals == JL_OPTIONS_HANDLE_SIGNALS_ON)
jl_install_default_signal_handlers();

Expand Down
45 changes: 44 additions & 1 deletion src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1557,6 +1557,16 @@ typedef struct {
int inlined;
} jl_frame_t;

// framehop-backed unwinding (opt-in). The build defines JL_ENABLE_FRAMEHOP to turn this
// on; JL_USE_FRAMEHOP is then derived for the (os, arch) combinations framehop supports.
// When off, everything below is byte-for-byte the existing libunwind/dbghelp path.
// Requires libunwind (the framehop path lives in the !JL_DISABLE_LIBUNWIND branch below).
#if !defined(JL_USE_FRAMEHOP) && defined(JL_ENABLE_FRAMEHOP) && !defined(JL_DISABLE_LIBUNWIND)
# if (defined(_OS_LINUX_) || defined(_OS_FREEBSD_) || defined(_OS_DARWIN_)) && (defined(_CPU_X86_64_) || defined(_CPU_AARCH64_))
# define JL_USE_FRAMEHOP 1
# endif
#endif

#ifdef _OS_WINDOWS_
#include <dbghelp.h>
JL_DLLEXPORT EXCEPTION_DISPOSITION NTAPI __julia_personality(
Expand All @@ -1581,7 +1591,20 @@ void jl_profile_process_dll_events(void) JL_NOTSAFEPOINT;
# include <libunwind.h>
#pragma GCC visibility pop
typedef unw_context_t bt_context_t;
// framehop integration is additive: libunwind stays linked (task.c context switching and
// proc-info lookup still use it), but the *backtrace* cursor is framehop's. On
// Linux/FreeBSD unw_context_t == ucontext_t, so jl_unw_init can extract framehop's
// registers straight from a bt_context_t.
# ifdef JL_USE_FRAMEHOP
// Default visibility so the fh_* references bind to the shared libframehopunwind
// (Julia builds with -fvisibility=hidden; same treatment as libunwind.h above).
# pragma GCC visibility push(default)
# include "framehopunwind.h"
# pragma GCC visibility pop
typedef fh_cursor bt_cursor_t;
# else
typedef unw_cursor_t bt_cursor_t;
# endif
# if (!defined(SYSTEM_LIBUNWIND) || UNW_VERSION_MAJOR > 1 || \
(UNW_VERSION_MAJOR == 1 && UNW_VERSION_MINOR != 0 && UNW_VERSION_MINOR != 1))
// Enable our memory manager only for libunwind with our patch or
Expand All @@ -1598,9 +1621,29 @@ size_t rec_backtrace(jl_bt_element_t *bt_data, size_t maxsize, int skip) JL_NOTS
// which was asynchronously interrupted.
size_t rec_backtrace_ctx(jl_bt_element_t *bt_data, size_t maxsize, bt_context_t *ctx,
jl_gcframe_t *pgcstack) JL_NOTSAFEPOINT;
#ifdef LLVMLIBUNWIND
// The macOS profiler's compact-unwind-fault DWARF retry; libunwind-only (framehop
// recovers faults via safe_restore instead, see signals-mach.c).
#if defined(LLVMLIBUNWIND) && !defined(JL_USE_FRAMEHOP)
size_t rec_backtrace_ctx_dwarf(jl_bt_element_t *bt_data, size_t maxsize, bt_context_t *ctx, jl_gcframe_t *pgcstack) JL_NOTSAFEPOINT;
#endif
// rec_backtrace_ctx for a context belonging to another (suspended) thread or a
// not-currently-running task; under framehop the target supplies exact stack bounds,
// elsewhere the extra arguments are ignored.
#ifdef JL_USE_FRAMEHOP
size_t rec_backtrace_ctx_target(jl_bt_element_t *bt_data, size_t maxsize, bt_context_t *ctx,
jl_gcframe_t *pgcstack, jl_ptls_t target_ptls,
jl_task_t *target_task) JL_NOTSAFEPOINT;
#else
STATIC_INLINE size_t rec_backtrace_ctx_target(jl_bt_element_t *bt_data, size_t maxsize,
bt_context_t *ctx, jl_gcframe_t *pgcstack,
jl_ptls_t target_ptls,
jl_task_t *target_task) JL_NOTSAFEPOINT
{
(void)target_ptls;
(void)target_task;
return rec_backtrace_ctx(bt_data, maxsize, ctx, pgcstack);
}
#endif
JL_DLLEXPORT jl_value_t *jl_get_backtrace(void) JL_CANSAFEPOINT;
JL_DLLEXPORT jl_value_t *jl_backtrace_from_here(int returnsp, int skip) JL_CANSAFEPOINT;
void jl_fprint_critical_error(ios_t *t, int sig, int si_code, bt_context_t *context, jl_task_t *ct) JL_CANSAFEPOINT;
Expand Down
Loading