llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libunwind

Author: Hubert Tong (hubert-reinterpretcast)

<details>
<summary>Changes</summary>

Further to https://github.com/llvm/llvm-project/pull/209306, test a case where 
a signal handler is a Virtual API function triggered synchronously while the 
VAPI is not active. Resuming an ancestor context of the signal frame should 
call the VAPI return glue.

---------

Assisted-by: IBM Bob

---
Full diff: https://github.com/llvm/llvm-project/pull/209662.diff


1 Files Affected:

- (added) libunwind/test/aix_vapi_signal_unwind.pass.cpp (+107) 


``````````diff
diff --git a/libunwind/test/aix_vapi_signal_unwind.pass.cpp 
b/libunwind/test/aix_vapi_signal_unwind.pass.cpp
new file mode 100644
index 0000000000000..038a0d5d4359d
--- /dev/null
+++ b/libunwind/test/aix_vapi_signal_unwind.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+/// Tests unwinding where the signal handler is a VAPI function.
+//
+/// `exit` is used as the signal handler and the unwinding is done in an atexit
+/// handler.
+/// `__builtin_debugtrap` is used because `raise` is also a VAPI function.
+
+/// REQUIRES: target={{.+}}-aix{{.*}}
+/// REQUIRES: has-filecheck
+
+/// ADDITIONAL_COMPILE_FLAGS: -fno-inline -fno-exceptions
+
+/// RUN: %{build}
+/// RUN: %{exec} %t.exe 2>&1 \
+/// RUN: | FileCheck --check-prefix=CHECK \
+/// RUN:       %if libunwind-assertions-enabled %{ --check-prefix=DEBUG %} \
+/// RUN:       %s
+
+#include <errno.h>
+#include <libunwind.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/// VAPI glue addresses
+constexpr uintptr_t vapi_glue_addr_ext_32 = 0x8b80;
+constexpr uintptr_t vapi_addr_64 = 0x8e00;
+constexpr size_t vapi_size_64 = 0x0200;
+constexpr uintptr_t vapi_glue_addr_begin = vapi_glue_addr_ext_32;
+constexpr uintptr_t vapi_glue_addr_end = vapi_addr_64 + vapi_size_64;
+
+struct FunctionDescriptor {
+  uintptr_t entry;
+  uintptr_t toc;
+  uintptr_t env;
+};
+
+void my_atexit_handler(void) {
+  FunctionDescriptor *fd = reinterpret_cast<FunctionDescriptor *>(exit);
+  bool llu_enabled =
+      vapi_glue_addr_begin <= fd->entry && fd->entry < vapi_glue_addr_end;
+
+  fprintf(stderr, "Retrieve a cursor to `main` by stepping up.\n");
+  // CHECK-LABEL: Retrieve a cursor to `main`
+  unw_context_t context;
+  unw_cursor_t cursor;
+  unw_getcontext(&context);
+  unw_init_local(&cursor, &context);
+  /// Step from `my_atexit_handler` up to `exit`.
+  unw_step(&cursor);
+  if (!llu_enabled)
+    fprintf(stderr,
+            "libunwind: the next return address=VAPI_NOT_ENABLED from VAPI\n");
+  /// Note:
+  /// The synthetic VAPI_NOT_ENABLED output would appear _after_ the trace
+  /// output indicating that the "next is a signal handler frame". Use 
DEBUG-DAG
+  /// to allow for that.
+  // DEBUG-LABEL: libunwind: stepWithTBTable: Look up traceback table of 
func=_Z17my_atexit_handlerv
+  // DEBUG-DAG: libunwind: the next return address={{[^ ]*}} from VAPI
+  // DEBUG-DAG: libunwind: The next is a signal handler frame
+  /// Step from `exit` (signal handler, VAPI) up to `trapper`.
+  unw_step(&cursor);
+  // DEBUG-LABEL: libunwind: stepWithTBTable: Look up traceback table of 
func=exit
+  // DEBUG-NEXT: libunwind: Possible signal handler frame
+  /// Step from `trapper` up to `main`.
+  unw_step(&cursor);
+  // DEBUG-LABEL: libunwind: stepWithTBTable: Look up traceback table of 
func=_Z7trapperv
+  // DEBUG-NOT: VAPI
+
+  fprintf(stderr, "Resume `main` at the call to `trapper`.\n");
+  // CHECK-LABEL: Resume `main`
+  if (!llu_enabled)
+    fprintf(stderr,
+            "libunwind: VAPI: executing return glue VAPI_NOT_ENABLED\n");
+  unw_resume(&cursor);
+  __builtin_unreachable();
+  // DEBUG: libunwind: VAPI: executing return glue
+}
+
+void trapper(void) {
+  __builtin_debugtrap();
+  _Exit(EXIT_FAILURE);
+}
+
+int main(void) {
+  if (setenv("LIBUNWIND_PRINT_UNWINDING", "1", true) != 0) {
+    perror("setenv");
+    abort();
+  }
+  if (atexit(my_atexit_handler) != 0) {
+    perror("atexit");
+    abort();
+  }
+  if (signal(SIGTRAP, exit) == SIG_ERR) {
+    perror("signal");
+    abort();
+  }
+  trapper();
+  _Exit(0);
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/209662
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to