【问题标题】:SIGINT signal re-install in linuxSIGINT 信号在 linux 中重新安装
【发布时间】:2013-10-07 08:00:11
【问题描述】:

我正在编写一个处理 Linux 信号的程序。更具体地说,我想在子进程中重新安装信号 SIGINT,结果发现它不起作用。

这是我的代码的一个更简单的版本:

void handler(int sig){
    //do something
    exit(0);
}

void handler2(int sig){
    //do something
    exit(0);
}
int main(){

    signal(SIGINT, handler);

    if ((pid = fork()) == 0) {
        signal(SIGINT, handler2); // re-install signal SIGINT

        // do something that takes some time
        printf("In child process:\n");
        execve("foo", argv, environ); // foo is a executable in local dir

        exit(0);
    }else{
        int status;
        waitpid(pid, &status, 0); // block itself waiting for child procee to exit
    }

    return 0;
}

当 shell 打印“在子进程中:”时,我按 ctrl+c。我发现函数handler 执行没有问题,但handler2 从未执行。

你能帮我解决我代码中的这个错误吗?

更新: 我希望子进程在foo运行过程中接收SIGINT信号,可以吗?

【问题讨论】:

  • 调用 execve() 后,子进程不再有任何信号设置,它们都被重置为 SIG_DFL - 默认值。你问的是这个吗?
  • @jimmcnamara 我不知道信号设置已重置为默认值。谢谢!

标签: linux signals sigint


【解决方案1】:

这不是错误 - 调用 execve 已经替换了正在运行的二进制映像。函数handler2()(以及二进制文件的任何其他函数)不再映射到程序内存中,已被“foo”的图像替换,因此所有信号设置都被替换为默认值。

如果您希望信号处理程序在“foo”运行期间处于活动状态,您必须:

  1. 确保处理函数映射到 foo 的内存中
  2. 在“foo”启动后注册一个信号处理程序。

一种方法是创建一个共享库,其中包含信号处理程序和init 函数,该函数被定义为注册所述信号处理程序的构造函数,并通过在你 execve foo (环境变量)包含

LD_PRELOAD=/path/to/shared_library.so

【讨论】:

  • “共享库”解决方案对我来说似乎很复杂。您能否更具体地提出您的建议“如果您希望信号处理程序在“foo”运行期间处于活动状态,...”?
  • execve 将您的程序替换为程序“foo”。如果你想让你的代码(信号处理程序)在信号发送到 foo 时运行,你需要让它加载你的代码。这就是共享库的作用
【解决方案2】:

@gby 的回答者提供了全面的背景知识。我在这里提供另一个没有共享库的解决方案。

每次子进程停止或终止时,父进程都会收到 SIGCHLD。您可以处理此 SIGCHLD 信号以了解子进程是否被 SIGINT 终止。在您的处理程序中:

pid_t pid = waitpid(pid_t pid,int * status,int options)

您可以通过waitpid函数获取子进程的状态。

if(WIFSIGNALED(status) && (pid == child_pid)){
    if(WTERMSIG(status) == SIGINT){
       // now you know your foo has received SIGINT.
       // do whatever you like.
    }
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2014-08-20
    相关资源
    最近更新 更多