【问题标题】:ptrace'ing multithread applicationptrace'ing 多线程应用程序
【发布时间】:2010-08-19 16:00:59
【问题描述】:

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

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 的主循环,以降低通过调试器将信号传递到用户线程的机会? 也不能更改生成陷阱的硬件和用户应用程序。停止第二个线程也不是变体。

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

提前致谢!

【问题讨论】:

  • 这里的sigtrap可以从断点到,无需极端硬件TRAP-generator。

标签: linux signals ptrace


【解决方案1】:

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

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

要获得您想要的行为,请在跟踪线程停止后立即挂起整个子进程(每个线程),方法是向进程 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 */

【讨论】:

  • 在我的例子中,用户应用程序由 2 个线程组成。您能否提供线索案例的来源或文档链接?
  • @osgx:整个进程,即所有线程,将在收到信号后停止。每当 POSIX 文档说某个进程发生了某些事情(例如“进程已停止”)时,它就是在谈论多线程情况下的整个进程。如果文档意味着只有单个线程受到影响,它总是这样说。
  • @caf:我不认为你最后的评论是正确的。我在 linux 上的所有实验都表明,如果一个线程在 linux 上接收到一个事件,另一个线程会继续正常运行,并且由调试器手动停止所有其他线程。对于像 *BSD 系列这样的其他操作系统可能会有所不同,但在 linux 上,每个线程都是一个进程,必须单独跟踪。
  • @Evan Teran:做了更多的测试,你是完全正确的。我被以下事实误导了:将SIGSTOP 发送到多线程进程确实会停止每个线程(根据 POSIX 的要求),但是跟踪停止的处理方式不同(这是允许的,因为ptrace() 不是 POSIX 的一部分全部)。
  • @caf:是的,新的 sn-p 可以工作,但前提是您只对主线程中的事件感兴趣。如果您想从其他线程捕获事件(注意断点!任何线程都可以触发它们),那么您需要手动附加到每个线程。它变得非常毛茸茸,老实说,我仍在想办法正确处理它。可以在这里找到对细节的一个很好的参考:code.google.com/p/go/source/browse/src/pkg/debug/proc/… 感谢 go 开发人员。
猜你喜欢
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
  • 2017-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多