From: Pedro Alves <pedro@codesourcery.com>
To: gdb-patches@sourceware.org
Cc: Michael Snyder <msnyder@vmware.com>, teawater <teawater@gmail.com>
Subject: Re: [reverse/record] adjust_pc_after_break in reverse execution mode?
Date: Mon, 20 Oct 2008 12:10:00 -0000 [thread overview]
Message-ID: <200810201309.35333.pedro@codesourcery.com> (raw)
In-Reply-To: <48FBD342.5070905@vmware.com>
[-- Attachment #1: Type: text/plain, Size: 3062 bytes --]
A Monday 20 October 2008 01:39:30, Michael Snyder escreveu:
> Pedro Alves wrote:
> > On Sunday 19 October 2008 23:39:20, Michael Snyder wrote:
> >> After codgitating for a bit (that's "thinking" when you're over 50),
> >> I've decided that you're right.
> >>
> >> However, I have a new concern -- I'm worried about what it will do
> >> when it's replaying but going forward.
> >>
> >> Could you possibly revisit your test and see what it does
> >> if you record all the way to line 9 or 10, then back up
> >> to line 6, then continue with breakpoints at 6 and 7?
> >
> > Eh, you're right. It's broken.
>
> Thought so.
>
> See, the problem is that "adjust_pc_after_break" is assuming
> memory-breakpoint semantics, but Process Record/Replay actually
> implements hardware-breakpoint semantics. It watches the
> instruction-address "bus" and stops when the PC matches the
> address of a breakpoint.
>
> I suspect this is probably a problem with other record/replay
> back-ends too, but I haven't confirmed it yet.
>
> Still, I think that the patch you committed was correct
> for the reverse case.
> This is a corner case that reveals
> that "reverse" and "replay" are not synonymous.
They certainly aren't. When replaying, I believe it's just best to
behave as close as possible to when it the inferior is really running.
From the inferior control side, GDB be mostly as agnostic about
"replay" vs normal run as possibly.
IIUC from reading the code, I see two issues.
1) When going forward and in reply mode, breakpoint hits are being checked
*after* a record item is replays. IIUC, we should check *before*,
and report an adjusted PC.
2) Un-inserted breakpoints weren't accounted for AFAICT (GDB will
un-inserted breakpoints temporarily when stepping over them).
Maybe they are, I got lost. :-) There's a loop going through the
bp_location_chain. Can you get rid of that and use
regular_breakpoint_inserted_here_p or similars?
Below is a 10 minutes hack at it, as a starting point. Replay stil
isn't perfect, mainly because I got lost in the record_wait maze --- that,
needs a bit of clean up. :-)
>
> > (gdb) record
> > (gdb) b 6
> > Breakpoint 2 at 0x8048352: file nop.c, line 6.
> > (gdb) b 7
> > Breakpoint 3 at 0x8048353: file nop.c, line 7.
> > (gdb) n
> >
> > Breakpoint 3, main () at nop.c:7
> > 7 asm ("nop");
> > (gdb) n
> > 8 asm ("nop");
> > (gdb)
> > 9 asm ("nop");
> > (gdb) n
> > 10 }
> > (gdb) rc
> > Continuing.
> >
> > Breakpoint 3, main () at nop.c:7
> > 7 asm ("nop");
> > (gdb) rn
> >
> > No more reverse-execution history.
> > main () at nop.c:6
> > 6 asm ("nop");
> > (gdb) n
> >
> > Breakpoint 2, main () at nop.c:6
> > 6 asm ("nop");
> > (gdb)
> > 8 asm ("nop");
> > (gdb)
> > 9 asm ("nop");
> > (gdb)
> >
> >
> >
> > --
> > Pedro Alves
>
>
--
Pedro Alves
[-- Attachment #2: record_decr_pc.diff --]
[-- Type: text/x-diff, Size: 8073 bytes --]
---
gdb/record.c | 159 +++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 101 insertions(+), 58 deletions(-)
Index: src/gdb/record.c
===================================================================
--- src.orig/gdb/record.c 2008-10-20 00:48:50.000000000 +0100
+++ src/gdb/record.c 2008-10-20 13:02:38.000000000 +0100
@@ -497,6 +497,9 @@ record_wait (ptid_t ptid, struct target_
int continue_flag = 1;
int first_record_end = 1;
struct cleanup *old_cleanups = make_cleanup (record_wait_cleanups, 0);
+ CORE_ADDR pc;
+ record_t *curr_record;
+ int first = 1;
record_get_sig = 0;
act.sa_handler = record_sig_handler;
@@ -512,20 +515,13 @@ record_wait (ptid_t ptid, struct target_
Then set it to terminal_ours to make GDB get the signal. */
target_terminal_ours ();
- /* In EXEC_FORWARD mode, record_list point to the tail of prev
- instruction. */
- if (execution_direction == EXEC_FORWARD && record_list->next)
- {
- record_list = record_list->next;
- }
-
/* Loop over the record_list, looking for the next place to
stop. */
status->kind = TARGET_WAITKIND_STOPPED;
do
{
/* Check for beginning and end of log. */
- if (execution_direction == EXEC_REVERSE
+ if (execution_direction == EXEC_REVERSE
&& record_list == &record_first)
{
/* Hit beginning of record log in reverse. */
@@ -539,8 +535,51 @@ record_wait (ptid_t ptid, struct target_
break;
}
+ /* Check for breakpoint hits in forward execution. */
+ pc = read_pc ();
+ if (execution_direction == EXEC_FORWARD
+ && regular_breakpoint_inserted_here_p (pc)
+ /* && !single-stepping */)
+ {
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ if (software_breakpoint_inserted_here_p (pc))
+ pc += gdbarch_decr_pc_after_break (current_gdbarch);
+ write_pc (pc);
+
+ if (sigaction (SIGALRM, &old_act, NULL))
+ perror_with_name (_("Process record: sigaction"));
+
+ discard_cleanups (old_cleanups);
+ return inferior_ptid;
+ }
+
+ if (first)
+ {
+ first = 0;
+ /* In EXEC_FORWARD mode, record_list point to the tail of prev
+ instruction. */
+ if (execution_direction == EXEC_FORWARD && record_list->next)
+ {
+ record_list = record_list->next;
+ }
+ }
+
+ curr_record = record_list;
+
+ if (execution_direction == EXEC_REVERSE)
+ {
+ if (record_list->prev)
+ record_list = record_list->prev;
+ }
+ else
+ {
+ if (record_list->next)
+ record_list = record_list->next;
+ }
+
/* set ptid, register and memory according to record_list */
- if (record_list->type == record_reg)
+ if (curr_record->type == record_reg)
{
/* reg */
gdb_byte reg[MAX_REGISTER_SIZE];
@@ -548,43 +587,43 @@ record_wait (ptid_t ptid, struct target_
{
fprintf_unfiltered (gdb_stdlog,
"Process record: record_reg 0x%s to inferior num = %d.\n",
- paddr_nz ((CORE_ADDR)record_list),
- record_list->u.reg.num);
+ paddr_nz ((CORE_ADDR)curr_record),
+ curr_record->u.reg.num);
}
- regcache_cooked_read (regcache, record_list->u.reg.num, reg);
- regcache_cooked_write (regcache, record_list->u.reg.num,
- record_list->u.reg.val);
- memcpy (record_list->u.reg.val, reg, MAX_REGISTER_SIZE);
+ regcache_cooked_read (regcache, curr_record->u.reg.num, reg);
+ regcache_cooked_write (regcache, curr_record->u.reg.num,
+ curr_record->u.reg.val);
+ memcpy (curr_record->u.reg.val, reg, MAX_REGISTER_SIZE);
}
- else if (record_list->type == record_mem)
+ else if (curr_record->type == record_mem)
{
/* mem */
- gdb_byte *mem = alloca (record_list->u.mem.len);
+ gdb_byte *mem = alloca (curr_record->u.mem.len);
if (record_debug > 1)
{
fprintf_unfiltered (gdb_stdlog,
"Process record: record_mem 0x%s to inferior addr = 0x%s len = %d.\n",
- paddr_nz ((CORE_ADDR)record_list),
- paddr_nz (record_list->u.mem.addr),
- record_list->u.mem.len);
+ paddr_nz ((CORE_ADDR)curr_record),
+ paddr_nz (curr_record->u.mem.addr),
+ curr_record->u.mem.len);
}
if (target_read_memory
- (record_list->u.mem.addr, mem, record_list->u.mem.len))
+ (curr_record->u.mem.addr, mem, curr_record->u.mem.len))
{
error (_("Process record: read memory addr = 0x%s len = %d error."),
- paddr_nz (record_list->u.mem.addr),
- record_list->u.mem.len);
+ paddr_nz (curr_record->u.mem.addr),
+ curr_record->u.mem.len);
}
if (target_write_memory
- (record_list->u.mem.addr, record_list->u.mem.val,
- record_list->u.mem.len))
+ (curr_record->u.mem.addr, curr_record->u.mem.val,
+ curr_record->u.mem.len))
{
error (_
("Process record: write memory addr = 0x%s len = %d error."),
- paddr_nz (record_list->u.mem.addr),
- record_list->u.mem.len);
+ paddr_nz (curr_record->u.mem.addr),
+ curr_record->u.mem.len);
}
- memcpy (record_list->u.mem.val, mem, record_list->u.mem.len);
+ memcpy (curr_record->u.mem.val, mem, curr_record->u.mem.len);
}
else
{
@@ -596,13 +635,13 @@ record_wait (ptid_t ptid, struct target_
{
fprintf_unfiltered (gdb_stdlog,
"Process record: record_end 0x%s to inferior need_dasm = %d.\n",
- paddr_nz ((CORE_ADDR)record_list),
- record_list->u.need_dasm);
+ paddr_nz ((CORE_ADDR)curr_record),
+ curr_record->u.need_dasm);
}
if (execution_direction == EXEC_FORWARD)
{
- need_dasm = record_list->u.need_dasm;
+ need_dasm = curr_record->u.need_dasm;
}
if (need_dasm)
{
@@ -631,45 +670,48 @@ record_wait (ptid_t ptid, struct target_
continue_flag = 0;
}
- /* check breakpoint */
- tmp_pc = read_pc ();
- for (bl = bp_location_chain; bl; bl = bl->global_next)
+ if (execution_direction == EXEC_REVERSE)
{
- b = bl->owner;
- gdb_assert (b);
- if (b->enable_state != bp_enabled
- && b->enable_state != bp_permanent)
- continue;
-
- if (b->type == bp_watchpoint || b->type == bp_catch_fork
- || b->type == bp_catch_vfork
- || b->type == bp_catch_exec
- || b->type == bp_hardware_watchpoint
- || b->type == bp_read_watchpoint
- || b->type == bp_access_watchpoint)
- {
- continue;
- }
- if (bl->address == tmp_pc)
+ /* check breakpoint */
+ tmp_pc = read_pc ();
+ for (bl = bp_location_chain; bl; bl = bl->global_next)
{
- if (record_debug)
+ b = bl->owner;
+ gdb_assert (b);
+ if (b->enable_state != bp_enabled
+ && b->enable_state != bp_permanent)
+ continue;
+
+ if (b->type == bp_watchpoint || b->type == bp_catch_fork
+ || b->type == bp_catch_vfork
+ || b->type == bp_catch_exec
+ || b->type == bp_hardware_watchpoint
+ || b->type == bp_read_watchpoint
+ || b->type == bp_access_watchpoint)
+ {
+ continue;
+ }
+ if (bl->address == tmp_pc)
{
- fprintf_unfiltered (gdb_stdlog,
- "Process record: break at 0x%s.\n",
- paddr_nz (tmp_pc));
+ if (record_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Process record: break at 0x%s.\n",
+ paddr_nz (tmp_pc));
+ }
+ continue_flag = 0;
+ break;
}
- continue_flag = 0;
- break;
}
}
}
if (execution_direction == EXEC_REVERSE)
{
- need_dasm = record_list->u.need_dasm;
+ need_dasm = curr_record->u.need_dasm;
}
}
-next:
+#if 0
if (continue_flag)
{
if (execution_direction == EXEC_REVERSE)
@@ -683,6 +725,7 @@ next:
record_list = record_list->next;
}
}
+#endif
}
while (continue_flag);
next prev parent reply other threads:[~2008-10-20 12:10 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-18 1:11 Pedro Alves
2008-10-18 1:26 ` Michael Snyder
2008-10-18 3:09 ` Pedro Alves
2008-10-18 3:18 ` teawater
2008-10-18 8:42 ` Andreas Schwab
2008-10-19 14:28 ` teawater
2008-10-19 20:10 ` Daniel Jacobowitz
2008-10-18 3:07 ` teawater
2008-10-18 3:26 ` Pedro Alves
2008-10-19 22:44 ` Michael Snyder
2008-10-20 0:10 ` Pedro Alves
2008-10-20 0:44 ` Michael Snyder
2008-10-20 1:46 ` Daniel Jacobowitz
2008-10-20 12:10 ` Pedro Alves [this message]
2008-10-20 15:50 ` teawater
2008-10-20 17:44 ` Pedro Alves
2008-10-20 17:51 ` Michael Snyder
2008-10-20 23:36 ` teawater
2008-10-21 0:21 ` Pedro Alves
2008-10-21 0:56 ` teawater
2008-10-21 3:13 ` teawater
2008-10-21 6:52 ` teawater
2008-10-21 6:52 ` teawater
2008-10-23 23:28 ` Michael Snyder
2008-10-21 7:04 ` teawater
2008-10-21 18:36 ` Michael Snyder
2008-10-22 0:39 ` teawater
2008-10-23 23:32 ` Michael Snyder
2008-10-23 23:46 ` Pedro Alves
2008-10-23 23:55 ` Pedro Alves
2008-10-24 0:45 ` Michael Snyder
2008-10-24 0:43 ` Michael Snyder
2008-10-24 1:51 ` Pedro Alves
2008-10-24 8:11 ` teawater
2008-10-24 9:58 ` teawater
2008-10-25 7:08 ` teawater
2008-10-28 3:21 ` teawater
2008-10-29 1:24 ` Michael Snyder
2008-10-30 3:01 ` teawater
2008-10-30 12:21 ` Pedro Alves
2008-10-30 22:06 ` Michael Snyder
2008-10-30 21:44 ` Pedro Alves
2008-10-30 21:29 ` Michael Snyder
2008-10-31 13:04 ` teawater
2008-10-31 0:25 ` teawater
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=200810201309.35333.pedro@codesourcery.com \
--to=pedro@codesourcery.com \
--cc=gdb-patches@sourceware.org \
--cc=msnyder@vmware.com \
--cc=teawater@gmail.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