Files
fruix/docs/reports/phase1-guile-local-build-validation.md

4.8 KiB

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:

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:

git clone --shared ~/repos/guile /tmp/guile-freebsd-validate-src

Autotools bootstrap:

cd /tmp/guile-freebsd-validate-src
M4=gm4 ./autogen.sh

Configure:

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:

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:

ldd /tmp/guile-freebsd-validate-install/bin/guile

To test the local build correctly, the process must use:

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

./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

EXPECT_GUILE_SUBPROCESS_CRASH=0 \
GUILE_BIN=/tmp/guile-freebsd-validate-install/bin/guile \
./tests/guile/run-subprocess-diagnostics.sh

Observed result:

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

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.