I tried using the script but had a few difficulties. I was able to run the 
environment collection and the first data collect (the stack trace of the 
crash) by hand, and have included the results.

Also note that the environment collection also seg faulted when attempting to 
do an apl --cfg. I've included the output of configure (config.log) in hopes 
that will be helpful.

Trying to run the script to collect the "hang" use case resulted in the same 
segfault and not a hang. I did not include output of that test case.

Aside from the traditional build process, I also have the GNU APL project 
confgured to build under the Xcode IDE (i used ./configure to populate 
config.in, and have tailored the Xcode project to build the apl binary similar 
to what the Makefile-driven build environment does). This has worked fine for 
me for debugging purposes prior to Xcode 27/macOS 27. I've found that the 
segfault that I've seen in this scripted test is the same as what I've seen 
while using the IDE. So it might make me a bit more able to provide assistance. 

Attached are a tar.gz file of the environment collection, the crash backtrace, 
and the config.log for the GNU APL build.

- Paul

Attachment: crash_apl_dash_v.tar.gz
Description: GNU Zip compressed data


> On Sep 25, 2026, at 8:07 AM, Dr. Jürgen Sauermann <mail@jürgen-sauermann.de> 
> wrote:
> 
> Hi Paul,
> 
> thanks for reporting this issue.
> 
> None of us on the GNU APL side currently have a macOS machine, so we
> can't reproduce this directly -- but one detail in your report already
> points somewhere fairly specific, and I'd like to help narrow it down
> rather than leave you guessing.
> 
> "apl --v" segfaulting is the important clue: that just prints a version
> string and exits, before argument parsing even reaches the interactive
> line editor. So this can't be the stdin/iostream code you suspected --
> it has to be crashing in C++ static initialization, i.e. before main()'s
> first line even runs.
> 
> src/static_Objects.cc exists specifically because of this class of
> problem: its own header comment cites ISO C++ 3.6.2 (the
> static-initialization-order rule) and it deliberately sequences several
> global objects that depend on each other (Workspace::the_workspace,
> Macro::init() and all Macro definitions, etc.) by relying on the one
> ordering guarantee the standard does give: within a single translation
> unit, construction happens top-to-bottom. What that file can't control
> is its order *relative to* dozens of other global singletons defined in
> Quad_*.cc/Bif_*.cc across other files -- that has only ever worked by
> whatever order the linker happened to place object files in. Recent
> Apple linkers (the one introduced around Xcode 15, moving toward being
> the default) are known to order and dead-strip differently than the
> classic ld64. If Xcode 27 continues that, it's quite plausible some
> Quad_XX::fun constructor is now running before Workspace::the_workspace
> exists, touching state that isn't there yet -- segfaulting the same way
> on every invocation, exactly as you're seeing, with the banner in the
> normal case suggesting some but not all of that chain completes first.
> 
> That's our leading hypothesis, not a confirmed diagnosis -- I'd like an
> actual backtrace before anyone changes any code. I've put together a
> small script that captures exactly that (a real lldb backtrace for the
> "apl --v" crash, plus two backtrace samples of the interactive hang a
> few seconds apart, plus the toolchain/linker details needed to check the
> theory above) and packages it into one tarball to attach here. Save it
> as macos_diag.sh next to your built apl binary (in src/), chmod +x it,
> and run ./macos_diag.sh from there:
> 
> ----------------------------------------------------------------------
> #!/bin/bash
> #
> # macos_diag.sh -- collect diagnostic evidence for "fails to build/run on
> # macOS 27 + Xcode 27" ([email protected], Paul Rockwell, 2026-09-24): apl --v
> # segfaults immediately (before any interactive input is even possible), and
> # a normal interactive start prints the welcome banner, a couple of garbage
> # characters, then hangs instead of prompting.
> #
> # We (GNU APL upstream) have no macOS machine to reproduce this on. This
> # script exists to gather, in one pass, what we would otherwise have to ask
> # for one command at a time: a real crash backtrace (not just "it
> # segfaults"), the same for the hang, and enough toolchain/build detail to
> # tell whether this is a static-initialization-order issue newly exposed by
> # a different linker. That is our leading hypothesis: src/static_Objects.cc
> # exists specifically to work around undefined *cross-translation-unit*
> # static-init order (its own header comment cites ISO C++ 3.6.2), by
> # consolidating every order-sensitive global (Workspace::the_workspace,
> # Macro::init(), etc.) into one file and relying on the standard's
> # within-one-TU top-to-bottom guarantee. Dozens of *other* files
> # (Quad_*.cc, Bif_*.cc) each define their own global singleton whose
> # construction order *relative to* that chain has never actually been
> # guaranteed by the standard -- only by whatever order the old linker
> # happened to place object files in. Recent Apple linkers (the one
> # introduced around Xcode 15, on track to become fully default) are known to
> # order/dead-strip differently than the classic ld64; if that is what
> # happened here, some Quad_XX::fun constructor is now plausibly running
> # before Workspace::the_workspace exists, touching state that isn't there
> # yet -- segfaulting identically and immediately on every invocation,
> # exactly as reported (even the simplest possible flag crashes; the banner
> # still printing on a normal start suggests some, but not all, of that
> # chain completed before things went wrong).
> #
> # Usage (from the built src/ directory; ./apl must already exist):
> #   ./macos_diag.sh
> #
> # Produces macos_diag_<hostname>.tar.gz in the current directory -- attach
> # that (or paste its contents) in a reply on [email protected].
> 
> set -u
> 
> MAX_WIDTH=79
> rep() { local c=$1 n=$2 s="" i; for ((i = 0; i < n; i++)); do s+=$c; done; 
> printf '%s' "$s"; }
> wrap_text() {
>    local text=$1 maxlen=$2
>    WRAP_LINES=()
>    local line="" word
>    for word in $text; do
>       if [[ -z "$line" ]]; then line=$word
>       elif (( ${#line} + 1 + ${#word} <= maxlen )); then line+=" $word"
>       else WRAP_LINES+=("$line"); line=$word
>       fi
>    done
>    WRAP_LINES+=("$line")
> }
> box() {
>    local hc=$1 tl=$2 tr=$3 bl=$4 br=$5 side=$6 label=$7 text=$8
>    local interior=$(( MAX_WIDTH - 2 )); local maxlen=$(( interior - 2 ))
>    (( maxlen < 10 )) && maxlen=10
>    wrap_text "$text" "$maxlen"
>    local width=${#label} wl w
>    for wl in "${WRAP_LINES[@]}"; do w=$(( ${#wl} + 2 )); (( w > width )) && 
> width=$w; done
>    local lead=4 tail=$(( width - lead - ${#label} ))
>    (( tail < 0 )) && { lead=0; tail=$(( width - ${#label} )); }
>    echo
>    printf '%s%s%s%s%s\n' "$tl" "$(rep "$hc" $lead)" "$label" "$(rep "$hc" 
> $tail)" "$tr"
>    for wl in "${WRAP_LINES[@]}"; do
>       local content=" $wl "
>       while (( ${#content} < width )); do content+=' '; done
>       printf '%s%s%s\n' "$side" "$content" "$side"
>    done
>    printf '%s%s%s\n' "$bl" "$(rep "$hc" $width)" "$br"
> }
> STEP=0
> step() { (( ++STEP )); box '═' '╔' '╗' '╚' '╝' '║' " Step #$STEP " "$*"; }
> note() { box '─' '┌' '┐' '└' '┘' '│' " $1 " "$2"; }
> 
> if [[ ! -x ./apl ]]; then
>    echo "macos_diag.sh: must be run from the src/ directory (need ./apl" \
>         "here, already built)" >&2
>    exit 1
> fi
> 
> HOST_TAG=$(hostname 2>/dev/null || uname -n 2>/dev/null)
> HOST_TAG=${HOST_TAG//[^A-Za-z0-9._-]/_}
> [[ -z "$HOST_TAG" ]] && HOST_TAG=unknown-host
> 
> OUTDIR=$(mktemp -d)
> TARBALL=$(pwd)/macos_diag_$HOST_TAG.tar.gz
> 
> step "collect toolchain and environment info"
> {
>    echo "=== sw_vers ==="; sw_vers 2>&1
>    echo; echo "=== uname -a ==="; uname -a 2>&1
>    echo; echo "=== arch ==="; arch 2>&1
>    echo; echo "=== xcodebuild -version ==="; xcodebuild -version 2>&1
>    echo; echo "=== xcode-select -p ==="; xcode-select -p 2>&1
>    echo; echo "=== clang --version ==="; clang --version 2>&1
>    echo; echo "=== ld -version_details (or -v) ==="
>    ld -version_details 2>&1 || ld -v 2>&1
>    echo; echo "=== otool -L ./apl (linked libraries) ==="; otool -L ./apl 2>&1
>    echo; echo "=== file ./apl ==="; file ./apl 2>&1
>    echo; echo "=== ./apl --cfg ==="; ./apl --cfg 2>&1
> } > "$OUTDIR/environment.txt" 2>&1
> note "wrote" "$OUTDIR/environment.txt"
> 
> step "capture a real backtrace for 'apl --v' (reported to segfault" \
>      "immediately)"
> if command -v lldb >/dev/null 2>&1; then
>    lldb -b \
>         -o "run --v" \
>         -o "bt all" \
>         -o "quit" \
>         -- ./apl > "$OUTDIR/crash_apl_dash_v.txt" 2>&1
>    note "wrote" "$OUTDIR/crash_apl_dash_v.txt (look for the first frame" \
>                 "below the signal line -- if it's a global constructor" \
>                 "rather than anything in main(), that confirms the" \
>                 "static-init-order hypothesis above)"
> else
>    echo "lldb not found -- install Xcode Command Line Tools" \
>         > "$OUTDIR/crash_apl_dash_v.txt"
>    note "lldb missing" "recorded a note instead; please install Xcode" \
>                         "Command Line Tools (xcode-select --install) and" \
>                         "re-run this script"
> fi
> 
> step "capture two backtrace samples of the interactive hang (banner +" \
>      "garbage characters, then no prompt)"
> # A real pty is needed here, not a plain pipe: GNU APL's raw-mode terminal
> # setup (LineInput.cc, tcsetattr) takes a different code path when stdin
> # isn't a tty at all, which could easily fail to reproduce the reported
> # hang. BSD/macOS 'script' allocates one for us.
> HANG_LOG="$OUTDIR/hang_session.txt"
> script -q /dev/null ./apl > "$HANG_LOG" 2>&1 &
> SCRIPT_PID=$!
> sleep 3
> APL_PID=$(pgrep -n -f '(^|/)apl$' 2>/dev/null)
> 
> if [[ -z "$APL_PID" ]]; then
>    note "could not find the apl process" "it may have exited (crashed?)" \
>         "instead of hanging this time -- see $HANG_LOG for whatever it" \
>         "printed before that"
> else
>    {
>       echo "=== sample 1, $(date '+%H:%M:%S') ==="
>       lldb -b -p "$APL_PID" -o "bt all" -o "detach" -o "quit" 2>&1
>       echo
>    } > "$OUTDIR/hang_backtrace.txt"
>    sleep 5
>    {
>       echo "=== sample 2, $(date '+%H:%M:%S') ==="
>       lldb -b -p "$APL_PID" -o "bt all" -o "detach" -o "quit" 2>&1
>    } >> "$OUTDIR/hang_backtrace.txt"
>    note "wrote" "$OUTDIR/hang_backtrace.txt (two samples 5s apart -- the" \
>                 "same location both times means a genuinely stuck" \
>                 "wait/loop, not just something slow)"
> fi
> kill -KILL "$APL_PID" 2>/dev/null
> kill -KILL "$SCRIPT_PID" 2>/dev/null
> wait 2>/dev/null
> 
> step "package everything for emailing"
> tar -czf "$TARBALL" -C "$OUTDIR" .
> rm -rf "$OUTDIR"
> note "wrote" "$TARBALL"
> 
> echo
> echo "Done. Please attach $TARBALL (or paste its contents) in a reply on" \
>      "[email protected]. Thank you for helping track this down -- none of us" \
>      "on the GNU APL side currently have a macOS machine to reproduce it on."
> ----------------------------------------------------------------------
> 
> If lldb refuses to attach for the hang capture (System Integrity
> Protection sometimes blocks debugger attach to processes outside
> Xcode), that's fine -- send whatever the script did produce along with
> a note that it happened, and we'll go from there.
> 
> Thanks again for digging into this and for offering to help others hit
> the same wall -- much appreciated.
> 
> Best regards,
> Jürgen
> 
> 
> On 9/24/26 22:36, Paul Rockwell wrote:
>> A head up to anyone trying to build GNU APL on macOS 27 Golden Gate with 
>> Xcode 27 or Command Line tools for Xcode 27.
>> 
>> It doesn't work.
>> 
>> I'm trying to get a handle on what's going on, but evidently Apple made some 
>> change to Xcode and/or the C++ environment that is breaking GNU APL. 
>> Everything works fine under macOS 26. And if you try to run GNU APL that you 
>> built on macOS 26 after upgrading to macOS 27, it still works.
>> 
>> Even something as simple as trying to display help via "apl --v" results in 
>> a seg fault.
>> 
>> Trying to bring up APL normally prints the welcome banner, displays a couple 
>> of garbage characters, and then hangs instead of prompting for input.
>> 
>> I'm suspecting that something in the way GNU APL is dealing with std input 
>> and output (or the C++ iostream llibraries) s incompatible with something 
>> that Apple changed in macOS 27 and/or the clang C++ environment that's 
>> present in the compilation system in Xcode 27.
>> 
>> Any thoughts on how to debug this would be appreciated.  I suspedt that 
>> Jürgen doesn't use macOS so us macOS users are probably going to have to 
>> help figure this out. If anyone else runs into this on macOS, please reach 
>> out and perhaps we can collaborate on getting to the bottom of what's wrong.
>> 
>> - Paul
> 

Reply via email to