Hi!
It easier to test on different targets if we have an actual patch to try.
That said, I fear it will not get a lot of testing as you'd probably have
to be affected by this corner case to bother.
I don't really follow the logic that GDB can't know which bp/wp was hit. Is
it because the halt $pc is so close to the other breakpoint? How close must
they be to trigger this special casing?
If we advertise swbreak in qSupported, won't we also have to actually send
swbreak in gdb_signal_reply()? Currently we only send the watchpoint stop
reasons. We'd need some mechanism to determine whether to send hwbreak or
swbreak. Hopefully this can be done generically (like looking through the
list of HW breakpoins and if none match $pc then it's a SW breakpoint
perhaps).
/Andreas
On Tue, Oct 4, 2016 at 9:47 PM, Tim Newsome <t...@sifive.com> wrote:
> Does anybody have an opinion here? Should I just submit the simple "fix"
> into gerrit and have the discussion there?
>
> Tim
>
> On Thu, Sep 22, 2016 at 12:25 PM, Tim Newsome <t...@sifive.com> wrote:
>
>> I ran into the following problem, debugging this:
>>
>> 8000036c <just_before_read_loop>:
>> 8000036c: 01000393 li t2,16
>>
>> 80000370 <read_loop>:
>> 80000370: 00052303 lw t1,0(a0)
>>
>> Set a software breakpoint on just_before_read_loop, and run to it. Then
>> set a hardware watchpoint on the address in a0. Tell gdb to continue.
>> Gdb clears breakpoints and single steps to get past the software
>> breakpoint. Then it sets all breakpoints again, and tells the target to
>> resume. The target halts at read_loop because the watchpoint is hit, and
>> reports a trap at 0x80000370. gdb however, then forcibly writes back the pc
>> to 0x8000036c. The code for this behavior in gdb is in
>> adjust_pc_after_break() (infrun.c). I didn’t follow that code in detail,
>> but it seems to come down to gdb decrementing the PC because it’s not sure
>> whether the software breakpoint or the watchpoint was hit.
>>
>> If OpenOCD tells gdb that it can tell the difference between the two,
>> then this code is bypassed and everything works as I expect. OpenOCD can do
>> that by adding swbreak+ to the reply to qSupported as follows:
>>
>> --- a/src/server/gdb_server.c
>> +++ b/src/server/gdb_server.c
>> @@ -2357,7 +2357,7 @@ static int gdb_query_packet(struct connection
>> *connection,
>> &buffer,
>> &pos,
>> &size,
>> -
>> "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;QStartNoAckMode+",
>> +
>> "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;QStartNoAckMode+;swbreak+",
>> (GDB_BUFFER_SIZE - 1),
>> ((gdb_use_memory_map == 1) &&
>> (flash_get_bank_count() > 0)) ? '+' : '-',
>> (gdb_target_desc_supported == 1) ? '+' : '-');
>>
>> My question is: is this safe for all targets? If it is, this is an easy
>> change. If not, I’ll have to invent some mechanism for targets to let the
>> gdb_server layer know what should be returned. If that’s required, are
>> there any guidelines I should follow?
>>
>> My target is RISC-V, which I’m working on implementing OpenOCD support
>> for. I imagine this same issue exists on other targets as well.
>>
>> Thank you,
>> Tim
>>
>>
>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel