From 69c61c3d9ae8f7397d64570412655007ea086c56 Mon Sep 17 00:00:00 2001 From: ShengYi Hung Date: Sun, 23 Aug 2026 12:45:10 +0800 Subject: [PATCH] meson: Fix unwinding error in libunwind over glibc glibc's pthread_cancel dlopens libgcc_s.so.1 and uses its unwinder, while libc++abi's personality routine resolves the Unwind* accessors from the global scope, where LLVM libunwind wins. This causes the two unwinders to interpret each other's unwind context incorrectly, and cancelling a thread segfaults. Pull libgcc_s into DT_NEEDED before libc++abi/libunwind so all Unwind* symbols resolve to the same unwinder. --- meson.build | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 5dc7338d5f..88be32e27b 100644 --- a/meson.build +++ b/meson.build @@ -17,7 +17,17 @@ cpp_link_args = [] if get_option('libcxx') cpp_args += ['-stdlib=libc++'] - cpp_link_args += ['-stdlib=libc++', '-lc++abi'] + cpp_link_args += ['-stdlib=libc++'] + # glibc's pthread_cancel dlopens libgcc_s.so.1 and forces the unwind through + # that unwinder, while libc++abi's personality routine resolves the _Unwind_* + # accessors through the global scope, where LLVM libunwind wins. The two read + # each other's unwind context as their own, so cancelling a thread + # (SleeperThread::stop) segfaults. Pull libgcc_s into DT_NEEDED ahead of + # libc++abi/libunwind so every _Unwind_* symbol resolves to one unwinder. + if compiler.has_link_argument('-lgcc_s') + cpp_link_args += ['-Wl,--push-state,--no-as-needed', '-lgcc_s', '-Wl,--pop-state'] + endif + cpp_link_args += ['-lc++abi'] endif if compiler.has_link_argument('-lc++fs')