[RFA] Reverse debugging, part 1/3: target interface
Michael Snyder
msnyder@redhat.com
Mon Apr 17 23:37:00 GMT 2006
Two week ping... there having been no objections to this patch,
shall I check it in?
Michael Snyder wrote:
> OK, folks, ready to submit this for real.
>
> As a preface, there *is* an open-source target that will
> support reverse execution, and will work with this patch.
> A patch to the SID simulator exists in-house, and will
> hopefully be ready for public submission "real soon now".
>
> Although the gdb patch is not huge, I've decided to split
> it into three parts, both for simplicity of review, and to
> emphasize that the three parts are pretty orthogonal.
> They are:
>
> 1) Target interface, including a working instance (remote)
> 2) Internals (the "handle_inferior_event" interface), and
> 3) User interface.
>
> This patch, #1, can be applied independantly of the other two,
> and passes test suites (no new failures). This patch is also
> fully compatible with the simics target.
>
> Numbers 2 and 3 depend on #1, but not on each other.
>
> In particular, if somebody really hates the UI, it can
> be tossed out and completely replaced without affecting
> the other two patches in any way.
>
> Eli, I've included the docs patch with the user interface.
>
>
> ------------------------------------------------------------------------
>
> 2006-03-31 Michael Snyder <msnyder@redhat.com>
>
> Target interface for reverse execution.
> * target.h (enum target_waitkind):
> Add new wait event, TARGET_WAITKIND_NO_HISTORY.
> (enum exec_direction_kind): New enum.
> (struct target_ops): New methods to_set_execdir, to_get_execdir.
> (target_set_execution_direction): New macro.
> (target_get_execution_direction): New macro.
> * target.c (update_current_target): Inherit new execdir methods.
>
> * remote.c (remote_get_execdir, remote_set_execdir): New methods.
> (_initialize_remote): Add new methods to remote target vector.
> (remote_resume): Check for reverse exec direction, and send
> appropriate command to target.
> (remote_wait): Check target response for NO_HISTORY status.
>
> Index: target.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/target.c,v
> retrieving revision 1.117
> diff -p -r1.117 target.c
> *** target.c 17 Mar 2006 00:30:34 -0000 1.117
> --- target.c 31 Mar 2006 21:46:54 -0000
> *************** update_current_target (void)
> *** 457,462 ****
> --- 457,464 ----
> INHERIT (to_find_memory_regions, t);
> INHERIT (to_make_corefile_notes, t);
> INHERIT (to_get_thread_local_address, t);
> + INHERIT (to_get_execdir, t);
> + INHERIT (to_set_execdir, t);
> INHERIT (to_magic, t);
> }
> #undef INHERIT
> Index: target.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/target.h,v
> retrieving revision 1.81
> diff -p -r1.81 target.h
> *** target.h 21 Feb 2006 18:22:26 -0000 1.81
> --- target.h 31 Mar 2006 21:46:55 -0000
> *************** enum target_waitkind
> *** 129,135 ****
> inferior, rather than being stuck in the remote_async_wait()
> function. This way the event loop is responsive to other events,
> like for instance the user typing. */
> ! TARGET_WAITKIND_IGNORE
> };
>
> struct target_waitstatus
> --- 129,139 ----
> inferior, rather than being stuck in the remote_async_wait()
> function. This way the event loop is responsive to other events,
> like for instance the user typing. */
> ! TARGET_WAITKIND_IGNORE,
> !
> ! /* The target has run out of history information,
> ! and cannot run backward any further. */
> ! TARGET_WAITKIND_NO_HISTORY
> };
>
> struct target_waitstatus
> *************** struct target_waitstatus
> *** 148,153 ****
> --- 152,165 ----
> value;
> };
>
> + /* Reverse execution. */
> + enum exec_direction_kind
> + {
> + EXEC_FORWARD,
> + EXEC_REVERSE,
> + EXEC_ERROR
> + };
> +
> /* Possible types of events that the inferior handler will have to
> deal with. */
> enum inferior_event_type
> *************** struct target_ops
> *** 423,428 ****
> --- 435,445 ----
> gdb_byte *readbuf, const gdb_byte *writebuf,
> ULONGEST offset, LONGEST len);
>
> + /* Set execution direction (forward/reverse). */
> + int (*to_set_execdir) (enum exec_direction_kind);
> + /* Get execution direction (forward/reverse). */
> + enum exec_direction_kind (*to_get_execdir) (void);
> +
> int to_magic;
> /* Need sub-structure for target machine related rather than comm related?
> */
> *************** extern int target_stopped_data_address_p
> *** 1074,1079 ****
> --- 1091,1108 ----
> #define target_stopped_data_address_p(CURRENT_TARGET) (1)
> #endif
>
> + /* Forward/reverse execution direction.
> + These will only be implemented by a target that supports reverse execution.
> + */
> + #define target_get_execution_direction() \
> + (current_target.to_get_execdir ? \
> + (*current_target.to_get_execdir) () : EXEC_ERROR)
> +
> + #define target_set_execution_direction(DIR) \
> + (current_target.to_set_execdir ? \
> + (*current_target.to_set_execdir) (DIR) : EXEC_ERROR)
> +
> +
> /* This will only be defined by a target that supports catching vfork events,
> such as HP-UX.
>
> Index: remote.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/remote.c,v
> retrieving revision 1.205
> diff -p -r1.205 remote.c
> *** remote.c 30 Mar 2006 16:56:30 -0000 1.205
> --- remote.c 31 Mar 2006 21:46:58 -0000
> *************** remote_resume (ptid_t ptid, int step, en
> *** 2423,2429 ****
> else
> set_thread (pid, 0); /* Run this thread. */
>
> ! if (siggnal != TARGET_SIGNAL_0)
> {
> buf[0] = step ? 'S' : 'C';
> buf[1] = tohex (((int) siggnal >> 4) & 0xf);
> --- 2423,2437 ----
> else
> set_thread (pid, 0); /* Run this thread. */
>
> ! if (target_get_execution_direction () == EXEC_REVERSE)
> ! {
> ! /* We don't pass signals to the target in reverse exec mode. */
> ! if (info_verbose && siggnal != TARGET_SIGNAL_0)
> ! warning (" - Can't pass signal %d to target in reverse: ignored.\n",
> ! siggnal);
> ! strcpy (buf, step ? "bs" : "bc");
> ! }
> ! else if (siggnal != TARGET_SIGNAL_0)
> {
> buf[0] = step ? 'S' : 'C';
> buf[1] = tohex (((int) siggnal >> 4) & 0xf);
> *************** remote_wait (ptid_t ptid, struct target_
> *** 2697,2702 ****
> --- 2705,2715 ----
> switch (buf[0])
> {
> case 'E': /* Error of some sort. */
> + if (buf[1] == '0' && buf[2] == '6')
> + {
> + status->kind = TARGET_WAITKIND_NO_HISTORY;
> + goto got_status;
> + }
> warning (_("Remote failure reply: %s"), buf);
> continue;
> case 'F': /* File-I/O request. */
> *************** remote_get_thread_local_address (ptid_t
> *** 5229,5234 ****
> --- 5242,5276 ----
> return 0;
> }
>
> + /* Reverse execution.
> + FIXME: set up as a capability. */
> + static enum exec_direction_kind remote_execdir = EXEC_FORWARD;
> +
> + static enum exec_direction_kind remote_get_execdir (void)
> + {
> + if (remote_debug && info_verbose)
> + printf_filtered ("remote execdir is %s\n",
> + remote_execdir == EXEC_FORWARD ? "forward" :
> + remote_execdir == EXEC_REVERSE ? "reverse" :
> + "unknown");
> + return remote_execdir;
> + }
> +
> + static int remote_set_execdir (enum exec_direction_kind dir)
> + {
> + if (remote_debug && info_verbose)
> + printf_filtered ("Set remote execdir: %s\n",
> + dir == EXEC_FORWARD ? "forward" :
> + dir == EXEC_REVERSE ? "reverse" :
> + "bad direction");
> +
> + /* FIXME: check target for capability. */
> + if (dir == EXEC_FORWARD || dir == EXEC_REVERSE)
> + return (remote_execdir = dir);
> + else
> + return EXEC_ERROR;
> + }
> +
> static void
> init_remote_ops (void)
> {
> *************** Specify the serial device it is connecte
> *** 5276,5281 ****
> --- 5318,5325 ----
> remote_ops.to_has_registers = 1;
> remote_ops.to_has_execution = 1;
> remote_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
> + remote_ops.to_get_execdir = remote_get_execdir;
> + remote_ops.to_set_execdir = remote_set_execdir;
> remote_ops.to_magic = OPS_MAGIC;
> }
>
More information about the Gdb-patches
mailing list