This is the mail archive of the
mailing list for the GDB project.
Re: [RFA/commit] arm-tdep.c: Do not single-step after hitting a watchpoint
- From: Pedro Alves <palves at redhat dot com>
- To: Will Deacon <will dot deacon at arm dot com>
- Cc: Peter Maydell <peter dot maydell at linaro dot org>, Joel Brobecker <brobecker at adacore dot com>, Marcus Shawcroft <marcus dot shawcroft at gmail dot com>, Terry Guo <Terry dot Guo at arm dot com>, Marcus Shawcroft <Marcus dot Shawcroft at arm dot com>, "lgustavo at codesourcery dot com" <lgustavo at codesourcery dot com>, "yao at codesourcery dot com" <yao at codesourcery dot com>, "gdb-patches at sourceware dot org" <gdb-patches at sourceware dot org>, "Gareth, McMullin" <gareth at blacksphere dot co dot nz>
- Date: Tue, 30 Sep 2014 11:07:21 +0100
- Subject: Re: [RFA/commit] arm-tdep.c: Do not single-step after hitting a watchpoint
- Authentication-results: sourceware.org; auth=none
- References: <CAFEAcA_0C+UqGwM39A4EQCQLg59fNbJ2du8rhrt++Q-pdE9rgQ at mail dot gmail dot com> <5429D9FC dot 6000509 at redhat dot com> <CAFEAcA9Dx5GE6QCktvbQF8sL1MsRxE5BmPNruSw4FsW9VyD_2w at mail dot gmail dot com> <542A72F9 dot 5090203 at redhat dot com> <20140930091824 dot GE8075 at arm dot com>
On 09/30/2014 10:18 AM, Will Deacon wrote:
> On Tue, Sep 30, 2014 at 10:08:09AM +0100, Pedro Alves wrote:
>> The report that confuses me is Gareth's:
>> As it sounds like he has v7-m hardware that has asynchronous
>> behavior. Gareth, can you confirm this, please?
> Running Linux or bare-metal? The hw_breakpoint code in the kernel certainly
> wasn't written with v7-m in mind and I'd be surprised if it even probed
> successfully at boot.
Judging from the black magic probes' description at:
http://www.blacksphere.co.nz/main/blackmagic, definitely bare-metal.
>> Still, in any case, from that LKML post:
>> "v6 cores are the opposite; they only generate asynchronous
>> watchpoint exceptions".
>> So, eh!? Does your qemu patch take this into account? Seems
>> like it should.
> Hmm, I didn't realise v6 was on the table here.
GDB supports that, and older. Doesn't qemu do v6?
> In that case, you need to signal an async exception and set the WFAR
> register to indicate the watchpointed instruction. Not that Linux uses this...
Yeah, even though Linux doesn't use this, this then must be what bare metal
probes and other OSs will necessarily be using to support watchpoints on < v7.
OK, then on v6 (and earlier), the WFAR will be (as Luis pointed out
(ARM1156T2F-S, IIUC, that's a v6)
WFAR - Watchpoint Fault Address Register
The WFAR is updated to indicate the address of the instruction that
accessed the watchpointed address:
- the address of the instruction + 8 in ARM state
- the address of the instruction + 4 in Thumb® state
What wasn't clear to me was whether this meant that the
instruction at the address of the instruction, and
at the the address of the instruction +4/+2 (ARM/Thumb) had
executed completely or not. It's my understanding now that,
yes, both the instruction that caused the watchpoint and the
instruction after that one have already been executed.
I may be missing something, but that page leaves me wondering
what happens if the instruction after the instruction that caused
the watchpoint is a branch. Will the WFAR point still point
at "address + 8" ? Or will it point at the branch destination?
In any case, it sounds like _nothing_ should be unwinding the PC
back -8 nor -4 to help the debugger, as that would make the
program re-execute instructions that had already executed.
For further confirmation, I looked at the v6-m manual I have
handy (DDI 0419C). There, I see:
The following are asynchronous debug events:
- Watchpoint debug events, including PC match watchpoints
And then on C1.6.4
The DebugReturnAddress value
DebugReturnAddress is the address of the first instruction to be executed on exit from Debug state. This
address indicates the point in the execution stream where the debug event was invoked. For a hardware or
a software breakpoint, this is the address of the breakpointed instruction. For all other debug events,
including PC match watchpoints, DebugReturnAddress is the address of the first instruction that both:
- in a simple sequential execution of the program, executes after the instruction that caused the debug
- has not been executed.
And in C1.7.1
A watchpoint event is asynchronous to the instruction that caused it. The DebugReturnAddress value for a
watchpoint event must be that of an instruction to be executed after the instruction responsible for
generating the watchpoint.
This seems to confirm my current understanding that indeed that +8/+4 offset
in WFAR should _never_ be adjusted, as the instructions at +0 and +4/+2 have
already been executed.
So, my current understanding is that when debugging a < v7 target, GDB
should always treat watchpoints as continuable (asynchronous), as that's
all the hardware supports/supported.
And when debugging a >= v7 target, GDB should treat watchpoints as
synchronous as that's all real hardware supports (even though
the architecture permits both sync and async, in theory).
And if we do this in GDB, then it's be better that qemu likewise
treats watchpoints as asynchronous on < v7, so that GDB doesn't need to
know whether it's talking to real bare-metal and against qemu.
Does that make sense?
> The comment/code above is about finding the address of the memory access
> that triggered the watchpoint, as opposed to the address of the instruction.
> (e.g. if I load from address FOO, then I only get told about FOO in v7.1).