summaryrefslogtreecommitdiff
path: root/libunwind/test/forceunwind.pass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libunwind/test/forceunwind.pass.cpp')
-rw-r--r--libunwind/test/forceunwind.pass.cpp20
1 files changed, 13 insertions, 7 deletions
diff --git a/libunwind/test/forceunwind.pass.cpp b/libunwind/test/forceunwind.pass.cpp
index db499d8bc308..344034e1ea5f 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,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;
}