Debian 和基于 Red Hat 的发行版之间的 Kill(pid, SIGINT) 行为差异

问题描述 投票:0回答:1

在虚拟机中使用 Debian 12 和 CentOS 7 之间的

kill(pid, SIGINT)
时,我的代码行为存在差异。以前,此代码在 Fedora 39 中按预期工作。

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <cstdlib>
#include <cstring>
#include <sys/wait.h>

using namespace std;

void sigint_handler(int signal) {
    cout << "The child process received the SIGINT signal. Ending..." << endl;
    exit(EXIT_SUCCESS);
}

int main() {
    pid_t pid = fork();

    if (pid < 0) {
        cerr << "Error creating the child process." << endl;
        exit(EXIT_FAILURE);
    } else if (pid == 0) {
        // Child process
        cout << "Child process created. PID: " << getpid() << endl;
        
        // Signal handler for SIGINT
        signal(SIGINT, sigint_handler);

        // Executing ping for 10 iterations, although parent process should stop it earlier
        execl("/bin/sh", "sh", "-c", "ping -c 10 google.com", NULL);
    } else {
        // Parent process
        cout << "parent process. PID from child: " << pid << endl;
        sleep(3); // Wait 3 seconds before sending the SIGINT

        cout << "Sending SIGINT to the child process..." << endl;
        if (kill(pid, SIGINT) == -1) {
            cerr << "Error sending SIGINT to the child process." << endl;
            exit(EXIT_FAILURE);
        }

        int status;
        waitpid(pid, &status, 0); // Wait to the child process to end
        if (WIFEXITED(status)) {
            cout << "Child process end with status: " << WEXITSTATUS(status) << endl;
        } else {
            cout << "Child process end in an incorrect way" << endl;
        }
    }

    return 0;
}

迁移到 Debian 12 后,上面的代码片段的行为不符合预期。它不会在发送 SIGINT 信号后停止 ping 进程,而是继续执行所有 10 次迭代。然而,当在 CentOS VM 中运行相同的代码时,它的行为正确,在几次迭代后停止。

为什么会出现这种情况?

提前致谢。

附加信息:

Debian 12 中的 g++ 版本:g++ (Debian 12.2.0-14) 12.2.0

CentOS 7 虚拟机中的 g++ 版本:g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

编辑1:

我也尝试过用

system("ping -c 10 google.com")

代替
execl()
,但没有成功。

除此之外,该问题与 Debian 和基于 Red Hat 的发行版中

ping

 的不同实现无关,因为我已经尝试过我的原始代码并且它不会停止。

在我的原始代码中,我调用了具有无限循环的

ping

,而不是 
program.o
,应使用 
Ctrl+C
 停止该循环。在 Fedora 和 CentOS 中,我的程序运行完美,但在 Debian 中则不然。

c++ debian posix redhat sigint
1个回答
1
投票
这并不像你期望的那样工作:

// Signal handler for SIGINT signal(SIGINT, sigint_handler); // Executing ping for 10 iterations, although parent process should stop it earlier execl("/bin/sh", "sh", "-c", "ping -c 10 google.com", NULL);

execl

 将在新进程中
将信号操作重置回默认值。这仅针对极短的窗口将信号处理程序设置为 sigint_handler

因此,

ping

SIGINT
 的反应完全取决于它如何设置其信号处理程序。据推测,不同的虚拟机具有不同的 
ping
 实现或版本。 
iputils
inetutils
 都有一个 
ping

© www.soinside.com 2019 - 2024. All rights reserved.