我正在尝试为在{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);
}
答案 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函数,因此您无法在信号处理程序中安全地调用它。