From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1983) id A81B53855589; Mon, 31 Oct 2022 18:44:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A81B53855589 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1667241881; bh=+NZFjatrZLohTDW93ttd07aR4hgG8gijhmoGotQrFCU=; h=From:To:Subject:Date:From; b=i1tp4oj10eqm5wKqpv5CoUCUZw8FUD0LlwnBH5YaTKG6LzAgvw8Q9gGwWKgY+QFmB 1++hJiqrRfgJqRGqti4gbeo6pCKxjQxrLAzD2z+XRQADjnNj+jzU9MU1bskv4uYmQp +ZdfdZSh/cYSMCbFklNRsz5HlNy/2lY8nb1MhYEQ= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Carl Love To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Remove REPARSE condition to force hardware resource checking when updating watchpoints X-Act-Checkin: binutils-gdb X-Git-Author: Carl Love X-Git-Refname: refs/heads/master X-Git-Oldrev: 15a1e4e2a7dac11fdf338c70efc355348d8a6d49 X-Git-Newrev: bc45f5366eaf4e93cfd675a07a8cc5bb5522b184 Message-Id: <20221031184441.A81B53855589@sourceware.org> Date: Mon, 31 Oct 2022 18:44:41 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dbc45f5366eaf= 4e93cfd675a07a8cc5bb5522b184 commit bc45f5366eaf4e93cfd675a07a8cc5bb5522b184 Author: Carl Love Date: Mon Oct 31 14:44:17 2022 -0400 Remove REPARSE condition to force hardware resource checking when updat= ing watchpoints =20 Currently the resource checking is done if REPARSE is true. The hardwa= re 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 t= he resource checking was not redone in update_watchpoints after **global_ptr_ptr changed. =20 The following descibes the situation in detail that occurs on Power 10 = with gdb running on the binary for gdb.base/watchpoint.c. =20 1 break func4 2 run 3 watch *global_ptr 4 next execute source code: buf[0] =3D 3; 5 next execute source code: global_ptr =3D buf; 6 next execute source code: buf[0] =3D 7; 7 delete 2 (delete watch *global_ptr) 8 watch **global_ptr_ptr 9 next execute source code: buf[1] =3D 5; 10 next global_ptr_ptr =3D &global_ptr; 11 next buf[0] =3D 9; =20 In step 8, the the watch **global_ptr_prt command calls update_watchpoi= nt 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 addre= sses are watched. The val_chain contains the address for **global_ptr_ptr a= nd 0 since **global_ptr_ptr has not been initialized. The update_watchpoint updates the breakpoint list as follows: =20 breakpoint 0 loc 0: b->address =3D 0x100009c0 breakpoint 1 loc 1: b->address =3D 0x7ffff7f838a0 breakpoint 2 loc 2: b->address =3D 0x7ffff7b7fc54 breakpoint 3 loc 3: b->address =3D 0x7ffff7a5788c breakpoint 4 loc 4: b->address =3D 0x0 <-- location pointed to by global_= ptr_ptr loc 5: b->address =3D 0x100200b8 <-- global_ptr_ptr watchpoint breakpoint 5 loc 6: b->address =3D 0x7ffff7b7fc54 =20 In step 10, the next command executes the source code global_ptr_ptr =3D &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 bu= f. The breakpoint list gets updated by update_watchpoint as follows: =20 breakpoint 0 loc 0: b->address =3D 0x100009c0 breakpoint 1 loc 1: b->address =3D 0x7ffff7f838a0 breakpoint 2 loc 2: b->address =3D 0x7ffff7b7fc54 breakpoint 3 loc 3: b->address =3D 0x7ffff7a5788c breakpoint 4 loc 4: b->address =3D 0x10020050 buf loc 5: b->address =3D 0x100200b0 watch *global_ptr loc 6: b->address =3D 0x100200b8 watch **global_ptr_ptr breakpoint 5 loc 7: b->address =3D 0x7ffff7b7fc54 breakpoint 6 =20 However, the hardware resource checking was not redone because update_breakpoint was called with REPARSE equal to 0. =20 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. =20 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. =20 The patch has been tested on Power 8, Power 10 and X86-64. Note the pa= tch has no effect on Power 9 since hardware watchpoint support is disabled = on that processor. Diff: --- gdb/breakpoint.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 30826032360..490708938ec 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -2123,10 +2123,9 @@ update_watchpoint (struct watchpoint *b, bool repars= e) } =20 /* 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;