日期:2014-05-16 浏览次数:20720 次
4) SIGILL(illegal instruction)执行非法指令
--------------------------initServer------------------------------------------ void initServer() { ... signal(SIGHUP, SIG_IGN); signal(SIGPIPE, SIG_IGN); setupSigSegvAction(); ... } void setupSigSegvAction(void) { struct sigaction act; sigemptyset (&act.sa_mask); /* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction * is used. Otherwise, sa_handler is used */ act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO; act.sa_sigaction = segvHandler; sigaction (SIGSEGV, &act, NULL);//段 sigaction (SIGBUS, &act, NULL);//总线 sigaction (SIGFPE, &act, NULL);//算术 sigaction (SIGILL, &act, NULL);//指令 sigaction (SIGBUS, &act, NULL);//两个BUS ? act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND; act.sa_handler = sigtermHandler; sigaction (SIGTERM, &act, NULL);//请求服务器终止 return; } ----------------------程序出错相关信号的hander--------------------------------- /*1.写服务器出错日志 2.再次执行信号的默认操作(为了core dump?)。 作者的解释:Make sure we exit with the right signal at the end. So for instance the core will be dumped if enabled. 比如:(http://zh.wikipedia.org/wiki/SIGSEGV) 在一个程序接收到SIGSEGV时的默认动作是异常终止。这个动作也许会结束进程, 但是可能生成一个核心文件(core file)以帮助调试,或者执行一些其他特定于某些平台的动作。例如, 使用了grsecurity补丁的Linux系统可能记录SIGSEGV信号以监视可能的使用缓存溢出的攻击尝试。*/ void segvHandler(int sig, siginfo_t *info, void *secret) { void *trace[100]; char **messages = NULL; int i, trace_size = 0; ucontext_t *uc = (ucontext_t*) secret; sds infostring; struct sigaction act; REDIS_NOTUSED(info); redisLog(REDIS_WARNING, "======= Ooops! Redis %s got signal: -%d- =======", REDIS_VERSION, sig); infostring = genRedisInfoString(); redisLog(REDIS_WARNING, "%s",infostring); /* It's not safe to sdsfree() the returned string under memory * corruption conditions. Let it leak as we are going to abort */ trace_size = backtrace(trace, 100); /* overwrite sigaction with caller's address */ if (getMcontextEip(uc) != NULL) { trace[1] = getMcontextEip(uc); } messages = backtrace_symbols(trace, trace_size); for (i=1; i<trace_size; ++i) redisLog(REDIS_WARNING,"%s", messages[i]); /* free(messages); Don't call free() with possibly corrupted memory. */ if (server.daemonize) unlink(server.pidfile); /* Make sure we exit with the right signal at the end. So for instance * the core will be dumped if enabled. */ //由于前面篡改了信号处理函数,为何程序按照正常的处理方式退出,这里采用 //将信号处理函数修改为默认,再次向本进程发送该信号,从而执行信号的默认操作(core dump) sigemptyset (&act.sa_mask); /* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction * is used. Otherwise, sa_handler is used */ act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND; act.sa_handler = SIG_DFL; sigaction (sig, &act, NULL); kill(getpid(),sig); } -----------------------SIGTERM信号