# Phase 1.1 follow-up: local Guile build validates the FreeBSD subprocess fix Date: 2026-04-01 ## Summary A local build of `~/repos/guile` was used to validate the previously identified FreeBSD subprocess crash. Result: - the packaged FreeBSD Guile (`/usr/local/bin/guile3`) still reproduces the crash - a locally built Guile from `~/repos/guile` works correctly for: - `system*` - `spawn` - `open-pipe*` - no local source patch to `~/repos/guile` was required because the local checkout already contains the upstream fix commit The relevant upstream commit already present in `~/repos/guile` is: - `eb828801f621d3e130b6fe88cfc4acaa69b98a03` - subject: `Don't use posix_spawn_file_actions_addclosefrom_np with glib posix_spawn` The tested local checkout revision was: - `bbf2baa10f6cc8dfdd9e4ea14b503d748287a03d` ## Additional build tooling installed on FreeBSD To build Guile from the local checkout, these packages were installed: ```sh sudo pkg install -y autoconf automake libtool gettext-tools texinfo help2man gperf pkgconf ``` An extra FreeBSD-specific detail also mattered: - Guile's `autogen.sh` expects GNU `m4` - FreeBSD base `/usr/bin/m4` is not GNU `m4` - the installed GNU version is available as `gm4` - `autogen.sh` therefore had to be run with `M4=gm4` ## Build procedure used A disposable build copy was created from the local repo to avoid polluting `~/repos/guile`: ```sh git clone --shared ~/repos/guile /tmp/guile-freebsd-validate-src ``` Autotools bootstrap: ```sh cd /tmp/guile-freebsd-validate-src M4=gm4 ./autogen.sh ``` Configure: ```sh cd /tmp/guile-freebsd-validate-build env \ M4=gm4 \ MAKE=gmake \ PKG_CONFIG=pkg-config \ PKG_CONFIG_PATH=/usr/local/libdata/pkgconfig:/usr/local/lib/pkgconfig \ CPPFLAGS='-I/usr/local/include' \ LDFLAGS='-L/usr/local/lib -Wl,-rpath,/usr/local/lib' \ /tmp/guile-freebsd-validate-src/configure \ --prefix=/tmp/guile-freebsd-validate-install \ --with-bdw-gc=bdw-gc-threaded \ --with-libgmp-prefix=/usr/local \ --with-libunistring-prefix=/usr/local \ --with-libiconv-prefix=/usr/local \ --with-libintl-prefix=/usr/local ``` Build and install: ```sh cd /tmp/guile-freebsd-validate-build gmake -j4 gmake install ``` ## Important validation detail: the executable must load the matching local libguile Immediately after installation, running `/tmp/guile-freebsd-validate-install/bin/guile` without adjusting the dynamic linker path still loaded the system `libguile-3.0.so.1` from `/usr/local/lib`, so it still crashed. This was confirmed with: ```sh ldd /tmp/guile-freebsd-validate-install/bin/guile ``` To test the local build correctly, the process must use: ```sh LD_LIBRARY_PATH=/tmp/guile-freebsd-validate-install/lib ``` The project test harnesses were updated accordingly so that when `GUILE_BIN` points to a non-system installation, the sibling `../lib` directory is automatically prepended to `LD_LIBRARY_PATH`. ## Validation results ### 1. Packaged Guile still reproduces the problem ```sh ./tests/guile/run-subprocess-diagnostics.sh ``` Observed result: - `system*` exits `139` - `spawn` exits `139` - `open-pipe*` exits `139` ### 2. Local Guile succeeds when using the matching local libguile ```sh EXPECT_GUILE_SUBPROCESS_CRASH=0 \ GUILE_BIN=/tmp/guile-freebsd-validate-install/bin/guile \ ./tests/guile/run-subprocess-diagnostics.sh ``` Observed result: ```text system-star exit=0 spawn exit=0 open-pipe-star exit=0 Guile subprocess helpers succeeded as expected ``` ### 3. The broader Phase 1.1 verification suite also passes with the local build ```sh GUILE_BIN=/tmp/guile-freebsd-validate-install/bin/guile \ ./tests/guile/run-phase1-verification.sh ``` Observed result: - module loading: pass - deterministic output: pass - file I/O: pass - process fork/wait: pass - loopback sockets: pass - FFI: pass - `(guix build make-bootstrap)` import and `copy-linux-headers`: pass ## boehm-gc note The user noted a package warning that Boehm GC is unmaintained on FreeBSD. For this specific validation step: - the local `~/repos/bdwgc` checkout was not needed - the packaged `boehm-gc-threaded` installation was sufficient to build and run the fixed local Guile - no local bdwgc source patch was necessary yet That said, the warning is worth keeping in mind as a likely future brittleness point if later Guile or Guix behavior exposes GC- or thread-related FreeBSD issues. ## Conclusion The local build validates the earlier root-cause analysis in practice: - the packaged Guile is broken on FreeBSD for subprocess helpers - a newer local Guile checkout that already contains upstream commit `eb828801f...` no longer crashes - the next Guix-on-FreeBSD work can proceed using either: 1. a locally built fixed Guile, or 2. a backported packaging patch carrying the same upstream fix This clears the way to proceed into Phase 1.2 while keeping a documented workaround available on the current host.