Linux支持的信号列表如下(很多信号是与机器的体系结构相关的)
信号值 默认处理动作 发出信号的原因
SIGHUP 1 A 终端挂起或者控制进程终止
SIGINT 2 A 键盘中断(如break键被按下)
SIGQU99v 3 C 键盘的退出键被按下
SIGILL 4 C 非法指令
SIGABRT 6 C 由abort(3)发出的退出指令
SIGFPE 8 C 浮点异常
SIGKILL 9 AEF Kill信号
SIGSEGV 11 C 无效的内存引用
SIGPIPE 13 A 管道破裂: 写一个没有读端口的管道
SIGALRM 14 A 由alarm(2)发出的信号
SIGTERM 15 A 终止信号
SIGUSR1 30,10,16 A 用户自定义信号1
SIGUSR2 31,12,17 A 用户自定义信号2
SIGCHLD 20,17,18 B 子进程结束信号
SIGCONT 19,18,25 进程继续(曾被停止的进程)
SIGSTOP 17,19,23 DEF 终止进程
SIGTSTP 18,20,24 D 控制终端(tty)上按下停止键
SIGTTIN 21,21,26 D 后台进程企图从控制终端读
SIGTTOU 22,22,27 D 后台进程企图从控制终端写
处理动作一项中的字母含义如下
A 缺省的动作是终止进程
C 缺省的动作是终止进程并进行内核映像转储(dump core),内核映像转储是指将进程数据在内存的映像和进程在内核结构中的部分内容以一定格式转储到文件系统,并且进程退出执行,这样做的好处是为程序员提供了方便,使得他们可以得到进程当时执行时的数据值,允许他们确定转储的原因,并且可以调试他们的程序。
E 信号不能被捕获
F 信号不能被忽略
#pragma once
#include <execinfo.h>
#include <signal.h>
#include <stdio.h>
#include <cxxabi.h>
#include <map>
#include <string>
#include <iostream>
#include <sstream>
#include "glog/logging.h"
const std::map<int, std::string> Signals = {
{SIGBUS, "SIGBUS"},
{SIGFPE, "SIGFPE"},
{SIGILL, "SIGILL"},
{SIGSEGV, "SIGSEGV"}
};
static void sigHandler(int signum, siginfo_t *info, void *ctx);
void InitCrashMonitor()
{
struct sigaction action;
sigemptyset(&action.sa_mask);
action.sa_sigaction = &sigHandler;
action.sa_flags = SA_SIGINFO;
for (const auto &sigPair : Signals)
{
if (sigaction(sigPair.first, &action, NULL) < 0)
fprintf(stderr, "Error: sigaction failed! \n");
}
}
static void sigHandler(int signum, siginfo_t *info, void *ctx)
{
const size_t dump_size = 50;
void *array[dump_size];
int size = backtrace(array, dump_size);
char **symbols = backtrace_symbols(array, size);
std::ostringstream oss;
for (int i = 0; i < size; ++i)
{
char *mangleName = 0;
char *offsetBegin = 0;
char *offsetEnd = 0;
for (char *p = symbols[i]; *p; ++p)
{
if ('(' == *p)
{
mangleName = p;
}
else if ('+' == *p)
{
offsetBegin = p;
}
else if (')' == *p)
{
offsetEnd = p;
break;
}
}
if (mangleName && offsetBegin && offsetEnd && mangleName < offsetBegin)
{
*mangleName++ = '\0';
*offsetBegin++ = '\0';
*offsetEnd++ = '\0';
int status;
char *realName = abi::__cxa_demangle(mangleName, 0, 0, &status);
if (0 == status)
oss << "\tstack dump [" << i << "] " << symbols[i] << " : " << realName << "+" ;
else
oss << "\tstack dump [" << i << "] " << symbols[i] << mangleName << "+";
oss << offsetBegin << offsetEnd << std::endl;
free(realName);
}
else
{
oss << "\tstack dump [" << i << "] " << symbols[i] << std::endl;
}
}
free(symbols);
LOG(ERROR) << oss.str(); // 打印函数调用栈信息
exit(0);
}