From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 54A2138582BB; Tue, 12 Mar 2024 16:07:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 54A2138582BB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1710259654; bh=BD/g9qYXrvIIpV0xK3LWwtxUgLuPpKKNl/Zq/EoFRmI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=OopJNK7864uB/lhyZtPIFPk4RRqX95ENHD84KrtjyxCBihghetB2FlPNqaT2vZoQv iMzvMJEA+GXuahwI+Tl3+w9czeYE4TDm8WEBQZGAqsAaEYu7FL6d0IWB4LcOrCyjDV /25bPcyAVbE95zziwnhvzmHYYaIP0YCIakSr8Jxo= From: "cvs-commit at gcc dot gnu.org" To: gdb-prs@sourceware.org Subject: [Bug tdep/31214] [gdb, aarch64] FAIL: gdb.base/watch-bitfields.exp: -location watch against bitfields: q.e: 0->5: continue Date: Tue, 12 Mar 2024 16:07:33 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gdb X-Bugzilla-Component: tdep X-Bugzilla-Version: 15.1 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: cvs-commit at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://sourceware.org/bugzilla/show_bug.cgi?id=3D31214 --- Comment #5 from Sourceware Commits --- The master branch has been updated by Tom de Vries : https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dcf16ab724a41= e4cbaf723b5633d4e7b29f61372b commit cf16ab724a41e4cbaf723b5633d4e7b29f61372b Author: Tom de Vries Date: Tue Mar 12 17:08:18 2024 +0100 [gdb/tdep] Fix gdb.base/watch-bitfields.exp on aarch64 On aarch64-linux, with test-case gdb.base/watch-bitfields.exp I run int= o: ... (gdb) continue^M Continuing.^M ^M Hardware watchpoint 2: -location q.a^M ^M Old value =3D 1^M New value =3D 0^M main () at watch-bitfields.c:42^M 42 q.h--;^M (gdb) FAIL: $exp: -location watch against bitfields: q.e: 0->5: continue ... In a minimal form, if we step past line 37 which sets q.e, and we have a watchpoint set on q.e, it triggers: ... $ gdb -q -batch watch-bitfields -ex "b 37" -ex run -ex "watch q.e" -ex = step Breakpoint 1 at 0x410204: file watch-bitfields.c, line 37. Breakpoint 1, main () at watch-bitfields.c:37 37 q.e =3D 5; Hardware watchpoint 2: q.e Hardware watchpoint 2: q.e Old value =3D 0 New value =3D 5 main () at /home/vries/gdb/src/gdb/testsuite/gdb.base/watch-bitfields.c= :38 38 q.f =3D 6; ... However, if we set in addition a watchpoint on q.a, the watchpoint on q= .e doesn't trigger. How does this happen? Bitfield q.a is just bit 0 of byte 0, and bitfield q.e is bit 4..7 of b= yte 1 and bit 1 of byte 2. So, watch q.a should watch byte 0, and watch q.e should watch bytes 1 and 2. Using "maint set show-debug-regs on" (and some more detailed debug prin= ts) we get: ... WP2: addr=3D0x440028 (orig=3D0x440029), ctrl=3D0x000000d5, ref.count=3D1 ctrl: enabled=3D1, offset=3D1, len=3D2 WP3: addr=3D0x440028 (orig=3D0x440028), ctrl=3D0x00000035, ref.count=3D1 ctrl: enabled=3D1, offset=3D0, len=3D1 ... which matches that. When executing line 37, a hardware watchpoint trap triggers and we hit aarch64_stopped_data_address with addr_trap =3D=3D 0x440028: ... (gdb) p /x addr_trap $1 =3D 0x440028 .... and since the loop in aarch64_stopped_data_address walks backward, we c= heck WP3 first, which matches, and consequently target_stopped_by_watchpoint returns true in watchpoints_triggered. Likewise for target_stopped_data_address, which also returns addr =3D=3D 0x440028. Watchpoints_triggered matches watchpoint q.a to that address, and sets watch_triggered_yes. However, subsequently the value of q.a is checked, and it's the same va= lue as before (becase the insn in line 37 didn't change q.a), so the watchpoint hardware trap is not reported to the user. The problem originates from that fact that aarch64_stopped_data_address picked WP3 instead of WP2. There's something we can do about this. In the example above, both target_stopped_by_watchpoint and target_stopped_data_address returned t= rue. Instead we can return true in target_stopped_by_watchpoint but false in target_stopped_data_address. This lets watchpoints_triggered known tha= t a watchpoint was triggered, but we don't know where, and both watchpoints get set to watch_triggered_unknown. Subsequently, the values of both q.a and q.e are checked, and since q.e= is not the same value as before, the watchpoint hardware trap is reported to t= he user. Note that this works well for regular (write) watchpoints (watch comman= d), but not for read watchpoints (rwatch command), because for those no value is checked. Likewise for access watchpoints (awatch command). So, fix this by: - passing a nullptr in aarch64_fbsd_nat_target::stopped_by_watchpoint a= nd aarch64_linux_nat_target::stopped_by_watchpoint to make clear we're n= ot interested in the stop address, - introducing a two-phase approach in aarch64_stopped_data_address, whe= re: - phase one handles access and read watchpoints, as before, and - phase two handles write watchpoints, where multiple matches cause: - return true if addr_p =3D=3D null, and - return false if addr_p !=3D null. Tested on aarch64-linux. Approved-By: Luis Machado PR tdep/31214 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=3D31214 --=20 You are receiving this mail because: You are on the CC list for the bug.=