对于test1.c
,我得到:
5
133
1
0
这意味着子进程首先得到
SIGTRAP
(5),由execl
引起。最后三行指示子进程因
SIGSTRAP
而终止来自父母的信号。
// test1.c
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/reg.h>
#include <stdio.h>
#include <pthread.h>
int main() {
pid_t child;
int status = 0;
child = fork();
if(child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("/bin/ls", "ls", NULL);
} else {
wait(&status);
printf("%d\n", status >> 8);
ptrace(PTRACE_CONT, child, NULL, SIGTRAP);
wait(&status);
printf("%d\n", status);
printf("%d\n", WIFSIGNALED(status));
printf("%d\n", WIFEXITED(status));
}
return 0;
}
对于
test2.c
,我得到:19
1029
0
0
1
19是
SIGSTOP
,1029
是(SIGTRAP | (PTRACE_EVENT_EXEC<<8))
,但是最后三行超出了我的能力范围。孩子为什么会正常退出?来自父母的
SIGTRAP
信号发生了什么?// test2.c
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/reg.h>
#include <stdio.h>
#include <pthread.h>
int main() {
pid_t child;
int status = 0;
child = fork();
if(child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
raise(SIGSTOP);
execl("/bin/ls", "ls", NULL);
} else {
wait(&status);
ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACEEXEC);
printf("%d\n", status >> 8);
ptrace(PTRACE_CONT, child, NULL, 0);
wait(&status);
printf("%d\n", status >> 8);
ptrace(PTRACE_CONT, child, NULL, SIGTRAP);
wait(&status);
printf("%d\n", status);
printf("%d\n", WIFSIGNALED(status));
printf("%d\n", WIFEXITED(status));
}
return 0;
}
最佳答案
当跟踪器发送信号时
ptrace(PTRACE_CONT, child, NULL, SIGXXXX);
追踪器没有收到该信号的通知-这是有意义的。否则,你怎么向追踪者发出信号?你总能抓住它。
帕特雷斯康特
重新启动已停止的跟踪进程。如果数据不为零,则为
解释为要传递给
tracee;否则,不发送信号。例如,
追踪器可以控制发送给被追踪器的信号是否
是否送达。
如果你想阻止孩子离开父母,你应该使用
kill(child_pid, SIGTRAP)
所以,我想当你在第一个例子中发送SIGTRAP的时候-你只是简单地发送一个未处理的信号给进程,这可能会杀死他。
另一方面,PTRACE_TRACEME不会导致孩子停止,所以,当SIGTRAP被发送时,它可能已经完成了它的执行。