2006-02-24 00:04:15

by Markus Gutschke

[permalink] [raw]
Subject: ptrace.c change in 2.6.15 (?) breaks code for listing threads

I was recently informed by a user of google-perftools.sf.net, that
current Linux kernels no longer allow perftools (and related code, such
as goog-coredumper.sf.net) to list threads in a running application.

I tracked the problem down to this changelist:

--- 5b8dd98a230e442c1ec46adc968acb60dfdb74ae
+++ b88d4186cd7ac2733c3adf231d5b4daa4e14b0a9
@@ -155,7 +155,7 @@ int ptrace_attach(struct task_struct *ta
retval = -EPERM;
if (task->pid <= 1)
goto bad;
- if (task == current)
+ if (task->tgid == current->tgid)
goto bad;
/* the same process cannot be attached many times */
if (task->ptrace & PT_PTRACED)

I believe, if I interpret the data on kernel.org correctly, this change
was made by Linus and shipped with 2.6.15.

Both perftools and coredumper need to locate all threads in the active
application in order to work. As libpthread has had changing and poorly
documented APIs to get this information, and as our intent is to support
all kernel versions and all libc versions, we resorted to ptracing any
process that is suspected to be one of our threads in order to determine
if it actually is. This has the added benefit of finding *all* threads
(including ones not managed by libpthread) and of temporarily suspending
them, so that we have a stable memory image that we can inspect. Think
of both tools as something like a lightweight in-process debugger.

Obviously, special care has to be taken to not ptrace our own thread,
and to avoid any library calls that could deadlock.

Before the patch, attaching ptrace to my own threads was a valid
operation. With this new patch, I can no longer do that.

I'd be happy to consider alternative approaches (which might be cleaner,
anyway) to list and suspend all of the threads in my application. But
before I do that I would like to ask if there is any chance the
restrictions imposed with this patch could be lifted. It would certainly
make my life easier if Linux continued to allow processes to ptrace
themselves -- as far as I have been able to test it, this feature has
been working ever since Linux first supported threads and only broke
very recently.


Markus

P.S.: I usually read LKML as archived on the web, so please cc me on any
responses, if you want me to see your answer quickly. Thanks.