PTRACE_O_TRACEEXEC和它的缺席有什么区别?

时间:2014-08-18 20:40:53

标签: linux ptrace

根据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并停止。有什么区别(除了最后关于线程的部分)?

2 个答案:

答案 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)