最有效测试方式是直接用系统原生机制发送信号并观察响应:用kill命令发sigterm(-15)、sigint(-2)或sigquit(-3),结合strace监控内核级信号接收与处理,编写带signal handler的小程序验证逻辑,注意sigkill和sigstop不可捕获。

直接向目标进程发送信号并观察其行为,是最有效、最贴近真实场景的测试方式。关键不是“模拟”,而是用系统原生机制触发响应,同时确保你能准确捕获和验证结果。
用 kill 命令发送标准终止信号
这是最基础也最常用的测试手段。不需要写代码,只需一条命令就能验证进程是否按预期响应:
-
SIGTERM(15号):运行
kill -15 <pid></pid>或kill -TERM <pid></pid>,检查进程是否优雅退出(如释放文件句柄、写入日志、等待子进程结束) -
SIGINT(2号):等效于 Ctrl+C,适合前台进程;对后台进程可用
kill -2 <pid></pid>,观察是否执行清理逻辑而非立即崩溃 -
SIGQUIT(3号):常用于请求进程生成调试信息(如堆栈跟踪),可配合
strace -p <pid></pid>查看是否调用了backtrace()或写入 core 文件
用 strace 监控信号接收与处理过程
仅看进程是否退出不够,需确认它是否真正“收到并响应”了信号。strace 能显示内核级行为:
- 启动进程时加跟踪:
strace -e trace=signal,kill,wait4 ./myapp - 发送信号后,strace 输出中应出现类似
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=12345, si_uid=1000} --- - 若看到
sigreturn()或自定义 handler 的系统调用(如write(2, ...)),说明信号被成功捕获并处理
编写最小化测试程序验证 handler 行为
当需要精确控制或复现特定逻辑时,写一个带 signal handler 的小程序更可靠:
- 注册 handler 并设置全局标志或写临时文件,例如在 handler 中
write(1, "got SIGTERM\n", 13) - 主循环中定期检查该标志或轮询文件是否存在,避免 handler 执行后进程立即退出
- 用
kill -TERM <pid></pid>触发,再用cat /tmp/siglog或观察 stdout 确认 handler 是否执行 - 注意:不要在 handler 中调用非异步信号安全函数(如 printf、malloc),推荐用 write() 和 _exit()
区分不可捕获信号以排除干扰
有些信号无法被自定义 handler 捕获,测试前必须明确这一点,避免误判:
- SIGKILL(9号) 和 SIGSTOP(19号) 是硬性终止/暂停,任何 handler 都无效 —— 若对它们“没反应”,属于正常行为,不是 bug
- 测试时优先用 SIGTERM/SIGINT;若进程对 SIGKILL 有反应(比如仍写日志),那其实是父进程或监控脚本在做善后,不是进程自身响应
- 可用
kill -0 <pid></pid>先确认进程存活,再发信号,避免因进程已死导致“无响应”的假象











