1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
From 69c61c3d9ae8f7397d64570412655007ea086c56 Mon Sep 17 00:00:00 2001
From: ShengYi Hung <aokblast@FreeBSD.org>
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')
|