From e89bd7953ed14a20ef00e806f8e545d2ac23d21b Mon Sep 17 00:00:00 2001 From: Paul Guyot Date: Tue, 5 May 2026 07:53:56 +0200 Subject: [PATCH] Fix failure of lldb test on macOS 26 runner Also update documentation about lldb bug related to breakpoint in jit code Signed-off-by: Paul Guyot --- .github/workflows/build-and-test-macos.yaml | 54 ++++++++++++++++----- doc/src/jit.md | 23 +++++++-- 2 files changed, 63 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-and-test-macos.yaml b/.github/workflows/build-and-test-macos.yaml index 6d51ca3df1..cd6d74b1aa 100644 --- a/.github/workflows/build-and-test-macos.yaml +++ b/.github/workflows/build-and-test-macos.yaml @@ -83,7 +83,7 @@ jobs: https://cdn.jsdelivr.net/hex - name: "Install deps" - run: brew update && HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install gperf doxygen socat ${{ matrix.mbedtls }} + run: brew update && HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install coreutils gperf doxygen socat ${{ matrix.mbedtls }} - name: "Workaround for nxdomain random issues" run: | @@ -147,9 +147,23 @@ jobs: - name: "Test: dwarf (test_executable_line)" if: matrix.cmake_opts_other == '-DAVM_DISABLE_JIT=OFF -DAVM_DISABLE_JIT_DWARF=OFF' + timeout-minutes: 4 working-directory: build + env: + # Apple lldb < 2100 hangs forever resolving pending source-line + # breakpoints against JIT-emitted DWARF on macOS 26 (the active + # Xcode 26.2 lldb is 1703.x). The CommandLineTools lldb is at + # 2100 and works. + LLDB: /Library/Developer/CommandLineTools/usr/bin/lldb run: | - OUTPUT=$(lldb -b \ + [ -x "$LLDB" ] || { echo "FAIL: $LLDB not executable"; exit 1; } + echo "## using $LLDB" + "$LLDB" --version | head -2 + LOG=/tmp/lldb-test_executable_line.log + set +e + gtimeout --foreground -k 30 120 "$LLDB" -b \ + -o "log enable -f /tmp/lldb-jit-loader.log lldb jit" \ + -o "log enable -f /tmp/lldb-gdb-test.log gdb-remote packets" \ -o "settings set plugin.jit-loader.gdb.enable on" \ -o "breakpoint set -f test_executable_line.erl -l 49" \ -o "breakpoint set -f test_executable_line.erl -l 52" \ @@ -157,10 +171,17 @@ jobs: -o "print term_to_int(ctx->x[0])" \ -o "c" \ -o "print term_to_int(ctx->x[0])" \ - -- ./tests/test-erlang test_executable_line 2>&1) - echo "$OUTPUT" - # Extract printed values in order - VALUES=$(echo "$OUTPUT" | sed -n 's/.*(\(avm_int_t\)) \(-\{0,1\}[0-9][0-9]*\).*/\2/p') + -o "quit" \ + -- ./tests/test-erlang test_executable_line 2>&1 | tee "$LOG" + LLDB_RC=${PIPESTATUS[0]} + set -e + if [ "$LLDB_RC" -eq 124 ] || [ "$LLDB_RC" -eq 137 ]; then + echo "FAIL: lldb timed out (rc=$LLDB_RC)" + [ -f /tmp/lldb-jit-loader.log ] && { echo "## jit log"; head -200 /tmp/lldb-jit-loader.log; } + [ -f /tmp/lldb-gdb-test.log ] && { echo "## gdb-remote packets (tail)"; tail -120 /tmp/lldb-gdb-test.log; } + exit 1 + fi + VALUES=$(sed -n 's/^(\(avm_int_t\)) \(-\{0,1\}[0-9][0-9]*\).*/\2/p' "$LOG") FIRST=$(echo "$VALUES" | sed -n '1p') SECOND=$(echo "$VALUES" | sed -n '2p') if [ "$FIRST" != "42" ]; then @@ -175,9 +196,15 @@ jobs: - name: "Test: dwarf (test_debug_line)" if: matrix.cmake_opts_other == '-DAVM_DISABLE_JIT=OFF -DAVM_DISABLE_JIT_DWARF=OFF' + timeout-minutes: 6 working-directory: build + env: + LLDB: /Library/Developer/CommandLineTools/usr/bin/lldb run: | - OUTPUT=$(lldb -b \ + [ -x "$LLDB" ] || { echo "FAIL: $LLDB not executable"; exit 1; } + LOG=/tmp/lldb-test_debug_line.log + set +e + gtimeout --foreground -k 30 240 "$LLDB" -b \ -o "settings set plugin.jit-loader.gdb.enable on" \ -o "breakpoint set -f test_debug_line.erl -l 49" \ -o "breakpoint set -f test_debug_line.erl -l 52" \ @@ -185,10 +212,15 @@ jobs: -o "print term_to_int(N)" \ -o "c" \ -o "print term_to_int(Z)" \ - -- ./tests/test-erlang test_debug_line 2>&1) - echo "$OUTPUT" - # Extract printed values in order - VALUES=$(echo "$OUTPUT" | sed -n 's/.*(\(avm_int_t\)) \(-\{0,1\}[0-9][0-9]*\).*/\2/p') + -o "quit" \ + -- ./tests/test-erlang test_debug_line 2>&1 | tee "$LOG" + LLDB_RC=${PIPESTATUS[0]} + set -e + if [ "$LLDB_RC" -eq 124 ] || [ "$LLDB_RC" -eq 137 ]; then + echo "FAIL: lldb timed out (rc=$LLDB_RC)" + exit 1 + fi + VALUES=$(sed -n 's/^(\(avm_int_t\)) \(-\{0,1\}[0-9][0-9]*\).*/\2/p' "$LOG") FIRST=$(echo "$VALUES" | sed -n '1p') SECOND=$(echo "$VALUES" | sed -n '2p') if [ "$FIRST" != "42" ]; then diff --git a/doc/src/jit.md b/doc/src/jit.md index b65888c8b6..9ea7af11a3 100644 --- a/doc/src/jit.md +++ b/doc/src/jit.md @@ -172,9 +172,26 @@ If the Erlang source was compiled with debug information and the BEAM Line chunk ``` ```{note} -LLDB 19 has a regression in the JIT loader that causes hangs when resolving breakpoints in JIT-loaded modules. Use LLDB 20 or later. -On macOS, you can use lldb that ships with Xcode 26+ or install lldb 20 from [MacPorts](https://www.macports.org/) (`port install lldb-20`) or -build from the [LLVM project source](https://github.com/llvm/llvm-project). +Upstream LLVM LLDB 19 and Apple LLDB versions earlier than `lldb-2100` (shipped in Xcode 26.4 and later) hang when resolving pending source-line breakpoints against JIT-emitted DWARF. + +Workarounds without changing lldb: + +* Set breakpoints by symbol name (`breakpoint set -n 'mod:fun/N'`) instead of file/line +* Defer source-line breakpoints until after the relevant module has been JIT-registered (e.g. break first on a symbol, then add the source-line breakpoint, then continue). + +For a fresh lldb: + +* On macOS 26, the LLDB shipped with the CommandLineTools is already at `lldb-2100` (independent of the active Xcode), so a quick fix is to invoke it directly: + +```shell +$ /Library/Developer/CommandLineTools/usr/bin/lldb -- ... +``` + +Alternatively, switch the active Xcode to 26.4 or later (`sudo xcode-select -s /Applications/Xcode_26.4.app`). + +* On any platform, install upstream LLDB 20 or later with `sudo port install lldb-20` from [MacPorts](https://www.macports.org/), `brew install llvm` (Homebrew), or build from the [LLVM project source](https://github.com/llvm/llvm-project). A self-signed `lldb` binary on macOS needs a debugger entitlement. + +`lldb --version` reports the version: `lldb-1703.x` and earlier are affected; `lldb-2100.x` and upstream LLDB 20+ are fixed. ``` ### Disassembling precompiled modules