c - 进程相互跟踪

标签 c linux

我正在尝试创建一个子进程,要求其父进程跟踪他。在此之后, child 会尝试依附于其 parent 。由于某些保护原因,进程只能跟踪它们的子进程,所以我必须使用 sudo 来执行我的代码。我想在两个进程之间创建一些通信,因此我在父进程中放置了一个 do-while 循环。如果 child 终止, parent 也应该终止。我的输出只有 Child is traced,所以我假设 child 没有依附于 parent 。

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

void child();
void parent(pid_t pid);

int main() {
    pid_t pid = fork();
    if(pid == 0)
        child();
    else if(pid > 0)
        parent(pid);
    else{
        perror("fork");
        exit(EXIT_FAILURE);
    }
}


void child(){
    if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
        perror("ptrace");
        exit(EXIT_FAILURE);
    }
    printf("Child is traced\n");


    pid_t ppid = getppid();
    if(ptrace(PTRACE_SEIZE, ppid, NULL, NULL) != 0) {
        perror("ptrace");
        exit(EXIT_FAILURE);
    }

    printf("Child is tracing\n");

    raise(SIGTRAP);

    ptrace(PTRACE_DETACH, ppid, NULL, NULL);

    printf("%s\n", "Child exiting...");
    exit(EXIT_SUCCESS);
}


void parent(pid_t pid){
    int status;
    do{
        waitpid(pid, &status, WUNTRACED | WCONTINUED);
        if(WIFSTOPPED(status)){
            printf("Child stopped: %d\n", WSTOPSIG(status));
            if(WSTOPSIG(status) == 5){
                printf("Stopsig status 5.\n");
            }
            ptrace(PTRACE_CONT, pid, 0, 0);
        }
    } while(!WIFEXITED(status) && !WIFSIGNALED(status));

    ptrace(PTRACE_DETACH, pid, NULL, NULL);

    printf("%s\n", "Parent exiting...");
    exit(EXIT_SUCCESS);
}

注释掉 raise(SIGTRAP) 我得到:

Child is traced
Child is tracing
Child exiting...
Parent exiting...

最佳答案

默认情况下,ptraced 进程将在收到信号时停止。当您的 child 引发 SIGTRAP 时,会向 parent 发送一个 SIGCHLD 信号。由于正在跟踪父项,因此它会停止,子项也会停止。死锁。

如果添加代码让父级忽略 SIGCHLD,程序将按预期运行:

Child is traced
Child is tracing
Child stopped: 5
Stopsig status 5.
Child exiting...
Parent exiting...

关于c - 进程相互跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36283255/

相关文章:

c - 防止缓冲区溢出

c - 将多个目录和文件包含到 makefile 中

linux - 操作系统中的函数叉

linux - 如何将所有传入的连接数据包传递给 NFQUEUE

c - 实现我自己的 ps 命令

c - 在反向 shell 中打印当前目录

c - 在 C 中运行时评估 switch 表达式

c - 获取操作系统的名称和版本

linux - Linux 中的 vm.overcommit_ratio 是什么?

linux - 使用固定种子打乱 find 的输出