https://xtuly.cn/article/android-crash-clear-context 一段关于信号异常的示例
cpp
//
// Created by Ylarod on 2022/11/30.
//
#include <csignal>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#ifndef NELEM
#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
#endif
const int signal_array[] = {SIGILL, SIGABRT, SIGBUS, SIGFPE, SIGSEGV, SIGSTKFLT, SIGSYS};
struct sigaction old_signal_handlers[NELEM(signal_array)];
void signal_handler(int signal, siginfo_t *info, void *context){
const int code = info->si_code;
printf("signal %d, code: %d, pid: %d, uid: %d, tid: %d\n",
signal,
code,
info->si_pid,
info->si_uid,
info->si_tid
);
// 清理context,直接memset也不是不行
auto* ucontext = (ucontext_t*)context;
ucontext->uc_mcontext.sp = 0;
ucontext->uc_mcontext.pc = 0;
ucontext->uc_mcontext.pstate = 0;
ucontext->uc_stack.ss_sp = nullptr;
ucontext->uc_stack.ss_size = 0;
for (unsigned long long& reg : ucontext->uc_mcontext.regs) {
reg = 0;
}
int index = -1;
for (int i = 0; i < NELEM(signal_array); ++i) {
if (signal_array[i] == signal) {
index = i;
break;
}
}
if (index == -1) {
exit(code);
}
// 调用之前的异常处理函数,如果不调用不会出现 tombstone
struct sigaction old = old_signal_handlers[index];
old.sa_sigaction(signal, info, context);
}
void make_crash(int type){
kill(getpid(), signal_array[type - 1]);
}
void init(){
struct sigaction handler = {
.sa_flags = SA_SIGINFO,
.sa_sigaction = signal_handler,
};
for (int i = 0; i < NELEM(signal_array); ++i) {
sigaction(signal_array[i], &handler, &old_signal_handlers[i]);
}
}
int main(int argc, char** argv){
init();
if (argc == 2){
int type = atoi(argv[1]);
make_crash(type);
}
}