[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
This commit is contained in:
Alastair Houghton 2024-06-10 15:21:13 +01:00 committed by GitHub
parent c5b68a9dce
commit fe1301b5d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 65 additions and 24 deletions

View File

@ -11,20 +11,27 @@
// 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 ELF 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 +52,7 @@ __attribute__((noinline)) void foo() {
_Unwind_Backtrace(frame_handler, NULL);
}
int main() {
__attribute__((section("main_func"))) int main() {
foo();
return -2;
}

View File

@ -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,14 @@ _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 +72,7 @@ __attribute__((noinline)) void foo() {
_Unwind_ForcedUnwind(e, stop, (void *)&foo);
}
int main() {
__attribute__((section("main_func"))) int main() {
foo();
return -2;
}

View File

@ -13,9 +13,15 @@
// TODO: Figure out why this fails with Memory Sanitizer.
// XFAIL: msan
// 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
//
// XFAIL: target={{.*}}-musl
#undef NDEBUG
#include <assert.h>
#include <dlfcn.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@ -24,16 +30,24 @@
#include <unistd.h>
#include <unwind.h>
// Using __attribute__((section("main_func"))) is ELF 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 +57,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;

View File

@ -13,9 +13,15 @@
// TODO: Figure out why this fails with Memory Sanitizer.
// XFAIL: msan
// 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
//
// XFAIL: target={{.*}}-musl
#undef NDEBUG
#include <assert.h>
#include <dlfcn.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@ -24,16 +30,24 @@
#include <unistd.h>
#include <unwind.h>
// Using __attribute__((section("main_func"))) is ELF 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 +70,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);