# 查看信号处理信息
## 例子
#include <stdio.h>
#include <signal.h>
void handler(int sig);
void handler(int sig)
{
signal(sig, handler);
printf("Receive signal: %d\n", sig);
}
int main(void) {
signal(SIGINT, handler);
signal(SIGALRM, handler);
while (1)
{
sleep(1);
}
return 0;
}
## 技巧
用gdb调试程序时,可以用“`i signals`”命令(或者“`i handle`”命令,`i`是`info`命令缩写)查看gdb如何处理进程收到的信号:
(gdb) i signals
Signal Stop Print Pass to program Description
SIGHUP Yes Yes Yes Hangup
SIGINT Yes Yes No Interrupt
SIGQUIT Yes Yes Yes Quit
......
SIGALRM No No Yes Alarm clock
......
第一项(`Signal`):标示每个信号。
第二项(`Stop`):表示被调试的程序有对应的信号发生时,gdb是否会暂停程序。
第三项(`Print`):表示被调试的程序有对应的信号发生时,gdb是否会打印相关信息。
第四项(`Pass to program`):gdb是否会把这个信号发给被调试的程序。
第五项(`Description`):信号的描述信息。
从上面的输出可以看到,当`SIGINT`信号发生时,gdb会暂停被调试的程序,并打印相关信息,但不会把这个信号发给被调试的程序。而当`SIGALRM`信号发生时,gdb不会暂停被调试的程序,也不打印相关信息,但会把这个信号发给被调试的程序。
启动gdb调试上面的程序,同时另起一个终端,先后发送`SIGINT`和`SIGALRM`信号给被调试的进程,输出如下:
Program received signal SIGINT, Interrupt.
0xfeeeae55 in ___nanosleep () from /lib/libc.so.1
(gdb) c
Continuing.
Receive signal: 14
可以看到收到`SIGINT`时,程序暂停了,也输出了信号信息,但并没有把`SIGINT`信号交由进程处理(程序没有输出)。而收到`SIGALRM`信号时,程序没有暂停,也没有输出信号信息,但把`SIGALRM`信号交由进程处理了(程序打印了输出)。
参见[gdb手册](https://sourceware.org/gdb/onlinedocs/gdb/Signals.html).
## 贡献者
nanxiao
- 介绍
- 信息显示
- 显示gdb版本信息
- 显示gdb版权相关信息
- 启动时不显示提示信息
- 退出时不显示提示信息
- 输出信息多时不会暂停输出
- 函数
- 列出函数的名字
- 是否进入带调试信息的函数
- 进入不带调试信息的函数
- 退出正在调试的函数
- 直接执行函数
- 打印函数堆栈帧信息
- 打印尾调用堆栈帧信息
- 选择函数堆栈帧
- 向上或向下切换函数堆栈帧
- 断点
- 在匿名空间设置断点
- 在程序地址上打断点
- 在程序入口处打断点
- 在文件行号上打断点
- 保存已经设置的断点
- 设置临时断点
- 设置条件断点
- 忽略断点
- 观察点
- 设置观察点
- 设置观察点只针对特定线程生效
- 设置读观察点
- 设置读写观察点
- Catchpoint
- 让catchpoint只触发一次
- 为fork调用设置catchpoint
- 为vfork调用设置catchpoint
- 为exec调用设置catchpoint
- 为系统调用设置catchpoint
- 通过为ptrace调用设置catchpoint破解anti-debugging的程序
- 打印
- 打印ASCII和宽字符字符串
- 打印STL容器中的内容
- 打印大数组中的内容
- 打印数组中任意连续元素值
- 打印数组的索引下标
- 打印函数局部变量的值
- 打印进程内存信息
- 打印静态变量的值
- 打印变量的类型和所在文件
- 打印内存的值
- 打印源代码行
- 每行打印一个结构体成员
- 按照派生类型打印对象
- 指定程序的输入输出设备
- 使用“$\”和“$\_”变量
- 打印程序动态分配内存的信息
- 打印调用栈帧中变量的值
- 多进程/线程
- 调试已经运行的进程
- 调试子进程
- 同时调试父进程和子进程
- 查看线程信息
- 在Solaris上使用maintenance命令查看线程信息
- 不显示线程启动和退出信息
- 只允许一个线程运行
- 使用“$_thread”变量
- 一个gdb会话中同时调试多个程序
- 打印程序进程空间信息
- 使用“$_exitcode”变量
- core dump文件
- 为调试进程产生core dump文件
- 加载可执行程序和core dump文件
- 汇编
- 设置汇编指令格式
- 在函数的第一条汇编指令打断点
- 自动反汇编后面要执行的代码
- 将源程序和汇编指令映射起来
- 显示将要执行的汇编指令
- 打印寄存器的值
- 显示程序原始机器码
- 改变程序的执行
- 改变字符串的值
- 设置变量的值
- 修改PC寄存器的值
- 跳转到指定位置执行
- 使用断点命令改变程序的执行
- 修改被调试程序的二进制文件
- 信号
- 查看信号处理信息
- 信号发生时是否暂停程序
- 信号发生时是否打印信号信息
- 信号发生时是否把信号丢给程序处理
- 给程序发送信号
- 使用“$_siginfo”变量
- 共享库
- 显示共享链接库信息
- 脚本
- 配置gdb init文件
- 按何种方式解析脚本文件
- 保存历史命令
- 源文件
- 设置源文件查找路径
- 替换查找源文件的目录
- 图形化界面
- 进入和退出图形化调试界面
- 显示汇编代码窗口
- 显示寄存器窗口
- 调整窗口大小
- 其它
- 命令行选项的格式
- 支持预处理器宏信息
- 使用命令的缩写形式
- 在gdb中执行shell命令和make
- 在gdb中执行cd和pwd命令
- 设置命令提示符
- 设置被调试程序的参数
- 设置被调试程序的环境变量
- 得到命令的帮助信息
- 记录执行gdb的过程