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

如何使用信号处理程序停止并恢复子进程?代码无法恢复子进程是什么原因

问题原因

你的代码存在几个关键逻辑错误,直接导致进程组被停止无法继续运行:

    1. 变量笔误(如果你的代码能运行说明实际代码已修正该问题):fork()的返回值赋值给了global_pid,但后续判断用的是未声明的pid变量,编译阶段就会报错。
    1. 信号处理上下文错误:int3指令是子进程执行的,触发的SIGTRAP(信号值5)是发送给子进程的,子进程继承了父进程的信号处理函数,实际是子进程在执行stop函数,而子进程中global_pid的值为0(fork给子进程的返回值是0)。
    1. 停止范围错误:kill(0, SIGSTOP)的含义是给当前进程所在的整个进程组发送停止信号,会直接把父进程和子进程都暂停,stop函数中后续发SIGCONT的代码根本没有运行机会,这就是你看到终端输出Stopped的原因。
    1. (非核心不影响运行但不规范)信号处理函数中调用printf属于不安全操作,printf是不可重入函数,信号处理可能打断正常的标准IO操作,导致输出异常。
修复方案

如果你的需求是子进程触发断点时,由父进程控制子进程的停止和恢复,调整逻辑如下:

  1. 子进程收到SIGTRAP后通知父进程,由父进程完成对信号的处理,不要在子进程的信号处理函数中操作停止逻辑
  2. 父进程需要等待子进程的状态变化,不要直接sleep后退出
  3. 避免在信号处理函数中使用不可重入函数

修正后示例代码

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/types.h>

#define ERR_EXIT(m) \
        do \
        { \
                perror(m); \
                exit(EXIT_FAILURE); \
        }while(0)

pid_t child_pid = -1;

void parent_handler(int signo) {
    // 信号处理函数用可重入的write输出
    const char msg[] = "catch SIGTRAP from child, stop then resume child\n";
    write(STDOUT_FILENO, msg, sizeof(msg)-1);
    // 父进程操作子进程
    kill(child_pid, SIGSTOP);
    // 此处可添加你需要的暂停处理逻辑
    sleep(1);
    kill(child_pid, SIGCONT);
}

void child_handler(int signo) {
    // 子进程收到SIGTRAP后转发通知父进程
    kill(getppid(), SIGUSR1);
}

int main()
{
    printf("before fork, pid = %d\n",getpid());
    pid_t pid = fork(); 
    child_pid = pid;

    if(pid == -1) 
    {
        ERR_EXIT("fork error");
    }
        
    if(pid > 0)
    {
        // 父进程注册SIGUSR1处理函数,接收子进程的断点通知
        signal(SIGUSR1, parent_handler);
        printf("This is parent pid = %d child pid = %d\n",getpid(),pid);
        // 等待子进程退出
        wait(NULL);
        printf("child exit, parent exit\n");
    }else if(pid == 0)
    {
        // 子进程注册SIGTRAP处理函数
        signal(SIGTRAP, child_handler);
        printf("This is child pid = %d parent pid = %d\n",getpid(),getppid());
        asm volatile("int3"); 
        printf("The child continued.\n");
        exit(0);
    }
    
    return 0;
}

内容的提问来源于stack exchange,提问作者gazile

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:27:00