ptrace'ing多线程应用程序

时间:2010-08-19 16:01:00

标签: linux signals ptrace

我有一个类似“调试器”的应用程序,名为hyper-ptrace。它以NPTL多线程启动user_appl3

超级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

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

所以有问题1

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

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

还有第二个问题,问题2

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

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

提前致谢!

1 个答案:

答案 0 :(得分:5)

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

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

要获得所需的行为,请在跟踪的线程停止后立即通过向进程PID发送SIGSTOP来暂停整个子进程(每个线程),并在您使用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 */