From: Pedro Alves <palves@redhat.com>
To: Peter Maydell <peter.maydell@linaro.org>,
Joel Brobecker <brobecker@adacore.com>
Cc: Marcus Shawcroft <marcus.shawcroft@gmail.com>,
Terry.Guo@arm.com,
Marcus Shawcroft <Marcus.Shawcroft@arm.com>,
"lgustavo@codesourcery.com" <lgustavo@codesourcery.com>,
yao@codesourcery.com, gdb-patches@sourceware.org,
Will Deacon <Will.Deacon@arm.com>,
"Gareth, McMullin" <gareth@blacksphere.co.nz>
Subject: Re: [RFA/commit] arm-tdep.c: Do not single-step after hitting a watchpoint
Date: Mon, 29 Sep 2014 22:15:00 -0000 [thread overview]
Message-ID: <5429D9FC.6000509@redhat.com> (raw)
In-Reply-To: <CAFEAcA_0C+UqGwM39A4EQCQLg59fNbJ2du8rhrt++Q-pdE9rgQ@mail.gmail.com>
On 09/29/2014 07:23 PM, Peter Maydell wrote:
> Joel Brobecker wrote:
>> I have been trying to understand the various contributions, and
>> I admit I am still not quite sure...
>>
>> Does it look like the patch I proposed is correct? It seems to be
>> supported by Terry Guo's experiments as well...
>
> Note that the ARMv7 architecture allows watchpoints to
> be implemented as *asynchronous*, in which case what
> you will see is that you take a watchpoint exception
> but it may not fire until after the instruction that
> triggers the watchpoint and possibly several following
> instructions have all finished execution. This may be
> what you are seeing in your hardware tests.
>
> For *synchronous* watchpoints, the behaviour is that the
> CPU stops *before* execution of the instruction which
> triggers the fault, and the memory access does not take
> place. This is pretty clearly described in the ARM ARM
> (see DDI0406C.c section C3.4.4 "Synchronous and asynchronous
> Watchpoint debug events" and the referenced "Effects of
> data-aborted instructions" section).
I only have DDI 0406C.b handy, which says:
ARMv7 permits watchpoints to be either synchronous or asynchronous. An implementation can implement
synchronous watchpoints, asynchronous watchpoints, or both. It is IMPLEMENTATION DEFINED under what
circumstances a watchpoint is synchronous or asynchronous.
Ouch. So this IMPLEMENTATION DEFINED note means this isn't really
in control of the software/debugger, i.e., nothing a stub/probe
could tweak, but instead baked into the specific ARM chip?
Or is there some register the probe could tweak to change
the this behavior?
Now I'm confused on the mention of the Linux kernel
subtracting 8 from the PC to help GDB. I can't find that
anywhere in the kernel's sources.
> For ARMv8 (so including all AArch64 CPUs) watchpoints must
> be synchronous.
Ah, so this issue will eventually go away on its own. :-)
>
> QEMU's built in gdbstub was incorrectly not implementing
> synchronous watchpoints (ie it was halting after the
> execution of the offending insn, not before). This is fixed
> by the QEMU patch referenced earlier, and with that patch
> QEMU and GDB interoperate correctly (on ARM and also on
> other architectures which have the "stop before insn"
> watchpoint semantics).
"Incorrect" may be too strong then, but understood.
>
> GDB should continue to set have_nonsteppable_watchpoint
> for ARM architectures, indicating:
> * watchpoints fire before the insn executes
> * you need to disable the watchpoint to successfully
> singlestep the insn
> as this is correct for synchronous watchpoints.
>
> If you have h/w with asynchronous watchpoints then there
> really isn't much you can do about stopping in the
> right place. Ideally I guess gdb would not do a step
> in that case, but I don't think it has access to
> enough info about the target CPU to know this (the
> kernel does get this info in the DBGDSCR.MOE register
> field, which is different for synchronous and
> asynchronous watchpoint events).
Ah. In the kernel I have handy, I see:
/*
* Called from either the Data Abort Handler [watchpoint] or the
* Prefetch Abort Handler [breakpoint] with interrupts disabled.
*/
static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
struct pt_regs *regs)
{
int ret = 0;
u32 dscr;
preempt_disable();
if (interrupts_enabled(regs))
local_irq_enable();
/* We only handle watchpoints and hardware breakpoints. */
ARM_DBG_READ(c0, c1, 0, dscr);
/* Perform perf callbacks. */
switch (ARM_DSCR_MOE(dscr)) {
case ARM_ENTRY_BREAKPOINT:
breakpoint_handler(addr, regs);
break;
case ARM_ENTRY_ASYNC_WATCHPOINT:
WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n");
case ARM_ENTRY_SYNC_WATCHPOINT:
watchpoint_handler(addr, fsr, regs);
break;
default:
ret = 1; /* Unhandled fault. */
}
preempt_enable();
return ret;
}
(note the ARM_ENTRY_ASYNC_WATCHPOINT case falls-through.)
So even on Linux, iiuc, it's possible to see a watchpoint
trigger after the write has already happened; it'll depend on
hardware implementation.
I think the most flexible would be if the watchpoint
event reported to GDB indicated which type it got, so
that'd support the case an arch ever supports mixing both
kinds of watchpoints.
The next option would be something in the xml target description.
It's be a global per-target, so no mixing types of watchpoints.
(That is either sent to gdb by the stub, or loaded manually
with "set tdesc filename".)
Failing all that, we may want a "set arm ..." knob to
override the default...
Or we just forget all this, assuming that ARM chips that
have async watchpoints will disappear into obsolescence
forever soon enough. :-)
Thanks,
Pedro Alves
next prev parent reply other threads:[~2014-09-29 22:15 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-29 18:23 Peter Maydell
2014-09-29 22:15 ` Pedro Alves [this message]
2014-09-29 22:54 ` Peter Maydell
2014-09-30 9:08 ` Pedro Alves
2014-09-30 9:18 ` Will Deacon
2014-09-30 10:07 ` Pedro Alves
2014-09-30 10:18 ` Peter Maydell
2014-09-30 10:38 ` Pedro Alves
2014-09-30 10:01 ` Peter Maydell
2014-09-30 10:34 ` Pedro Alves
2014-09-30 12:54 ` Pedro Alves
2014-09-30 13:50 ` Joel Brobecker
2014-09-30 14:11 ` Pedro Alves
2014-09-30 14:26 ` Joel Brobecker
2014-09-30 14:50 ` Peter Maydell
2014-09-30 8:57 ` Will Deacon
2014-09-30 9:04 ` Will Deacon
2014-09-30 9:14 ` Pedro Alves
2014-09-30 9:24 ` Will Deacon
-- strict thread matches above, loose matches on Subject: below --
2014-09-15 13:01 Joel Brobecker
2014-09-16 11:12 ` Yao Qi
2014-09-16 11:59 ` Joel Brobecker
2014-09-16 12:05 ` Luis Machado
2014-09-16 12:48 ` Joel Brobecker
2014-09-16 13:09 ` Luis Machado
2014-09-16 15:21 ` Pedro Alves
2014-09-18 11:40 ` Marcus Shawcroft
2014-09-19 17:31 ` Pedro Alves
2014-09-29 17:51 ` Joel Brobecker
2014-09-29 17:57 ` Luis Machado
2014-09-29 21:04 ` Pedro Alves
2014-09-30 8:54 ` Will Deacon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5429D9FC.6000509@redhat.com \
--to=palves@redhat.com \
--cc=Marcus.Shawcroft@arm.com \
--cc=Terry.Guo@arm.com \
--cc=Will.Deacon@arm.com \
--cc=brobecker@adacore.com \
--cc=gareth@blacksphere.co.nz \
--cc=gdb-patches@sourceware.org \
--cc=lgustavo@codesourcery.com \
--cc=marcus.shawcroft@gmail.com \
--cc=peter.maydell@linaro.org \
--cc=yao@codesourcery.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox