Skip to content

Commit fe1301b

Browse files
authored
[libunwind] Tweak tests for musl support. (#85097)
We can't use `dladdr()` in the tests, because when we're statically linking with musl that function is a no-op. Additionally, because musl disables emission of unwind information in its build, and because its signal trampolines don't include unwind information, tests that involve unwinding through a signal handler won't work and need to be disabled for musl. rdar://123436891
1 parent c5b68a9 commit fe1301b

File tree

4 files changed

+65
-24
lines changed

4 files changed

+65
-24
lines changed

libunwind/test/floatregister.pass.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,27 @@
1111

1212
// Basic test for float registers number are accepted.
1313

14-
#include <dlfcn.h>
1514
#include <stdlib.h>
1615
#include <string.h>
1716
#include <unwind.h>
1817

18+
// Using __attribute__((section("main_func"))) is ELF specific, but then
19+
// this entire test is marked as requiring Linux, so we should be good.
20+
//
21+
// We don't use dladdr() because on musl it's a no-op when statically linked.
22+
extern char __start_main_func;
23+
extern char __stop_main_func;
24+
1925
_Unwind_Reason_Code frame_handler(struct _Unwind_Context *ctx, void *arg) {
2026
(void)arg;
21-
Dl_info info = {0, 0, 0, 0};
2227

23-
// Unwind util the main is reached, above frames depend on the platform and
28+
// Unwind until the main is reached, above frames depend on the platform and
2429
// architecture.
25-
if (dladdr(reinterpret_cast<void *>(_Unwind_GetIP(ctx)), &info) &&
26-
info.dli_sname && !strcmp("main", info.dli_sname))
30+
uintptr_t ip = _Unwind_GetIP(ctx);
31+
if (ip >= (uintptr_t)&__start_main_func &&
32+
ip < (uintptr_t)&__stop_main_func) {
2733
_Exit(0);
34+
}
2835

2936
return _URC_NO_REASON;
3037
}
@@ -45,7 +52,7 @@ __attribute__((noinline)) void foo() {
4552
_Unwind_Backtrace(frame_handler, NULL);
4653
}
4754

48-
int main() {
55+
__attribute__((section("main_func"))) int main() {
4956
foo();
5057
return -2;
5158
}

libunwind/test/forceunwind.pass.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
#undef NDEBUG
1919
#include <assert.h>
20-
#include <dlfcn.h>
2120
#include <signal.h>
2221
#include <stdint.h>
2322
#include <stdio.h>
@@ -27,6 +26,13 @@
2726
#include <unistd.h>
2827
#include <unwind.h>
2928

29+
// Using __attribute__((section("main_func"))) is Linux specific, but then
30+
// this entire test is marked as requiring Linux, so we should be good.
31+
//
32+
// We don't use dladdr() because on musl it's a no-op when statically linked.
33+
extern char __start_main_func;
34+
extern char __stop_main_func;
35+
3036
void foo();
3137
_Unwind_Exception ex;
3238

@@ -41,14 +47,14 @@ _Unwind_Reason_Code stop(int version, _Unwind_Action actions,
4147
assert(exceptionObject == &ex);
4248
assert(stop_parameter == &foo);
4349

44-
Dl_info info = {0, 0, 0, 0};
45-
46-
// Unwind util the main is reached, above frames depend on the platform and
50+
// Unwind until the main is reached, above frames depend on the platform and
4751
// architecture.
48-
if (dladdr(reinterpret_cast<void *>(_Unwind_GetIP(context)), &info) &&
49-
info.dli_sname && !strcmp("main", info.dli_sname)) {
52+
uintptr_t ip = _Unwind_GetIP(context);
53+
if (ip >= (uintptr_t)&__start_main_func &&
54+
ip < (uintptr_t)&__stop_main_func) {
5055
_Exit(0);
5156
}
57+
5258
return _URC_NO_REASON;
5359
}
5460

@@ -66,7 +72,7 @@ __attribute__((noinline)) void foo() {
6672
_Unwind_ForcedUnwind(e, stop, (void *)&foo);
6773
}
6874

69-
int main() {
75+
__attribute__((section("main_func"))) int main() {
7076
foo();
7177
return -2;
7278
}

libunwind/test/signal_unwind.pass.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@
1313
// TODO: Figure out why this fails with Memory Sanitizer.
1414
// XFAIL: msan
1515

16+
// Note: this test fails on musl because:
17+
//
18+
// (a) musl disables emission of unwind information for its build, and
19+
// (b) musl's signal trampolines don't include unwind information
20+
//
21+
// XFAIL: target={{.*}}-musl
22+
1623
#undef NDEBUG
1724
#include <assert.h>
18-
#include <dlfcn.h>
1925
#include <signal.h>
2026
#include <stdio.h>
2127
#include <stdlib.h>
@@ -24,16 +30,24 @@
2430
#include <unistd.h>
2531
#include <unwind.h>
2632

33+
// Using __attribute__((section("main_func"))) is ELF specific, but then
34+
// this entire test is marked as requiring Linux, so we should be good.
35+
//
36+
// We don't use dladdr() because on musl it's a no-op when statically linked.
37+
extern char __start_main_func;
38+
extern char __stop_main_func;
39+
2740
_Unwind_Reason_Code frame_handler(struct _Unwind_Context* ctx, void* arg) {
2841
(void)arg;
29-
Dl_info info = { 0, 0, 0, 0 };
3042

31-
// Unwind util the main is reached, above frames depend on the platform and
43+
// Unwind until the main is reached, above frames depend on the platform and
3244
// architecture.
33-
if (dladdr(reinterpret_cast<void *>(_Unwind_GetIP(ctx)), &info) &&
34-
info.dli_sname && !strcmp("main", info.dli_sname)) {
45+
uintptr_t ip = _Unwind_GetIP(ctx);
46+
if (ip >= (uintptr_t)&__start_main_func &&
47+
ip < (uintptr_t)&__stop_main_func) {
3548
_Exit(0);
3649
}
50+
3751
return _URC_NO_REASON;
3852
}
3953

@@ -43,7 +57,7 @@ void signal_handler(int signum) {
4357
_Exit(-1);
4458
}
4559

46-
int main(int, char**) {
60+
__attribute__((section("main_func"))) int main(int, char **) {
4761
signal(SIGUSR1, signal_handler);
4862
kill(getpid(), SIGUSR1);
4963
return -2;

libunwind/test/unwind_leaffunction.pass.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@
1313
// TODO: Figure out why this fails with Memory Sanitizer.
1414
// XFAIL: msan
1515

16+
// Note: this test fails on musl because:
17+
//
18+
// (a) musl disables emission of unwind information for its build, and
19+
// (b) musl's signal trampolines don't include unwind information
20+
//
21+
// XFAIL: target={{.*}}-musl
22+
1623
#undef NDEBUG
1724
#include <assert.h>
18-
#include <dlfcn.h>
1925
#include <signal.h>
2026
#include <stdio.h>
2127
#include <stdlib.h>
@@ -24,16 +30,24 @@
2430
#include <unistd.h>
2531
#include <unwind.h>
2632

33+
// Using __attribute__((section("main_func"))) is ELF specific, but then
34+
// this entire test is marked as requiring Linux, so we should be good.
35+
//
36+
// We don't use dladdr() because on musl it's a no-op when statically linked.
37+
extern char __start_main_func;
38+
extern char __stop_main_func;
39+
2740
_Unwind_Reason_Code frame_handler(struct _Unwind_Context* ctx, void* arg) {
2841
(void)arg;
29-
Dl_info info = { 0, 0, 0, 0 };
3042

3143
// Unwind until the main is reached, above frames depend on the platform and
3244
// architecture.
33-
if (dladdr(reinterpret_cast<void *>(_Unwind_GetIP(ctx)), &info) &&
34-
info.dli_sname && !strcmp("main", info.dli_sname)) {
45+
uintptr_t ip = _Unwind_GetIP(ctx);
46+
if (ip >= (uintptr_t)&__start_main_func &&
47+
ip < (uintptr_t)&__stop_main_func) {
3548
_Exit(0);
3649
}
50+
3751
return _URC_NO_REASON;
3852
}
3953

@@ -56,7 +70,7 @@ __attribute__((noinline)) void crashing_leaf_func(int do_trap) {
5670
__builtin_trap();
5771
}
5872

59-
int main(int, char**) {
73+
__attribute__((section("main_func"))) int main(int, char **) {
6074
signal(SIGTRAP, signal_handler);
6175
signal(SIGILL, signal_handler);
6276
crashing_leaf_func(1);

0 commit comments

Comments
 (0)