Unwinding out of signal handlers currently does not work since the sigreturn trampoline is not annotated with CFI data. Fix this by detecting the sigreturn trampoline during unwinding and providing appropriate unwind data manually. This follows closely the approach used by existing code for the AArch64 target. Reviewed by: MaskRay Differential Revision: https://reviews.llvm.org/D124765
50 lines
1.4 KiB
C++
50 lines
1.4 KiB
C++
// -*- C++ -*-
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Ensure that the unwinder can cope with the signal handler.
|
|
// REQUIRES: linux && (target={{aarch64-.+}} || target={{s390x-.+}} || target={{x86_64-.+}})
|
|
|
|
// TODO: Figure out why this fails with Memory Sanitizer.
|
|
// XFAIL: msan
|
|
|
|
#include <assert.h>
|
|
#include <dlfcn.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <unwind.h>
|
|
|
|
_Unwind_Reason_Code frame_handler(struct _Unwind_Context* ctx, void* arg) {
|
|
(void)arg;
|
|
Dl_info info = { 0, 0, 0, 0 };
|
|
|
|
// Unwind util the main is reached, above frames depend on the platform and
|
|
// architecture.
|
|
if (dladdr(reinterpret_cast<void *>(_Unwind_GetIP(ctx)), &info) &&
|
|
info.dli_sname && !strcmp("main", info.dli_sname)) {
|
|
_Exit(0);
|
|
}
|
|
return _URC_NO_REASON;
|
|
}
|
|
|
|
void signal_handler(int signum) {
|
|
(void)signum;
|
|
_Unwind_Backtrace(frame_handler, NULL);
|
|
_Exit(-1);
|
|
}
|
|
|
|
int main(int, char**) {
|
|
signal(SIGUSR1, signal_handler);
|
|
kill(getpid(), SIGUSR1);
|
|
return -2;
|
|
}
|