Linux 异常信号总结
Linux 下运行程序崩溃,会看到打印某个 Linux 消息值,根据这个消息值,可以大概推测出是内存检索越界,还是调用了未初始化的指针,方便快速查找出崩溃原因。这篇文章是用来记录下 Linux 常见的异常信号(这些名称定义在signal.h
中),括号内的数字为信号对应的值。
SIGHUP(1)
终端挂起或者控制进程终止,报告用户的终端已经从系统中断开。
SIGINT(2)
键盘中断,该名称是 program interrupt 的缩写,当用户从控制台输入终止字符(通常是 Ctrl-c)时发送给进程的信号。
SIGQUIT(3)
键盘的退出键被按下,该信号和SIGINT相似,区别是它通过用户输入退出字符(通常是 Ctrl-/)来产生,进程处理退出外,还要产生内核转储,就象接收到了错误信号一样。 对于这个信号,你可以认为是用户发现了程序错误而通知程序的一种方法。
SIGILL(4)
非法指令,这个信号的名称来源于“非法的指令(illegal instrution)”,它往往意味着你的程序要执行根本无法译码的指令或你无权执行的特权指令。既然 C 语言只能编译产生有效的合法的指令,所以 SIGILL 信号很多情况下表明可执行文件破坏了,或者正在把数据当作代码来执行。后一种情况往往是由于把一个指针错当成函数指针传递,或者数组越界破坏 了堆栈段的数据,使其中的函数返回地址错误等。SIGILL 也可以由堆栈溢出,或者系统无法执行传递给系统的信号响应函数的句柄引起。
SIGABRT(6)
由程序调用 abort(3) 函数发出的退出指令。
SIGFPE(8)
浮点异常,这个信号表明产生了一个致命的算术运算错误。尽管该信号的名称来源于“浮点异常(floating-point exception)”,但是,它实际上包含了所有的算术指令错误,包括除数是 0 和溢出等。
SIGKILL(9)
Kill 信号,SIGKILL 信号用来让进程立即终止,它不能被控制和忽略,总是致命的,也不能阻塞。该信号通常只能通过特定的命令直接产生,如 Ctrl-c 或者 SIGTERM 等方法。如果一个进程对其它结束信号没有响应,则采用 SIGKILL 信号,总是能让程序结束。事实上,如果 SIGKILL 信号也不起作用的话,你就应该报告一个内核错误。当一个进程由于某中原因不能在进行下 去的时候,系统也能够发送该消息结束进程的执行。
SIGSEGV(11)
无效的内存引用,当程序试图读或写系统分配给它的内存以外的存储器,或者写只有读权限的存储器时会发生这个信号。实际上,由于操作系统检测机制的限制,对程序的检测并不是那么及时,往往只有当超出范围很远时系统才会检测出来。信号的名称来源于“段变异(segmentation violation)”。这个信号的发生往往是由于引用没有初始化或空的指针,或者用指针引用数组时由于疏于检查而越界。
SIGPIPE(13)
管道破裂,如果你使用管道或者 FIFO 进行进程间的通讯,你必须让你的应用程序在写入一个管道之前先有一个程序已经打开了该管道并且已经开始读取数据。如果这时没有开始,或者读管道的进程意外退出了,那么写操作就会产生一个 SIGPIPE 信号。如果 SIGPIPE 信号被阻塞、控制或忽略,那么写操作将返回错误,错误 代码是 EPIPE。
参考: