Re: [RFA]: Modified Watchthreads Patch

Eli Zaretskii
2004-12-11T17:53:04Z

> Date: Sat, 11 Dec 2004 11:52:37 -0500
> From: Daniel Jacobowitz <drow@false.org>
> Cc: Jeff Johnston <jjohnstn@redhat.com>, gdb-patches@sources.redhat.com
>
> - The GDB core needs to continue to support watchpoints (hardware
> breakpoints; et cetera) triggering in an unexpected thread.

Agreed.

> Rationale: some targets won't support any other way. For instance
> page protection based watchpoints on GNU/Linux would probably apply to
> all threads.

Another, even better (IMHO) rationale: one important reason for using
watchpoints is to find what code accesses some specific data; when we
use watchpoints for this, we more often than not do not know what
thread will access the data.

> - As an optimization, the interfaces for inserting and removing
> watchpoints could specify a thread to apply the watchpoint to.
> The target could, if it supports this operation, apply the watchpoint
> to only that thread.

This is also needed, for situations where we do know which thread we
are interested in, and other threads hit the same watchpoint too
frequently.

> How useful would this be? For hardware read or write watchpoints,
> very. For "normal" hardware watchpoints (bp_hardware_watchpoint), I
> think almost not at all. GDB relies on knowing the value of all
> watched locations to decide whether the watchpoint "triggered" and
> should stop the program, right?

Yes, but I think (and have said it several times in the past) that
this difference in handling bp_hardware_watchpoint and
bp_read_watchpoint/bp_access_watchpoint is a Bad Thing and we should
rewrite it so that all the types of hardware-assisted watchpoints are
handled in the same way. The current code that handles
bp_hardware_watchpoint is simply the same code that handled software
bp_watchpoint, which to me doesn't make sense, because at least on
x86, the hardware tells us exactly what address was written to.

(However, note that some platforms that cannot implement
target_stopped_data_address actually take advantage of the different
treatment of bp_hardware_watchpoint to implement `watch' even though
`rwatch' and `awatch' are not implemented. If we decide to make the
treatment of all hardware-assisted watchpoints similar, we should be
careful not to break those platforms.)

> If other threads modify the watched
> location, GDB would report the watchpoint the next time we stop,
> because the value would appear to change. And consider a scenario like
> this:
>
> Thread A Thread B
>
> *p = 0
> *p = 1
> *p = 0
> *p = 1
> *p = 0
> *p = 1
> *p = 0
>
> Assuming that the program didn't stop for any other reason, and that
> hardware watchpoints trigger after the write is executed

(I note in parens that on x86, watchpoints trigger _before_ the write
is executed. Not sure if it matters here.)

> "watch *p thread A" would never trigger, because the value would
> always appear to be the same.

With current handling of bp_hardware_watchpoint, yes. With the
handling I would like to see, one that is the same as for
bp_read_watchpoint/bp_access_watchpoint, no: the hardware will tell us
that the address was written to! We just need to be smarter about the
funky logic we have now in breakpoint.c that decides whether or not to
announce the watchpoint, based on whether the value changed or not.

> If we want thread-specific watchpoint insertion, I think that we need
> to either restrict it to rwatch/awatch

It doesn't make sense, from the user point of view, that awatch
catches data writes which watch does not. That's because, to the
user, awatch is a superset of rwatch and watch (when the latter is
hardware-assisted).

> or come up with a more useful behavior for software and hardware
> watchpoints than the one I've thought of. Can you think of one?

I think there's nothing wrong with the model you suggested, it's just
that our handling of bp_hardware_watchpoint is wrong. Assuming we
change it along the lines I suggested above, do you see any further
problems with extending watchpoints to threaded programs?

One aspect where a kernel can help us with multi-threaded programs is
if it tells us not only that a watchpoint has been hit, but also what
thread hit that watchpoint. Are there any kernel-level features that
can be used to find that out?