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 rev. 2


A revised patch, implementing earlier suggestions.
Still haven't added a probe, but I thought I'd seek comments anyway.

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.c (target_get_execdir): New generic method.
	(target_set_execdir): Ditto.
	* remote.c (remote_get_execdir, remote_set_execdir): New methods.
	(remote_vcont_resume): Jump out if attempting reverse execution.
	(remote_resume): Check for reverse exec direction, and send
	appropriate command to target.
	(remote_wait): Check target response for NO_HISTORY status.
	Also check for empty reply (target doesn't understand "bs" or "bc).
	(_initialize_remote): Add new methods to remote target vector.

Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.82
diff -p -r1.82 target.h
*** target.h	18 Apr 2006 19:20:06 -0000	1.82
--- target.h	29 Apr 2006 00:52:37 -0000
*************** enum target_waitkind
*** 130,136 ****
         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
--- 130,140 ----
         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
*** 149,154 ****
--- 153,166 ----
      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
*** 424,429 ****
--- 436,446 ----
  				gdb_byte *readbuf, const gdb_byte *writebuf,
  				ULONGEST offset, LONGEST len);
  
+     /* Set execution direction (forward/reverse).  */
+     enum exec_direction_kind (*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
*** 1070,1075 ****
--- 1087,1098 ----
  #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.  */
+ 
+ extern enum exec_direction_kind target_get_execdir (void);
+ extern enum exec_direction_kind target_set_execdir (enum exec_direction_kind);
+ 
  /* This will only be defined by a target that supports catching vfork events,
     such as HP-UX.
  
Index: target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.118
diff -p -r1.118 target.c
*** target.c	18 Apr 2006 19:20:06 -0000	1.118
--- target.c	29 Apr 2006 00:52:37 -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);
+       /* Do not inherit to_get_execdir.  */
+       /* Do not inherit to_set_execdir.  */
        INHERIT (to_magic, t);
      }
  #undef INHERIT
*************** target_async_mask (int mask)
*** 1502,1507 ****
--- 1504,1564 ----
  }
  
  /* Look through the list of possible targets for a target that can
+    support reverse execution.  */
+ 
+ enum exec_direction_kind
+ target_get_execdir (void)
+ {
+   struct target_ops *t;
+ 
+   for (t = current_target.beneath; t != NULL; t = t->beneath)
+     {
+       if (t->to_get_execdir != NULL)
+ 	{
+ 	  enum exec_direction_kind retval = t->to_get_execdir ();
+ 	  if (targetdebug)
+ 	    fprintf_unfiltered (gdb_stdlog, "%s->to_get_execdir () = %s\n",
+ 				t->to_shortname, 
+ 				retval == EXEC_FORWARD ? "Forward" :
+ 				retval == EXEC_REVERSE ? "Reverse" :
+ 				retval == EXEC_ERROR   ? "Error"   :
+ 				"*unknown*");
+ 	  return retval;
+ 	}
+     }
+ 
+   if (targetdebug)
+     fprintf_unfiltered (gdb_stdlog, "target_get_execdir: unsupported\n");
+   return EXEC_ERROR;
+ }
+ 
+ enum exec_direction_kind
+ target_set_execdir (enum exec_direction_kind setdir)
+ {
+   struct target_ops *t;
+ 
+   for (t = current_target.beneath; t != NULL; t = t->beneath)
+     {
+       if (t->to_set_execdir != NULL)
+ 	{
+ 	  enum exec_direction_kind retval = t->to_set_execdir (setdir);
+ 	  if (targetdebug)
+ 	    fprintf_unfiltered (gdb_stdlog, "%s->to_set_execdir () = %s\n",
+ 				t->to_shortname, 
+ 				retval == EXEC_FORWARD ? "Forward" :
+ 				retval == EXEC_REVERSE ? "Reverse" :
+ 				retval == EXEC_ERROR   ? "Error"   :
+ 				"*unknown*");
+ 	  return retval;
+ 	}
+     }
+ 
+   if (targetdebug)
+     fprintf_unfiltered (gdb_stdlog, "target_set_execdir: unsupported\n");
+   return EXEC_ERROR;
+ }
+ 
+ /* Look through the list of possible targets for a target that can
     follow forks.  */
  
  int
Index: remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.209
diff -p -r1.209 remote.c
*** remote.c	26 Apr 2006 18:45:32 -0000	1.209
--- remote.c	29 Apr 2006 00:52:38 -0000
*************** remote_vcont_resume (ptid_t ptid, int st
*** 2327,2332 ****
--- 2327,2336 ----
    char *buf = NULL, *outbuf;
    struct cleanup *old_cleanup;
  
+   /* vCont does not currently support reverse execution.  */
+   if (target_get_execdir () == EXEC_REVERSE)
+     return 0;
+ 
    if (remote_protocol_packets[PACKET_vCont].support == PACKET_SUPPORT_UNKNOWN)
      remote_vcont_probe (rs);
  
*************** remote_resume (ptid_t ptid, int step, en
*** 2419,2425 ****
    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_execdir () == 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_
*** 2693,2698 ****
--- 2705,2716 ----
        switch (buf[0])
  	{
  	case 'E':		/* Error of some sort.  */
+ 	  if (buf[1] == '0' && buf[2] == '6' 
+ 	      && target_get_execdir == EXEC_REVERSE)
+ 	    {
+ 	      status->kind = TARGET_WAITKIND_NO_HISTORY;
+ 	      goto got_status;
+ 	    }
  	  warning (_("Remote failure reply: %s"), buf);
  	  continue;
  	case 'F':		/* File-I/O request.  */
*************** Packet: '%s'\n"),
*** 2823,2832 ****
  	  remote_console_output (buf + 1);
  	  continue;
  	case '\0':
  	  if (last_sent_signal != TARGET_SIGNAL_0)
  	    {
- 	      /* Zero length reply means that we tried 'S' or 'C' and
- 	         the remote system doesn't support it.  */
  	      target_terminal_ours_for_output ();
  	      printf_filtered
  		("Can't send signals to this remote system.  %s not sent.\n",
--- 2841,2850 ----
  	  remote_console_output (buf + 1);
  	  continue;
  	case '\0':
+ 	  /* Zero length reply may mean that we tried 'S' or 'C' and
+ 	     the remote system doesn't support it.  */
  	  if (last_sent_signal != TARGET_SIGNAL_0)
  	    {
  	      target_terminal_ours_for_output ();
  	      printf_filtered
  		("Can't send signals to this remote system.  %s not sent.\n",
*************** Packet: '%s'\n"),
*** 2838,2847 ****
  	      putpkt ((char *) buf);
  	      continue;
  	    }
  	  /* else fallthrough */
  	default:
! 	  warning (_("Invalid remote reply: %s"), buf);
! 	  continue;
  	}
      }
  got_status:
--- 2856,2871 ----
  	      putpkt ((char *) buf);
  	      continue;
  	    }
+ 	  /* Or, it may mean that we tried "bs" or "bc" and
+ 	     the remote system doesn't support that.  */
+ 	  else if (target_get_execdir () == EXEC_REVERSE)
+ 	    {
+ 	      error (_("Target does not support reverse execution."));
+ 	    }
  	  /* else fallthrough */
  	default:
! 	  error (_("Invalid remote reply: %s"), buf);
! 	  break;	/* Lint.  */
  	}
      }
  got_status:
*************** remote_get_thread_local_address (ptid_t 
*** 5218,5223 ****
--- 5242,5281 ----
    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 enum exec_direction_kind 
+ 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)
+     {
+       remote_execdir = dir;
+       return dir;
+     }
+   else
+     return EXEC_ERROR;
+ }
+ 
  static void
  init_remote_ops (void)
  {
*************** Specify the serial device it is connecte
*** 5265,5270 ****
--- 5323,5330 ----
    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]