c - ptrace SIGTRAP 未处理

标签 c linux ptrace

对于 test1.c ,我得到:

5
133
1
0

表示子进程先得到SIGTRAP (5), 原因 execl . 最后三行表示子进程由于 SIGSTRAP 而终止。 来自 parent 的信号。

// 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 发生了什么来自 parent 的信号?

// 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;
}

最佳答案

当跟踪器使用

发送 SIGNAL 时
ptrace(PTRACE_CONT, child, NULL, SIGXXXX);

跟踪器不会收到该信号的通知 - 这是有道理的。否则,您将如何向被跟踪者发送信号?你总能捕获它。

PTRACE_CONT Restart the stopped tracee process. If data is nonzero, it is interpreted as the number of a signal to be delivered to the tracee; otherwise, no signal is delivered. Thus, for example, the tracer can control whether a signal sent to the tracee is delivered or not.

如果你想阻止你应该使用的 parent 的 child

kill(child_pid, SIGTRAP)

所以,我猜想当您在第一个示例中发送 SIGTRAP 时 - 您只是向进程发送了一个未处理的信号,这可能会杀死他。

另一方面 - PTRACE_TRACEME 不会导致子进程停止,因此,它可能在发送 SIGTRAP 时已经完成了它的执行。

关于c - ptrace SIGTRAP 未处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42735923/

相关文章:

c - 为什么匿名枚举不符合 MISRA C 2012 规则 10.3 而命名枚举不符合?

c - 有没有办法在 C 中多次运行 execvp() 而无需递归?

c - 如何使用 ptrace 找到 CALL 和 RET 号码?

c - 在 C 中动态创建对象

c - 每次从 stdin 读取 char 的最佳方法是什么?

c - linux中的信号量操作,收到SIGSEGV和segmentation fault,哪一部分出错了?

linux - 将 txt 文件中的数据求和,然后将其输出到一行

linux - 无法从 shell 脚本终止进程

c - 尝试使用 ptrace 调用用户函数时出现问题 - nanosleep 导致崩溃

linux - UNIX ptrace() 阻止 child 的系统调用