无法注册SIGTRAP的处理程序

时间:2015-12-30 13:00:23

标签: c linux signals

我正在尝试为在{child}中调用SIGTRAP而导致的int3注册处理程序,但它不起作用。将SIGTRAP更改为SIGCHLD有效。

#include <signal.h>
#include <wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>


void child();
void parent(pid_t pid);
void sigtrap_handler(int sig);

int main(){
    pid_t pid = fork();
    if(pid == 0){
        child();
    } else {
        parent(pid);
    }
}


void child(){
    sleep(1);
    asm("int3");
    exit(EXIT_SUCCESS);
}

void parent(pid_t pid){
    signal(SIGTRAP, sigtrap_handler);
    int status;
    do{
        waitpid(pid, &status, WUNTRACED | WCONTINUED);
    } while(!WIFEXITED(status) && !WIFSIGNALED(status));
    exit(EXIT_SUCCESS);
}

void sigtrap_handler(int sig){
    printf("Process %d received sigtrap %d.\n", getpid(), sig);
}

1 个答案:

答案 0 :(得分:1)

只有父进程为SIGTRAP注册了信号处理程序,但没有为子进程注册。因此,当您在子进程中引发SIGTRAP时,父进程进程不会意识到它。

SIGCHLD有效(即由父级接收),因为当子进程终止(或停止)时,信号SIGCHLD将被发送到父进程。但是在SIGTRAP(或任何其他信号)的情况下,它不会被发送到父进程。 SIGCHLD在某种意义上是特殊的,它在终止时默认发送到父进程,而其他信号则不是。

如果在子进程中添加处理程序,您将看到调用处理程序:

void child(){
    signal(SIGTRAP, sigtrap_handler);
    sleep(1);
    asm("int3");
    exit(EXIT_SUCCESS);
}

顺便说一下,printf()不是async-signal-safe函数,因此您无法在信号处理程序中安全地调用它。