根据ptrace手册页,
如果PTRACE_O_TRACEEXEC选项无效,则跟踪进程对execve(2)的所有成功调用都将使其发送SIGTRAP信号,使父进程有机会在新程序开始执行之前获得控制权。
如果选项 有效,
在下一个execve(2)停止跟踪。跟踪器的waitpid(2)将返回状态值
status>>8 == (SIGTRAP | (PTRACE_EVENT_EXEC<<8))
。如果执行线程不是线程组组长,则在此停止之前将线程ID重置为线程组组长的ID。从Linux 3.0开始,可以使用PTRACE_GETEVENTMSG检索以前的线程ID。
因此,如果未设置该选项,则tracee将获取SIGTRAP并停止,以便跟踪器可以获得控制权。如果设置 选项,则tracee将获得SIGTRAP并停止。有什么区别(除了最后关于线程的部分)?
答案 0 :(得分:2)
差异不在于追踪方面,而在追踪方面。如果没有该选项,则跟踪器无法区分PTRACE_EVENT
停止关注execve
和传入SIGTRAP
;它无法使用PTRACE_GETEVENTMSG
;另外,交付方式不同:如果我没有弄错,如果SIGTRAP
已经挂起则没有选项。它没有重新排队(像往常一样非实时信号)。
答案 1 :(得分:0)
我将提供一个说明一个区别的具体例子。
#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, NULL, PTRACE_O_TRACEEXEC);
printf("%d\n", status >> 8);
ptrace(PTRACE_CONT, child, NULL, NULL);
wait(&status);
printf("%d\n", status >> 8);
printf("%d\n", (SIGTRAP | PTRACE_EVENT_EXEC << 8));
}
return 0;
}
我们将获得19
(SIGSTOP)和5
(SIGTRAP)。取消注释PTRACE_O_TRACEEXEC
行后,我们将获得与19
相同的1029
和(SIGTRAP | PTRACE_EVENT_EXEC << 8)
。