public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Remove REPARSE condition to force hardware resource checking when updating watchpoints
@ 2022-10-18 16:42 Carl Love
  2022-10-28 13:28 ` Ulrich Weigand
  0 siblings, 1 reply; 2+ messages in thread
From: Carl Love @ 2022-10-18 16:42 UTC (permalink / raw)
  To: gdb-patches, Ulrich Weigand

GDB maintainers:

The hardware resource checking done in function update_watchpoints in
file gdb/breakpoints.c is currently only done when the input argument
REPARSE is set to one.  Function update_watchpoints is called with
REPARSE set to 1 to verify there are enough hardware resources
available to use hardware watchpoings when executing the watch command.
The variable being watched can later change and thus change the number
of hardware resources required for the watchpoint.  However, the
resource checking is not redone in update_watchpoint since the function
is not called again with REPARSE set to 1.  This can result the number
of addresses to be watched exceeding the available hardware watch
registers.  This issue occurs on Power 10 when executing the 
gdb.base/watchpoint.exe test.  When the issue occurs the test fails on
an internal gdb error.

The issue can be fixed by forcing the resource checking to be redone
each time update_watchpoints is called.  This patch makes forces the
resources to be rechecked on each call to update_watchpoints by
removing the "if (reparse)" line in the function.  The change allows
gdb to catch that the resource requirements changed and handle the
situation correctly.

The patch has been tested on Power 8, Power 10 and X86-64 without
regressions.  The patch has no effect on Power 9 as hardware
watchpoints are disabled on that processor.

Please let me know if this patch is acceptable for mainline.  Thanks.

                       Carl Love


----------------------------
Remove REPARSE condition to force hardware resource checking when updating watchpoints

Currently the resource checking is done if REPARSE is true.  The hardware
watchpoint resource checking in update_watchpoint needs to be redone on
each call to function update_watchpoints as the value chain may have
changed.  The number of hardware registers needed for a watchpoint can
change if the variable being watched changes.  This situation occurs in
this test when watching variable **global_ptr_ptr.  Initially when the
watch command is issued, only two addresses need to be watched as
**global_ptr_ptr has not yet been initialized.  Once the value of
**global_ptr_ptr is initialized the locations to be tracked increase to
three addresses.  However, update_watchpoints is not called again with
REPARSE set to 1 to force the resource checking to be redone.  When the
test is run on Power 10, an internal gdb error occurs when the PowerPC
routine tries to setup the three hardware watchpoint address since the hw
only has two hardware watchpoint registers.  The error occurs because the
resource checking was not redone in update_watchpoints after
**global_ptr_ptr changed.

The following descibes the situation in detail that occurs on Power 10 with
gdb running on the binary for gdb.base/watchpoint.c.

1 break func4
2 run
3 watch *global_ptr
4 next      execute source code:   buf[0] = 3;
5 next      execute source code:   global_ptr = buf;
6 next      execute source code:   buf[0] = 7;
7 delete 2  (delete watch *global_ptr)
8 watch **global_ptr_ptr
9 next       execute source code:   buf[1] = 5;
10 next      global_ptr_ptr = &global_ptr;
11 next      buf[0] = 9;

In step 8, the the watch **global_ptr_prt command calls update_watchpoint
in breakpoint.c with REPARSE set to 1.  The function update_watchpoint
calls can_use_hardware_watchpoint to see if there are enough
resources available to add the watchpoint since REPARSE is set to 1.  At
this point, **global_ptr_ptr has not been initialized so only two addresses
are watched.  The val_chain contains the address for **global_ptr_ptr and 0
since **global_ptr_ptr has not been initialized.  The update_watchpoint
updates the breakpoint list as follows:

  breakpoint 0
   loc 0: b->address = 0x100009c0
  breakpoint 1
   loc 1: b->address = 0x7ffff7f838a0
  breakpoint 2
   loc 2: b->address = 0x7ffff7b7fc54
  breakpoint 3
   loc 3: b->address = 0x7ffff7a5788c
  breakpoint 4
   loc 4: b->address = 0x0         <-- location pointed to by global_ptr_ptr
   loc 5: b->address = 0x100200b8  <-- global_ptr_ptr watchpoint
  breakpoint 5
   loc 6: b->address = 0x7ffff7b7fc54

In step 10, the next command executes the source code
global_ptr_ptr = &global_ptr.  This changes the set of locations to be
watched for the watchpoint **global_ptr_prt.  The list of addresses for the
breakpoint consist of the address for global_ptr_prt, global_ptr and buf.
The breakpoint list gets updated by update_watchpoint as follows:

  breakpoint 0
   loc 0: b->address = 0x100009c0
  breakpoint 1
   loc 1: b->address = 0x7ffff7f838a0
  breakpoint 2
   loc 2: b->address = 0x7ffff7b7fc54
  breakpoint 3
   loc 3: b->address = 0x7ffff7a5788c
  breakpoint 4
   loc 4: b->address = 0x10020050           buf
   loc 5: b->address = 0x100200b0           watch *global_ptr
   loc 6: b->address = 0x100200b8           watch **global_ptr_ptr
  breakpoint 5
   loc 7: b->address = 0x7ffff7b7fc54
  breakpoint 6

However, the hardware resource checking was not redone because
update_breakpoint was called with REPARSE equal to  0.

Step 11, execute the third next command.  The function
ppc_linux_nat_target::low_prepare_to_resume() attempts a ptrace
call to setup each of the three address for breakpoint 4.  The slot
value returned for the third ptrace call is -1 indicating an error
because there are only two hardware watchpoint registers available on
Power 10.

This patch removes just the statement "if (reparse)" in function
update_watchpoint to force the resources to be rechecked on every call to
the function.  This ensures that any changes to the val_chain resulting
in needing more resources then available will be caught.

The patch has been tested on Power 8, Power 10 and X86-64.  Note the patch
has no effect on Power 9 since hardware watchpoint support is disabled on
that processor.
---
 gdb/breakpoint.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index e9aee6315fa..24c4af3c968 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -2126,10 +2126,9 @@ update_watchpoint (struct watchpoint *b, int reparse)
 	}
 
       /* Change the type of breakpoint between hardware assisted or
-	 an ordinary watchpoint depending on the hardware support
-	 and free hardware slots.  REPARSE is set when the inferior
-	 is started.  */
-      if (reparse)
+	 an ordinary watchpoint depending on the hardware support and
+	 free hardware slots.  Recheck the number of free hardware slots
+	 as the value chain may have changed.  */
 	{
 	  int reg_cnt;
 	  enum bp_loc_type loc_type;
-- 
2.37.2



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Remove REPARSE condition to force hardware resource checking when updating watchpoints
  2022-10-18 16:42 [PATCH] Remove REPARSE condition to force hardware resource checking when updating watchpoints Carl Love
@ 2022-10-28 13:28 ` Ulrich Weigand
  0 siblings, 0 replies; 2+ messages in thread
From: Ulrich Weigand @ 2022-10-28 13:28 UTC (permalink / raw)
  To: gdb-patches, cel; +Cc: will_schmidt

Carl Love <cel@us.ibm.com> wrote:

>Remove REPARSE condition to force hardware resource checking when updating watchpoints

This is OK.

Thanks,
Ulrich


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-10-28 13:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-18 16:42 [PATCH] Remove REPARSE condition to force hardware resource checking when updating watchpoints Carl Love
2022-10-28 13:28 ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).