-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[libunwind] Tweak tests for musl support. #85097
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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
This is a cherry pick of swiftlang#8260. |
@llvm/pr-subscribers-libunwind Author: Alastair Houghton (al45tair) ChangesWe can't use 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 Full diff: https://github.com/llvm/llvm-project/pull/85097.diff 4 Files Affected:
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);
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Tweak code formatting to keep clang-format happy. rdar://123436891
Fix a couple of comments, and change to using `XFAIL` rather than explicitly selecting only `linux-gnu`. rdar://123436891
I don't have merge rights here, so someone else will need to hit the Merge button. |
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
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