This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] Reverse debugging, part 1/3: target interface


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;
  }
  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]