Stack unwinding unit tests.
Bug: 17436734
Change-Id: I1e98da7eaeab646b448fb3f2b683973dddc319b0
diff --git a/tests/stack_unwinding_test_impl.c b/tests/stack_unwinding_test_impl.c
index 7518a2c..2e03938 100644
--- a/tests/stack_unwinding_test_impl.c
+++ b/tests/stack_unwinding_test_impl.c
@@ -18,52 +18,47 @@
* Contributed by: Intel Corporation
*/
-#include <stdio.h>
+#include <dlfcn.h>
#include <signal.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <unwind.h>
#define noinline __attribute__((__noinline__))
-#define unused __attribute__((__unused__))
-static noinline _Unwind_Reason_Code stop_fn(int a unused,
+#ifndef __unused
+#define __unused __attribute__((__unused__))
+#endif
+
+static noinline _Unwind_Reason_Code cleanup_unwind_fn(int a __unused,
_Unwind_Action action,
- _Unwind_Exception_Class b unused, struct _Unwind_Exception* c unused,
- struct _Unwind_Context* d unused, void* e unused) {
+ _Unwind_Exception_Class b __unused,
+ struct _Unwind_Exception* c __unused,
+ struct _Unwind_Context* ctx __unused,
+ void* e __unused) {
if ((action & _UA_END_OF_STACK) != 0) {
- // We reached the end of the stack without executing foo_cleanup. Test failed.
- abort();
+ abort(); // We reached the end of the stack without executing foo_cleanup (which would have exited). Test failed.
}
return _URC_NO_REASON;
}
-static void noinline foo_cleanup(char* param unused) {
+static void noinline foo_cleanup(char* param __unused) {
exit(42);
}
-static void noinline do_crash() {
- char* ptr = NULL;
- *ptr = 0; // Deliberately cause a SIGSEGV.
+static void noinline function_with_cleanup_function() {
+ char c __attribute__((cleanup(foo_cleanup))) __unused;
+ *((int*) 1) = 0;
}
-static void noinline foo() {
- char c1 __attribute__((cleanup(foo_cleanup))) unused;
- do_crash();
+static void noinline cleanup_sigsegv_handler(int param __unused) {
+ struct _Unwind_Exception* exception = (struct _Unwind_Exception*) calloc(1, sizeof(*exception));
+ _Unwind_ForcedUnwind(exception, cleanup_unwind_fn, 0);
}
-// It's SEGSEGV handler. We start forced stack unwinding here.
-// If libgcc don't find dso for signal frame stack unwinding will be finished.
-// libgcc pass to stop_fn _UA_END_OF_STACK flag.
-// Test pass condition: stack unwinding through signal frame and foo1_handler execution.
-static void noinline sigsegv_handler(int param unused) {
- struct _Unwind_Exception* exception = (struct _Unwind_Exception*) malloc(sizeof(*exception));
- memset(&exception->exception_class, 0, sizeof(exception->exception_class));
- exception->exception_cleanup = 0;
- _Unwind_ForcedUnwind(exception, stop_fn, 0);
-}
-
-void do_test() {
- signal(SIGSEGV, &sigsegv_handler);
- foo();
+void unwind_through_frame_with_cleanup_function() {
+ signal(SIGSEGV, &cleanup_sigsegv_handler);
+ function_with_cleanup_function();
}