Skip to content

Commit 4f28e6f

Browse files
committed
fix(build): link the toolchain libc++/abi dylibs by path (round-5 crash: dual libc++ states)
Crash report named it: exit-time locale::~locale freeing a pointer malloc never allocated — two libc++ copies in one process, from -l resolution mixing the sibling libc++.a into the link. By-path dylib linking removes the ambiguity. Forensics now also counts statically embedded libc++ text symbols (nm) to prove the binary is archive-free.
1 parent 4b552ec commit 4f28e6f

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

.github/workflows/ci-macos.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ jobs:
346346
[ -n "$BIN" ] || exit 0
347347
echo "--- otool -L ---"; otool -L "$BIN" || true
348348
echo "--- rpaths ---"; otool -l "$BIN" | grep -A2 LC_RPATH || true
349+
echo "--- statically embedded libc++? ---"
350+
nm "$BIN" 2>/dev/null | grep -cE "T __ZNSt3__1" || echo "0 (good: no libc++ code in binary)"
349351
echo "--- direct run ---"
350352
set +e
351353
"$BIN" > run.out 2>&1

src/build/flags.cppm

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -402,11 +402,18 @@ CompileFlags compute_flags(const BuildPlan& plan) {
402402
auto libDir = llvmRootForStdlib / "lib";
403403
if (std::filesystem::exists(libDir / "libc++.dylib")
404404
|| std::filesystem::exists(libDir / "libc++.1.dylib")) {
405-
// -lc++abi is REQUIRED with this llvm distribution: its
406-
// libc++.dylib does not reexport the abi (round 2 linked
407-
// without it and died on undefined __cxa_* / operator new).
408-
f.ldStdlibTest = " -nostdlib++ -L" + escape_path(libDir)
409-
+ " -lc++ -lc++abi"
405+
// Link the dylibs BY PATH, not -l: with libc++.a and
406+
// libc++.dylib side by side in libDir, -l resolution pulled
407+
// part of the ARCHIVE into the binary alongside the dylib —
408+
// two libc++ global states in one process, and every exit
409+
// aborted in locale::~locale with
410+
// BUG_IN_CLIENT_OF_LIBMALLOC_POINTER_BEING_FREED (CI crash
411+
// report, round 5). A concrete dylib file path has no
412+
// search ambiguity. -lc++abi stays (this distribution's
413+
// libc++ does not reexport the abi — round 2).
414+
f.ldStdlibTest = " -nostdlib++ "
415+
+ escape_path(libDir / "libc++.1.dylib")
416+
+ " " + escape_path(libDir / "libc++abi.1.dylib")
410417
+ " -Wl,-rpath," + escape_path(libDir);
411418
}
412419
}

0 commit comments

Comments
 (0)