SignalHandler 处理系统信号

it2023-01-20  61

在服务器端后台开发中,常常需要写 daemon 程序在后台默默执行一些任务。除了正常的逻辑之外,还需要考虑处理异常退出时怎么办。这时可以用到 signal 这个函数来注册异常信号的回调函数。

示例

#include <iostream> #include <csignal> #include <time.h> #include <stdlib.h> #include <unistd.h> using namespace std; void signalHandler( int signum ) { cout << "Interrupt signal (" << signum << ") received.\n"; // cleanup and close up stuff here // terminate program exit(signum); } int main () { // register signal SIGINT and signal handler signal(SIGINT, signalHandler); while(1){ cout << "Going to sleep...." << endl; sleep(1); } return 0; }

当 CTRL+C 时发出 SIGINT 信号,程序打印

Going to sleep.. Going to sleep.. Going to sleep.. Interrupt signal (2) received.

用 backtrace 记录进行堆栈

用 GDB bt 命令可以查看堆栈信息,在程序中也可以使用 backtrace 函数来记录当前进程的堆栈信息。一旦接收到系统异常信号,将堆栈信息 dump 到文件中,便于分析定位问题

void BackTraceDumper(int signo) { static const uint32_t MAX_STACK_BACKTRACE_SIZE = 100; static void* stack_array[MAX_STACK_BACKTRACE_SIZE]; uint32_t size = backtrace(stack_array, MAX_STACK_BACKTRACE_SIZE); char path[256]; sprintf(path, "/home/user/tmp/core_%lu", time(NULL)); int core_file_fd = open(path, O_CREAT | O_WRONLY, 0444); backtrace_symbols_fd(stack_array, size, core_file_fd); close(core_file_fd); std::exit(-1); } static void SignalHandler(void) { signal(SIGPIPE, SIG_IGN); signal(SIGALRM, SIG_IGN); signal(SIGCHLD, SIG_IGN); sigset(SIGHUP, SIG_IGN); sigset(SIGINT, SignalStop); sigset(SIGTERM, SignalStop); sigset(SIGUSR1, SignalStop); sigset(SIGABRT, BackTraceDumper); sigset(SIGFPE, BackTraceDumper); sigset(SIGBUS, BackTraceDumper); sigset(SIGSEGV, BackTraceDumper); return; }

使用

kill -SIGINT 20482

发送 SIGINT 信号测试

常见信号

kill -l 显示

1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX

参考

http://www.embeddedlinux.org.cn/html/jishuzixun/201211/19-2388.html

最新回复(0)