You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

程序收到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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 09:35:29