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
