temp-mixed-c-forensics #2
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # TEMPORARY — minimal repro matrix for the mixed-C/C++ static-libc++ | |
| # runtime SIGSEGV (e2e 36_llvm_toolchain, exit 139). Pure clang, no mcpp | |
| # involved, to isolate which ingredient kills the process: | |
| # m1: pure C++ + static libc++ (control — expected OK) | |
| # m2: mixed .c/.cpp + dynamic libc++ (control — expected OK) | |
| # m3: mixed .c/.cpp + static libc++ (the e2e 36 shape) | |
| # m4: m3 but answer.c compiled as C++ (isolate the C-object factor) | |
| # m5: m3 + crash report collection | |
| # DO NOT MERGE. | |
| name: temp-mixed-c-forensics | |
| on: | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| jobs: | |
| matrix: | |
| runs-on: macos-15 | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Fetch official LLVM 20.1.7 | |
| run: | | |
| curl -fsSL -o /tmp/llvm.tar.xz \ | |
| "https://github.com/llvm/llvm-project/releases/download/llvmorg-20.1.7/LLVM-20.1.7-macOS-ARM64.tar.xz" | |
| mkdir -p "$HOME/llvm" && tar -xJf /tmp/llvm.tar.xz -C "$HOME/llvm" --strip-components=1 | |
| "$HOME/llvm/bin/clang++" --version | head -1 | |
| - name: Repro matrix | |
| run: | | |
| set +e | |
| LLVM="$HOME/llvm" | |
| SDK=$(xcrun --show-sdk-path) | |
| mkdir -p /tmp/w && cd /tmp/w | |
| cat > main.cpp <<'CEOF' | |
| #include <iostream> | |
| extern "C" int answer(void); | |
| int main() { std::cout << "llvm " << answer() << "\n"; return 0; } | |
| CEOF | |
| cat > answer.c <<'CEOF' | |
| int answer(void) { return 42; } | |
| CEOF | |
| CXXFLAGS="--no-default-config -std=c++23 -nostdinc++ -isystem $LLVM/include/c++/v1 --sysroot=$SDK -mmacosx-version-min=14.0" | |
| CFLAGS="--no-default-config --sysroot=$SDK -mmacosx-version-min=14.0" | |
| LDSTATIC="-nostdlib++ $LLVM/lib/libc++.a $LLVM/lib/libc++abi.a" | |
| run_case() { | |
| name="$1"; shift | |
| echo "=== $name ===" | |
| "$@" 2>&1 | head -20 | |
| if [ -x ./prog ]; then | |
| ./prog; echo "exit=$?" | |
| otool -L ./prog | tail -n +2 | |
| else | |
| echo "LINK FAILED" | |
| fi | |
| rm -f ./prog | |
| } | |
| # m1: pure C++ static | |
| cat > pure.cpp <<'CEOF' | |
| #include <iostream> | |
| int answer2(void) { return 42; } | |
| int main() { std::cout << "llvm " << answer2() << "\n"; return 0; } | |
| CEOF | |
| run_case "m1 pure-c++ static" \ | |
| "$LLVM/bin/clang++" $CXXFLAGS -fuse-ld=lld pure.cpp -o prog $LDSTATIC | |
| # m2: mixed dynamic | |
| "$LLVM/bin/clang" $CFLAGS -c answer.c -o answer.o | |
| run_case "m2 mixed dynamic" \ | |
| "$LLVM/bin/clang++" $CXXFLAGS -fuse-ld=lld main.cpp answer.o -o prog -stdlib=libc++ | |
| # m3: mixed static (e2e 36 shape) | |
| run_case "m3 mixed static" \ | |
| "$LLVM/bin/clang++" $CXXFLAGS -fuse-ld=lld main.cpp answer.o -o prog $LDSTATIC | |
| # m4: answer compiled as C++ then static | |
| "$LLVM/bin/clang++" $CXXFLAGS -x c++ -c answer.c -o answercc.o | |
| run_case "m4 mixed(as-c++) static" \ | |
| "$LLVM/bin/clang++" $CXXFLAGS -fuse-ld=lld main.cpp answercc.o -o prog $LDSTATIC | |
| # m6: load_hidden form — forces the ARCHIVE by path with | |
| # hidden visibility (the lld-correct equivalent of ld64 | |
| # -hidden-l). Hypothesis: fixes the split-brain libc++ | |
| # (static copy + system dylib coexisting) seen in m1/m3. | |
| run_case "m6 mixed static load_hidden" \ | |
| "$LLVM/bin/clang++" $CXXFLAGS -fuse-ld=lld main.cpp answer.o -o prog \ | |
| -nostdlib++ -Wl,-load_hidden,"$LLVM/lib/libc++.a" -Wl,-load_hidden,"$LLVM/lib/libc++abi.a" | |
| # m7: pure-C++ int-output + load_hidden (control for m6) | |
| cat > pureint.cpp <<'CEOF' | |
| #include <iostream> | |
| int answer3(void) { return 42; } | |
| int main() { std::cout << "llvm " << answer3() << "\n"; return 0; } | |
| CEOF | |
| run_case "m7 pure-c++ int load_hidden" \ | |
| "$LLVM/bin/clang++" $CXXFLAGS -fuse-ld=lld pureint.cpp -o prog \ | |
| -nostdlib++ -Wl,-load_hidden,"$LLVM/lib/libc++.a" -Wl,-load_hidden,"$LLVM/lib/libc++abi.a" | |
| # m5: rebuild m3 and harvest crash report if it dies | |
| "$LLVM/bin/clang++" $CXXFLAGS -fuse-ld=lld main.cpp answer.o -o prog $LDSTATIC | |
| ./prog; rc=$? | |
| echo "m5 exit=$rc" | |
| if [ "$rc" -ge 128 ]; then | |
| sleep 8 | |
| ls ~/Library/Logs/DiagnosticReports/ 2>/dev/null | tail -3 | |
| R=$(ls -t ~/Library/Logs/DiagnosticReports/prog-* 2>/dev/null | head -1) | |
| [ -n "$R" ] && head -120 "$R" | |
| fi | |
| exit 0 |