你可以使用多个线程来追踪一个应用程序吗?

时间:2009-06-18 02:46:01

标签: linux multithreading debugging ptrace

我正在编写一个面向GUI的调试器,主要针对Linux,但我将来会计划到其他操作系统的端口。因为GUI必须始终保持交互,所以我有几个线程处理不同的事情。

主要是我有一个“调试事件”线程,它只是循环等待waitpid返回并将接收到的事件传递给其他线程。我这样做是因为waitpid没有超时,这使得很难将它与其他事件循环集成并保持响应(waitpid可以无限期挂起!)。

到目前为止,这种策略对Linux版本起了很好的作用。最近我一直试图让我的调试器线程知道(如在调试应用程序中的线程,而不是调试器本身)。

因此,我将ptrace选项设置为跟随克隆事件,并查找将16位高位设置为PTRACE_EVENT_CLONE的状态。然后我使用PTRACE_GETEVENTMSG来获取新线程的TID。这一切都适用于我的小型测试工具应用程序。但由于某种原因,当我将该代码放入我的实际调试器时,它失败了。 (我得到一个“没有这样的过程”错误代码)

我遇到的一件事是Windows有一条规则,即只有连接到应用程序的线程才能侦听调试事件。 Linux的ptrace是否有类似的限制?如果是这样,为什么我的代码适用于其他调试事件?

修改

似乎至少waitpid支持从另一个线程等待,该手册页说:

  

在Linux 2.4之前,一个线程只是一个   一个过程的特例,并作为一个   结果一个线程无法等待   另一个线程的孩子,即使是   后者属于同一个线程   组。但是,POSIX规定了   这样的功能,自Linux 2.4以来   线程可以,默认情况下   将等待其他孩子   同一线程组中的线程。

所以最多这是一个ptrace限制。

2 个答案:

答案 0 :(得分:5)

在实现Maxine VM debugger的Linux特定部分时,我遇到了同样的问题(还有许多其他问题!)。您的猜测是正确的,调试器中只有一个线程可以使用ptrace来控制调试对象。我们通过在专用线程上调用ptrace来完成此操作。您可能会发现查看kenai.com/projects/maxine/sources/maxine/show上提供的Maxine源代码中的LinuxTask.java,linuxTask.h和linuxTask.c文件很有用

答案 1 :(得分:4)

据我所知,这是不允许的。任务无法在未附加的任务上使用ptrace。此外,任务最多可以由一个其他任务跟踪,因此您不能简单地在每个线程中附加一次。我认为这是因为当一个任务附加到另一个任务时,跟踪任务成为跟踪任务的父级,每个任务只能有一个父级。

似乎应该允许多线程跟踪,因为线程是同一进程的一部分,但是在实现方面,Linux内核中的线程和进程之间并没有太大的区别。线程只是一个碰巧与其他任务共享大部分资源的任务。

如果您有兴趣,可以浏览内核中的source code for ptrace。具体来看ptrace_check_attachsys_ptrace为大多数请求调用{{3}}。如果目标任务的父级不是当前任务,则返回-ESRCH(听起来像您正在获取的错误代码)。