3

我有一个类似“调试器”的应用程序,名为hyper-ptrace. 它开始user_appl3使用 NPTL 进行多线程处理。

hyper-ptrace 的主循环是:

wait3(&status, FLAGS, &u);
// find a pid of child, which has a signal
switch (signal = WSTOPSIG(status))
{
  case SIGTRAP:
    do_some_analysis_of_the_child(pid, &status) // up to several ms
    break;
}
ptrace(PTRACE_CONT, pid); // discard signal, user_appl3 doesn't know anything 
                          //about this SIGTRAP

SIGTRAP 由硬件在每个线程的某个周期间隔为 user_appl3 生成,并将其传递给某些线程。间隔可以是 100..1 毫秒甚至更短。它是一种带有中断的每个 CPU 时钟。每个线程仅在其 CPU 上运行(与亲和性绑定)。

所以有问题1

如果 thread1 得到 TRAP 并且调试器进入do_some_analysis_of_the_child, (所以调试器不会wait3为第二个线程做一个),并且稍后 thread2 也得到了 TRAP,Linux 内核会做什么?

在我看来:thread1 将被停止,因为它得到一个信号并且有一个等待调试器。但是 thread2 继续运行(是吗?)。当 thread2 收到信号时,不会有等待调试器,因此 TRAP 可以传递给 thread2 本身,有效地杀死它。我对吗?

还有第二个问题question2

对于这种情况,我应该如何重写 主循环hyper-ptrace降低通过调试器将信号传递到用户线程的机会?也不能更改生成陷阱的硬件和用户应用程序。停止第二个线程也不是变体。

我需要分析两个线程。有些部分只有在线程停止时才能完成。

提前致谢!

4

1 回答 1

6

不,信号不会传递给应用程序。子应用程序将在信号发生时停止,并且您的 ptracing 进程将在下次调用时收到通知wait()

你是对的 - 跟踪停止仅适用于主线程。

要获得您想要的行为,请在跟踪线程停止后立即挂起整个子进程(每个线程),方法是SIGSTOP向进程 PID 发送 a ,并在完成后使用 a 恢复它SIGCONT

wait3(&status, FLAGS, &u);

if (WIFSTOPPED(status))
    kill(pid, SIGSTOP);  /* Signal entire child process to stop */

switch (signal = WSTOPSIG(status))
{
  case SIGTRAP:
    do_some_analysis_of_the_child(pid, &status) // up to several ms
    break;
}

ptrace(PTRACE_CONT, pid, 0, 0); // discard signal, user_appl3 doesn't know anything about this SIGTRAP
kill(pid, SIGCONT);  /* Signal entire child process to resume */
于 2010-08-20T01:41:26.453 回答