在无ltrace/strace的Yocto镜像中检测进程信号来源的方法
解决Yocto镜像中程序因SIGHUP(信号1)退出的排查方案
首先明确:信号1是SIGHUP,通常由终端断开、父进程退出或其他进程主动发送导致。以下是无strace/ltrace工具时的排查方法:
一、修改程序代码,直接定位信号发送者
这是最精准的方式,在程序中为SIGHUP注册带详细信息的处理函数:
- 使用
sigaction而非signal,因为前者能获取信号发送方的PID和UID:#include <stdio.h> #include <signal.h> #include <unistd.h> void sighup_handler(int sig, siginfo_t *info, void *context) { printf("Received SIGHUP (signal %d) from PID: %d, UID: %d\n", sig, info->si_pid, info->si_uid); // 暂停10秒再退出,方便后续查进程信息 sleep(10); } int main() { struct sigaction sa; sa.sa_sigaction = sighup_handler; sa.sa_flags = SA_SIGINFO; // 必须设置此标志才能获取信号发送者信息 sigaction(SIGHUP, &sa, NULL); // 原程序逻辑 while(1) { sleep(1); printf("Program running...\n"); } return 0; } - 重新编译程序后放到镜像运行,就能直接看到发送SIGHUP的进程PID,再用
ps -ef | grep [PID]定位具体进程。
二、利用proc文件系统追踪进程状态
Yocto镜像默认挂载proc文件系统,可通过以下方式排查:
- 启动目标程序后记录其PID,比如用
./your_program & echo $!快速获取PID - 写简单bash脚本监控进程状态,退出后对比进程变化、查看系统日志:
#!/bin/bash TARGET_PID=$1 echo "Monitoring PID $TARGET_PID..." ps -ef > before.txt while kill -0 $TARGET_PID 2>/dev/null; do sleep 0.5 done echo "Process $TARGET_PID exited. Checking process changes:" ps -ef > after.txt diff before.txt after.txt # 查看系统日志(如果镜像开启了日志记录) dmesg | tail -20 cat /var/log/messages 2>/dev/null | tail -20 - 进程运行时,可查看
/proc/$TARGET_PID/status中的SigCgt(已捕获信号)、SigPnd(待处理信号)字段,确认SIGHUP的处理状态。
三、排查父进程与终端关联
SIGHUP常见触发场景是父进程退出或终端断开:
- 用
ps -o ppid= -p $TARGET_PID查看目标进程的父进程PID,检查父进程是否会提前退出 - 尝试用
nohup ./your_program &运行程序,脱离终端关联,看是否还会收到SIGHUP - 用
pstree查看进程树,确认目标进程的归属链,排查是否有管理进程会主动发送SIGHUP
关于bash脚本监听所有信号的可行性
bash脚本无法直接捕获系统中所有进程的信号——信号是内核发给特定进程的,bash只能处理发给自身的信号。但可以通过上述脚本结合proc文件系统、进程状态监控的方式,间接追踪目标进程的信号来源,或者通过修改程序代码的方式直接定位发送者。
内容的提问来源于stack exchange,提问作者Termanly
相关产品推荐
相关产品推荐

