程序收到SIGUSR1信号从pause()恢复时崩溃(退出码138)的问题排查
程序收到SIGUSR1信号从pause()恢复时崩溃(退出码138)的问题排查
让我们一步步拆解你遇到的问题:
首先,退出码138的含义很关键——它等于128 + 10,而SIGUSR1的信号编号恰好是10。这说明你的客户端程序收到SIGUSR1信号后触发了默认的进程终止行为,而非从pause()调用中恢复继续执行。
问题根源
你的客户端代码犯了一个核心错误:没有为SIGUSR1和SIGUSR2注册任何信号处理函数。
当你调用pause()时,程序会阻塞直到收到一个信号。但如果收到的信号没有自定义处理函数,操作系统会执行该信号的默认动作——对于SIGUSR1/SIGUSR2来说,默认动作就是终止进程。这就是为什么你的客户端在收到服务器反馈时直接崩溃,而不是继续执行后续代码。
修复方案
你需要先为SIGUSR1和SIGUSR2注册一个简单的处理函数,让操作系统知道收到这些信号时不要终止进程,而是唤醒pause()并让程序继续执行。
1. 编写信号处理函数
这个函数不需要做复杂操作,只要存在就能覆盖默认行为:
void signal_handler(int sig) { (void)sig; // 消除未使用变量的编译警告 // 空函数即可,目的只是让pause()从阻塞状态返回 }
2. 在main函数中注册处理函数
推荐使用更可靠的sigaction()来注册(比老式的signal()函数行为更一致):
int main(int argc, char **argv) { int i; int pid; struct sigaction sa; // 新增信号动作结构体 i = 0; if (argc != 3) { ft_printf("Error: Wrong number of arguments."); exit(EXIT_FAILURE); } // 新增:注册信号处理函数 sa.sa_handler = signal_handler; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); // 清空信号掩码 if (sigaction(SIGUSR1, &sa, NULL) == -1 || sigaction(SIGUSR2, &sa, NULL) == -1) { ft_printf("Failed to set up signal handlers\n"); exit(EXIT_FAILURE); } while (argv[1][i]) { if (!ft_isdigit(argv[1][i++])) { ft_printf("Error: Invalid process ID."); exit(EXIT_FAILURE); } } pid = ft_atoi(argv[1]); ft_printf("%s, %d\n", argv[2], getpid()); send_signal(pid, argv[2]); return (0); }
额外优化建议
pause()存在一个竞态条件问题:如果服务器的反馈信号在pause()调用之前就到达,会导致pause()永久阻塞。更安全的替代方案是使用sigsuspend(),它可以先设置信号掩码,再原子性地进入阻塞状态,避免这种竞态。不过先解决信号处理的问题,这是当前崩溃的直接原因。
备注:内容来源于stack exchange,提问作者Buğrahan Özcan
相关产品推荐
相关产品推荐

