[libunwind] [libunwind] Tweak tests for musl support. (PR #85097)
Alastair Houghton via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 13 08:02:00 PDT 2024
https://github.com/al45tair created https://github.com/llvm/llvm-project/pull/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
>From 6808d20b198bba4f2e062094b89cfc13eac49f85 Mon Sep 17 00:00:00 2001
From: Alastair Houghton <ahoughton at apple.com>
Date: Thu, 22 Feb 2024 11:59:24 +0000
Subject: [PATCH] [libunwind] Tweak tests for musl support.
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
---
libunwind/test/floatregister.pass.cpp | 18 +++++++++-----
libunwind/test/forceunwind.pass.cpp | 19 +++++++++------
libunwind/test/signal_unwind.pass.cpp | 26 +++++++++++++++------
libunwind/test/unwind_leaffunction.pass.cpp | 24 ++++++++++++++-----
4 files changed, 61 insertions(+), 26 deletions(-)
diff --git a/libunwind/test/floatregister.pass.cpp b/libunwind/test/floatregister.pass.cpp
index 64107e6d490b70b..e4657c63fd1adf3 100644
--- a/libunwind/test/floatregister.pass.cpp
+++ b/libunwind/test/floatregister.pass.cpp
@@ -11,20 +11,26 @@
// Basic test for float registers number are accepted.
-#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <unwind.h>
+// Using __attribute__((section("main_func"))) is Linux specific, but then
+// this entire test is marked as requiring Linux, so we should be good.
+//
+// We don't use dladdr() because on musl it's a no-op when statically linked.
+extern char __start_main_func;
+extern char __stop_main_func;
+
_Unwind_Reason_Code frame_handler(struct _Unwind_Context *ctx, void *arg) {
(void)arg;
- Dl_info info = {0, 0, 0, 0};
- // Unwind util the main is reached, above frames depend on the platform and
+ // Unwind until the main is reached, above frames depend on the platform and
// architecture.
- if (dladdr(reinterpret_cast<void *>(_Unwind_GetIP(ctx)), &info) &&
- info.dli_sname && !strcmp("main", info.dli_sname))
+ uintptr_t ip = _Unwind_GetIP(ctx);
+ if (ip >= (uintptr_t)&__start_main_func && ip < (uintptr_t)&__stop_main_func) {
_Exit(0);
+ }
return _URC_NO_REASON;
}
@@ -45,7 +51,7 @@ __attribute__((noinline)) void foo() {
_Unwind_Backtrace(frame_handler, NULL);
}
-int main() {
+__attribute__((section("main_func"))) int main() {
foo();
return -2;
}
diff --git a/libunwind/test/forceunwind.pass.cpp b/libunwind/test/forceunwind.pass.cpp
index db499d8bc30894e..feb71fb769980c8 100644
--- a/libunwind/test/forceunwind.pass.cpp
+++ b/libunwind/test/forceunwind.pass.cpp
@@ -17,7 +17,6 @@
#undef NDEBUG
#include <assert.h>
-#include <dlfcn.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
@@ -27,6 +26,13 @@
#include <unistd.h>
#include <unwind.h>
+// Using __attribute__((section("main_func"))) is Linux specific, but then
+// this entire test is marked as requiring Linux, so we should be good.
+//
+// We don't use dladdr() because on musl it's a no-op when statically linked.
+extern char __start_main_func;
+extern char __stop_main_func;
+
void foo();
_Unwind_Exception ex;
@@ -41,14 +47,13 @@ _Unwind_Reason_Code stop(int version, _Unwind_Action actions,
assert(exceptionObject == &ex);
assert(stop_parameter == &foo);
- Dl_info info = {0, 0, 0, 0};
-
- // Unwind util the main is reached, above frames depend on the platform and
+ // Unwind until the main is reached, above frames depend on the platform and
// architecture.
- if (dladdr(reinterpret_cast<void *>(_Unwind_GetIP(context)), &info) &&
- info.dli_sname && !strcmp("main", info.dli_sname)) {
+ uintptr_t ip = _Unwind_GetIP(context);
+ if (ip >= (uintptr_t)&__start_main_func && ip < (uintptr_t)&__stop_main_func) {
_Exit(0);
}
+
return _URC_NO_REASON;
}
@@ -66,7 +71,7 @@ __attribute__((noinline)) void foo() {
_Unwind_ForcedUnwind(e, stop, (void *)&foo);
}
-int main() {
+__attribute__((section("main_func"))) int main() {
foo();
return -2;
}
diff --git a/libunwind/test/signal_unwind.pass.cpp b/libunwind/test/signal_unwind.pass.cpp
index 954a5d4ba3db10d..715299e7496efe7 100644
--- a/libunwind/test/signal_unwind.pass.cpp
+++ b/libunwind/test/signal_unwind.pass.cpp
@@ -8,14 +8,13 @@
//===----------------------------------------------------------------------===//
// Ensure that the unwinder can cope with the signal handler.
-// REQUIRES: target={{(aarch64|riscv64|s390x|x86_64)-.+linux.*}}
+// REQUIRES: target={{(aarch64|riscv64|s390x|x86_64)-.+}}linux-gnu
// TODO: Figure out why this fails with Memory Sanitizer.
// XFAIL: msan
#undef NDEBUG
#include <assert.h>
-#include <dlfcn.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -24,16 +23,29 @@
#include <unistd.h>
#include <unwind.h>
+// Note: this test fails on musl because:
+//
+// (a) musl disables emission of unwind information for its build, and
+// (b) musl's signal trampolines don't include unwind information
+//
+
+// Using __attribute__((section("main_func"))) is Linux specific, but then
+// this entire test is marked as requiring Linux, so we should be good.
+//
+// We don't use dladdr() because on musl it's a no-op when statically linked.
+extern char __start_main_func;
+extern char __stop_main_func;
+
_Unwind_Reason_Code frame_handler(struct _Unwind_Context* ctx, void* arg) {
(void)arg;
- Dl_info info = { 0, 0, 0, 0 };
- // Unwind util the main is reached, above frames depend on the platform and
+ // Unwind until the main is reached, above frames depend on the platform and
// architecture.
- if (dladdr(reinterpret_cast<void *>(_Unwind_GetIP(ctx)), &info) &&
- info.dli_sname && !strcmp("main", info.dli_sname)) {
+ uintptr_t ip = _Unwind_GetIP(ctx);
+ if (ip >= (uintptr_t)&__start_main_func && ip < (uintptr_t)&__stop_main_func) {
_Exit(0);
}
+
return _URC_NO_REASON;
}
@@ -43,7 +55,7 @@ void signal_handler(int signum) {
_Exit(-1);
}
-int main(int, char**) {
+__attribute__((section("main_func"))) int main(int, char**) {
signal(SIGUSR1, signal_handler);
kill(getpid(), SIGUSR1);
return -2;
diff --git a/libunwind/test/unwind_leaffunction.pass.cpp b/libunwind/test/unwind_leaffunction.pass.cpp
index 112a5968247a42d..5826ad2ba9533c3 100644
--- a/libunwind/test/unwind_leaffunction.pass.cpp
+++ b/libunwind/test/unwind_leaffunction.pass.cpp
@@ -8,14 +8,13 @@
//===----------------------------------------------------------------------===//
// Ensure that leaf function can be unwund.
-// REQUIRES: target={{(aarch64|riscv64|s390x|x86_64)-.+linux.*}}
+// REQUIRES: target={{(aarch64|riscv64|s390x|x86_64)-.+}}linux-gnu
// TODO: Figure out why this fails with Memory Sanitizer.
// XFAIL: msan
#undef NDEBUG
#include <assert.h>
-#include <dlfcn.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -24,16 +23,29 @@
#include <unistd.h>
#include <unwind.h>
+// Note: this test fails on musl because:
+//
+// (a) musl disables emission of unwind information for its build, and
+// (b) musl's signal trampolines don't include unwind information
+//
+
+// Using __attribute__((section("main_func"))) is Linux specific, but then
+// this entire test is marked as requiring Linux, so we should be good.
+//
+// We don't use dladdr() because on musl it's a no-op when statically linked.
+extern char __start_main_func;
+extern char __stop_main_func;
+
_Unwind_Reason_Code frame_handler(struct _Unwind_Context* ctx, void* arg) {
(void)arg;
- Dl_info info = { 0, 0, 0, 0 };
// Unwind until the main is reached, above frames depend on the platform and
// architecture.
- if (dladdr(reinterpret_cast<void *>(_Unwind_GetIP(ctx)), &info) &&
- info.dli_sname && !strcmp("main", info.dli_sname)) {
+ uintptr_t ip = _Unwind_GetIP(ctx);
+ if (ip >= (uintptr_t)&__start_main_func && ip < (uintptr_t)&__stop_main_func) {
_Exit(0);
}
+
return _URC_NO_REASON;
}
@@ -56,7 +68,7 @@ __attribute__((noinline)) void crashing_leaf_func(int do_trap) {
__builtin_trap();
}
-int main(int, char**) {
+__attribute__((section("main_func"))) int main(int, char**) {
signal(SIGTRAP, signal_handler);
signal(SIGILL, signal_handler);
crashing_leaf_func(1);
More information about the cfe-commits
mailing list