66 lines · cpp
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10// Ensure that the unwinder can cope with the signal handler.11// REQUIRES: target={{(aarch64|loongarch64|riscv64|s390x|x86_64)-.+}}12// UNSUPPORTED: target={{.*-windows.*}}13 14// TODO: Figure out why this fails with Memory Sanitizer.15// XFAIL: msan16 17// Note: this test fails on musl because:18//19// (a) musl disables emission of unwind information for its build, and20// (b) musl's signal trampolines don't include unwind information21//22// XFAIL: target={{.*}}-musl23 24#undef NDEBUG25#include <assert.h>26#include <signal.h>27#include <stdio.h>28#include <stdlib.h>29#include <string.h>30#include <sys/types.h>31#include <unistd.h>32#include <unwind.h>33 34// Using __attribute__((section("main_func"))) is ELF specific, but then35// this entire test is marked as requiring Linux, so we should be good.36//37// We don't use dladdr() because on musl it's a no-op when statically linked.38extern char __start_main_func;39extern char __stop_main_func;40 41_Unwind_Reason_Code frame_handler(struct _Unwind_Context* ctx, void* arg) {42 (void)arg;43 44 // Unwind until the main is reached, above frames depend on the platform and45 // architecture.46 uintptr_t ip = _Unwind_GetIP(ctx);47 if (ip >= (uintptr_t)&__start_main_func &&48 ip < (uintptr_t)&__stop_main_func) {49 _Exit(0);50 }51 52 return _URC_NO_REASON;53}54 55void signal_handler(int signum) {56 (void)signum;57 _Unwind_Backtrace(frame_handler, NULL);58 _Exit(-1);59}60 61__attribute__((section("main_func"))) int main(int, char **) {62 signal(SIGUSR1, signal_handler);63 kill(getpid(), SIGUSR1);64 return -2;65}66