Project

General

Profile

Actions

Misc #22320

open

Build fails with SIGSEGV in `miniruby` during `builtin_binary` on macOS 26 (Tahoe): `pipe2` declared by SDK but absent from libSystem at runtime

Misc #22320: Build fails with SIGSEGV in `miniruby` during `builtin_binary` on macOS 26 (Tahoe): `pipe2` declared by SDK but absent from libSystem at runtime
1

Added by mreiche@adobe.com (Michael Reiche) 5 days ago.

Status:
Open
Assignee:
-
[ruby-core:126735]

Description

Environment

  • macOS 26.6.2 (Tahoe), Apple Silicon (arm64)
  • Apple clang 21.0.0 (clang-2100.3.34.2), target arm64-apple-darwin25.6.0
  • Ruby 3.4.10 (also reproduced on 4.0.7), built via ruby-build 20260915 / rbenv
  • Also reproduces with a plain ./configure && make from the release tarball

Summary
On macOS 26, make dies with Segmentation fault: 11 at the step that runs the freshly-linked miniruby to generate builtin_binary.inc (builtin_binary.rbbin). Every Ruby version fails identically, because miniruby segfaults on launch during interpreter init.

compiling enc/trans/newline.c
linking miniruby
make: *** [builtin_binary.inc] Segmentation fault: 11

Root cause
macOS 26's SDK now declares pipe2() in its headers, so Ruby's configure sets HAVE_PIPE2 and rb_cloexec_pipe() compiles a call to pipe2. However, libSystem does not actually provide the symbol at runtime. The weak-imported _pipe2 binds to NULL, and the call during timer-thread setup jumps to address 0.

Crash report (~/Library/Logs/DiagnosticReports/miniruby-*.ips):

Exception: EXC_BAD_ACCESS (SIGSEGV), KERN_INVALID_ADDRESS at 0x0000000000000000
Faulting thread frames:
  0x0                                  ← call through NULL function pointer
  miniruby  rb_cloexec_pipe
  miniruby  setup_communication_pipe_internal
  miniruby  rb_thread_create_timer_thread
  miniruby  Init_Thread
  miniruby  rb_call_inits
  miniruby  ruby_setup / ruby_init
  miniruby  main
  dyld      start

Confirmation that pipe2 is declared but not present at runtime:

$ cat > /tmp/pipe2test.c <<'EOF'
#include <stdio.h>
extern int pipe2(int[2], int);
int main(void){ printf("%p\n", (void*)pipe2); return 0; }
EOF
$ clang -o /tmp/pipe2test /tmp/pipe2test.c && /tmp/pipe2test
dyld[]: Symbol not found: _pipe2
  Expected in: /usr/lib/libSystem.B.dylib

Steps to reproduce

  1. On macOS 26 (Apple Silicon), build Ruby 3.4.x from source (./configure && make).
  2. make segfaults at builtin_binary.inc while executing miniruby.

Expected
configure should not enable HAVE_PIPE2 when the symbol is declared but unavailable at runtime, or rb_cloexec_pipe should guard the call (e.g. __builtin_available / weak-symbol NULL check) and fall back to pipe() + FD_CLOEXEC.

Actual
HAVE_PIPE2 is enabled based solely on the declaration; the resulting binary calls a NULL symbol and crashes.

Workaround

ac_cv_func_pipe2=no ./configure ...
# or, with rbenv:
RUBY_CONFIGURE_OPTS="ac_cv_func_pipe2=no" rbenv install 3.4.10

Suggested fix
Make the pipe2 detection on Darwin a link-and-availability test rather than a declaration check, or wrap the call site with an availability guard so it degrades to the pipe() fallback when &pipe2 == NULL. (macOS historically lacked pipe2; the macOS 26 SDK appears to declare it ahead of libSystem actually providing it.)

No data to display

Actions

Also available in: PDF Atom