From 1ec62f500a29e126078108e0bf4ef8c0b6cd2356 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Wed, 27 May 2026 03:26:45 -0400 Subject: [PATCH] Apply libunwind preload to child Julia processes The libunwind workaround in 933a238 (JuliaInterop#238) preloads Julia's bundled libunwind in the parent R process via dyn.load, which fixes the in-process embedded Julia path (.julia$cmd / setup.jl). It does not propagate to child Julia processes spawned by julia_line via system2 -- install_dependency.jl, rebuildRCall.jl, and the version / libjulia probes early in julia_setup. On Ubuntu 24+, R's startup wrapper prepends /usr/lib/x86_64-linux-gnu to LD_LIBRARY_PATH; the child Julia inherits this and loads system libunwind 1.6.2 (libunwind/libunwind#637) -> SIGSEGV during Pkg.add in install_dependency.jl. The user then sees a confusing "Package Suppressor not found" from setup.jl, because the subprocess that was supposed to install it crashed. Set LD_PRELOAD on the child to Julia's bundled libunwind, mirroring the in-process dyn.load and closing the gap. Reported in SciML/diffeqr#49. Co-Authored-By: Chris Rackauckas --- R/aaa.R | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/R/aaa.R b/R/aaa.R index 9fd0806..d685417 100644 --- a/R/aaa.R +++ b/R/aaa.R @@ -91,7 +91,28 @@ julia_locate <- function(JULIA_HOME = NULL){ ## It is currently used in julia_setup in zzz.R and julia_library in package.R julia_line <- function(command, ...){ command <- c("--startup-file=no", command) - system2(file.path(.julia$bin_dir, "julia"), shQuote(command), ...) + + # Workaround for Ubuntu libunwind issue (see JuliaInterop/JuliaCall#238). + # julia_setup in zzz.R preloads Julia's bundled libunwind in the parent R + # process via dyn.load, but child Julia processes spawned here inherit R's + # LD_LIBRARY_PATH (set by the R startup wrapper to /usr/lib/x86_64-linux-gnu) + # and otherwise load the buggy system libunwind 1.6.2, which segfaults + # during e.g. Pkg.add in install_dependency.jl. + extra_env <- character(0) + if (identical(get_os(), "linux") && !is.null(.julia$bin_dir)) { + libunwind_paths <- Sys.glob(file.path(.julia$bin_dir, "..", "lib", + "julia", "libunwind.so*")) + if (length(libunwind_paths) > 0) { + existing <- Sys.getenv("LD_PRELOAD") + extra_env <- paste0("LD_PRELOAD=", + paste(c(libunwind_paths[1], + if (nzchar(existing)) existing), + collapse = " ")) + } + } + + system2(file.path(.julia$bin_dir, "julia"), shQuote(command), + env = extra_env, ...) # r[length(r)] }