Re: [RFA]: Modified Watchthreads Patch

Daniel Jacobowitz
2004-12-11T16:37:02Z

On Sat, Dec 11, 2004 at 03:33:52PM +0100, Mark Kettenis wrote:
> Put another way, using a mechanism such as observers for internal code
> means we leave our internal structure not entirely defined. We design
> the internals, so we ought to know what needs to be done where and
> when. For example, this particular usage of an observer means that we
> don't really know in advance that watchpoint insertion needs to be
> done for each thread when it is being attached. Do we really want to
> say that we don't know what we are doing in our own program?
>
> ...indeed. It's a bit strange that there's a need for a
> Linux-specific observer. The Linux-specific code should know the
> details isn't it? Unfortunately the situation is a bit murky. The
> implementation of hardware (or kernel-assisted) watchpoints is very
> platform-dependent. And on top of that, because of the poor
> thread-debugging interface that Linux has, we never really know what
> threads/lwps actaully exist within a process. This may call for
> unorthodox ways of handling things.
>
> Personally I think that it's better to declare watchpoints in
> multi-threaded programs as unsupported. Then add a sane interface for
> debugging threads and watchpoints to the kernel, before revisiting the
> issue in GDB. I mean, it's like the Linux kernel is no longer Open
> Source.
>
> Adding hacks around hacks, like we've been doing to support threads on
> Linux for quite some time now is defenitely not a good idea.

Mark, would you please stop saying this? I don't believe it to be true
any more. If you think it's still accurate, please point me at
specific hacks around hacks, and let's see if we can get rid of them
now.

The kernel implementation of hardware watchpoints is very
platform-dependent because the hardware implementation of hardware
watchpoints is very platform-dependent. If I had a list of all current
and future platforms to work with, maybe I could come up with a common
interface - but I doubt it. I would expect that they would always be
per-thread on any Linux target with true hardware watchpoints. Of
course, they'll be process global if they're implemented by page
protections; this is something I've been meaning to implement for
Linux for years, but never had the time for.

If I were designing a new operating system from scratch, and I wanted
to architect a thread debugging interface, it wouldn't look anything
like the Linux kernel's does. That much is obvious. However, the two
reasons for that are that I know a lot more about debuggers (and spend
a lot more of my time working on debuggers) than I do about high
performance threading, and that I wouldn't have the historical
architecture of the kernel to contend with. Without thousands of
man-hours to redo the kernel internals, and probably user-visible
incompatible changes, there aren't a whole lot of options.

Moreover, what we have right now is extremely rich, and reasonably well
defined. It is not well-documented, since no one's been motivated to
sit down and write a treatise on it, but I know how it is supposed to
work - that's why I knew to raise a flag to Jeff's "process global"
setting of debug registers, because there are almost no process global
actions in Linux ptrace.

It allows for catching the creation and destruction of threads. This
was one of its big historical holes, which I filled - because the
kernel IS still open.

It allows for finding a list of existing threads when attaching - I
admit, this is one of the big warts. It's not very straightforward
for LinuxThreads, but it can be done without resorting to thread_db.
For modern threading (NPTL) it's very easy.

I admit there are some peculiarities related to stopping all threads.
But most of them are related to very real situations that we want to be
able to debug: two threads receiving a signal at the same time, hitting
different breakpoints at the same time, et cetera. Life with threads
is just more complicated. Some platforms do the complicated bits in
the kernel, and Linux chose to expose an LWP-oriented interface rather
than a whole-process oriented interface so we have to do the
complicated bits in userspace. That is not going to change, because
the Linux design philosophy for threading is that they are just a
special kind of process; Linux has no concept of "the whole process"
and will not be adding one. This has been discussed from time to time
on the linux-kernel list. [There is some correlation to the POSIX
threading concept of a process, for the purpose of POSIX-compliant
signal delivery, but that's the extent of it.]

And I'm busily (at work) improving platform support for NPTL; one of my
goals is to someday rip all the LinuxThreads support code out of GDB.
But it's going to be a long time before that's a viable option - at
least a couple of years from now. That's no more friendly than
dropping support for all but the newest kernel. And we'll need some
of that code to provide quality support for debugging multiple
processes simultaneously, or to support debugging applications which
use clone() directly.

--
Daniel Jacobowitz