2008-10-18 Pedro Alves * infrun.c (adjust_pc_after_break): Do nothing if executing in reverse. --- gdb/infrun.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) Index: src/gdb/infrun.c =================================================================== --- src.orig/gdb/infrun.c 2008-10-18 02:06:15.000000000 +0100 +++ src/gdb/infrun.c 2008-10-18 02:09:36.000000000 +0100 @@ -1787,6 +1787,33 @@ adjust_pc_after_break (struct execution_ if (ecs->ws.value.sig != TARGET_SIGNAL_TRAP) return; + /* In reverse execution, when a breakpoint is hit, the instruction + under it has already been de-executed. The reported PC always + points at the breakpoint address, so adjusting it further would + be wrong. E.g., consider: + + B1 0x08000000 : INSN1 + B2 0x08000001 : INSN2 + 0x08000002 : INSN3 + PC -> 0x08000003 : INSN4 + + Say you're stopped at 0x08000003 as above. Reverse continuing + from that point should hit B2 as below. Reading the PC when the + SIGTRAP is reported should read 0x08000001 and INSN2 should have + been de-executed already. + + B1 0x08000000 : INSN1 + B2 PC -> 0x08000001 : INSN2 + 0x08000002 : INSN3 + 0x08000003 : INSN4 + + If we tried to adjust the PC on for example, a + decr_pc_after_break == 1 architecture, we would wrongly further + adjust the PC to 0x08000000 and report a hit on B1, although the + INSN1 effects hadn't been de-executed yet. */ + if (execution_direction == EXEC_REVERSE) + return; + /* If this target does not decrement the PC after breakpoints, then we have nothing to do. */ regcache = get_thread_regcache (ecs->ptid);