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]

Extending RSP with vCont;n and vCont;f


Hallo,

we would like to improve the RSP command "vCont" for remote debugging. It seems that the range option has been introduced recently to get rid of time consuming, successive single-steps. Our intention is to get rid of further, unnecessary RSP packages being sent as our target is capable to do a step-over (called next by GDB) and a step-return (called finish by GDB). Therefore we propose to extend the vCont command with "vCont;n" and "vCont;f" as well.

You will find the necessary patch below. It has been tested on MinGW with a x86-Target. It's based on the todays trunk.

Thanks in advance. 
Robert Ilg

diff --git a/gdb/remote.c b/gdb/remote.c
index a9ef297..df31c3a 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -256,11 +256,19 @@

   /* vCont;r */
   int r;
+
+  /* vCont;f */
+  int f;
+
+  /* vCont;n */
+  int n;
};

 /* Controls whether GDB is willing to use range stepping.  */

 static int use_range_stepping = 1;
+static int use_finish_stepping = 1;
+static int use_next_stepping = 1;

 #define OPAQUETHREADBYTES 8

@@ -4704,6 +4712,8 @@
       support_C = 0;
       rs->supports_vCont.t = 0;
       rs->supports_vCont.r = 0;
+      rs->supports_vCont.n = 0;
+      rs->supports_vCont.f = 0;
       while (p && *p == ';')
    {
      p++;
@@ -4719,6 +4729,10 @@
        rs->supports_vCont.t = 1;
      else if (*p == 'r' && (*(p + 1) == ';' || *(p + 1) == 0))
        rs->supports_vCont.r = 1;
+      else if (*p == 'f' && (*(p + 1) == ';' || *(p + 1) == 0))
+        rs->supports_vCont.f = 1;
+      else if (*p == 'n' && (*(p + 1) == ';' || *(p + 1) == 0))
+        rs->supports_vCont.n = 1;

       p = strchr (p, ';');
    }
@@ -4747,9 +4761,29 @@
            ptid_t ptid, int step, enum gdb_signal siggnal)
{
   struct remote_state *rs = get_remote_state ();
+  struct thread_info *tp;
+
+  if (ptid_equal (ptid, minus_one_ptid))
+  {
+    /* If we don't know about the target thread's tid, then
+     * we're resuming magic_null_ptid (see caller).  */
+    tp = find_thread_ptid (magic_null_ptid);
+   }
+   else
+     tp = find_thread_ptid (ptid);

+   gdb_assert (tp != NULL);
+
   if (step && siggnal != GDB_SIGNAL_0)
     p += xsnprintf (p, endp - p, ";S%02x", siggnal);
+  else if (
+       /* GDB is willing to step next and target supports it */
+       use_next_stepping && rs->supports_vCont.n &&
+       /* step next is suitable for this resumption */
+       step && (tp->control.step_over_calls == STEP_OVER_ALL))
+  {
+    p += xsnprintf (p, endp - p, ";n");
+  }
   else if (step
       /* GDB is willing to range step.  */
       && use_range_stepping
@@ -4761,18 +4795,6 @@
          it).  */
       && !(remote_multi_process_p (rs) && ptid_is_pid (ptid)))
     {
-      struct thread_info *tp;
-
-      if (ptid_equal (ptid, minus_one_ptid))
-    {
-      /* If we don't know about the target thread's tid, then
-         we're resuming magic_null_ptid (see caller).  */
-      tp = find_thread_ptid (magic_null_ptid);
-    }
-      else
-    tp = find_thread_ptid (ptid);
-      gdb_assert (tp != NULL);
-
       if (tp->control.may_range_step)
    {
      int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
@@ -4790,6 +4812,14 @@
     p += xsnprintf (p, endp - p, ";s");
   else if (siggnal != GDB_SIGNAL_0)
     p += xsnprintf (p, endp - p, ";C%02x", siggnal);
+  else if (
+       /* GDB is willing to step next and target supports it */
+       use_finish_stepping && rs->supports_vCont.f &&
+       /* step finish is suitable for this resumption */
+       (tp->control.proceed_to_finish == 1))
+  {
+    p += xsnprintf (p, endp - p, ";f");
+  }
   else
     p += xsnprintf (p, endp - p, ";c");

@@ -11760,6 +11790,82 @@
     }
}

+/* The "set/show next-stepping" show hook.  */
+
+static void
+show_next_stepping (struct ui_file *file, int from_tty,
+             struct cmd_list_element *c,
+             const char *value)
+{
+  fprintf_filtered (file,
+            _("Debugger's willingness to use next stepping "
+              "is %s.\n"), value);
+}
+
+/* The "set/show next-stepping" set hook.  */
+
+static void
+set_next_stepping (char *ignore_args, int from_tty,
+            struct cmd_list_element *c)
+{
+  /* When enabling, check whether next stepping is actually
+     supported by the target, and warn if not.  */
+  if (use_next_stepping)
+    {
+      if (remote_desc != NULL)
+    {
+      struct remote_state *rs = get_remote_state ();
+
+      if (remote_protocol_packets[PACKET_vCont].support == PACKET_SUPPORT_UNKNOWN)
+        remote_vcont_probe (rs);
+
+      if (remote_protocol_packets[PACKET_vCont].support == PACKET_ENABLE
+          && rs->supports_vCont.n)
+        return;
+    }
+
+      warning (_("Next stepping is not supported by the current target"));
+    }
+}
+
+/* The "set/show finish-stepping" show hook.  */
+
+static void
+show_finish_stepping (struct ui_file *file, int from_tty,
+             struct cmd_list_element *c,
+             const char *value)
+{
+  fprintf_filtered (file,
+            _("Debugger's willingness to use finish stepping "
+              "is %s.\n"), value);
+}
+
+/* The "set/show finish-stepping" set hook.  */
+
+static void
+set_finish_stepping (char *ignore_args, int from_tty,
+            struct cmd_list_element *c)
+{
+  /* When enabling, check whether finish stepping is actually
+     supported by the target, and warn if not.  */
+  if (use_finish_stepping)
+    {
+      if (remote_desc != NULL)
+    {
+      struct remote_state *rs = get_remote_state ();
+
+      if (remote_protocol_packets[PACKET_vCont].support == PACKET_SUPPORT_UNKNOWN)
+        remote_vcont_probe (rs);
+
+      if (remote_protocol_packets[PACKET_vCont].support == PACKET_ENABLE
+          && rs->supports_vCont.f)
+        return;
+    }
+
+      warning (_("Finish stepping is not supported by the current target"));
+    }
+}
+
void
_initialize_remote (void)
{
@@ -12168,6 +12274,34 @@
                  &setlist,
                  &showlist);

+  add_setshow_boolean_cmd ("next-stepping", class_run,
+                 &use_next_stepping, _("\
+  Enable or disable next stepping."), _("\
+  Show whether target-assisted next stepping is enabled."), _("\
+  If on, and the target supports it, when skipping over a source line, GDB\n\
+  tells the target to skip the next instruction itself instead of\n\
+  of issuing multiple single-steps.  This speeds up source level\n\
+  stepping.  If off, GDB always issues slower stepping mechanisms\n\
+  instead, even if next stepping is supported by the target.  The default is on."),
+                 set_next_stepping,
+                 show_next_stepping,
+                 &setlist,
+                 &showlist);
+
+  add_setshow_boolean_cmd ("finish-stepping", class_run,
+                 &use_finish_stepping, _("\
+  Enable or disable finish stepping."), _("\
+  Show whether target-assisted finish stepping is enabled."), _("\
+  If on, and the target supports it, when stepping out of a function, GDB\n\
+  tells the target to step out of the corresponding stack frame itself.\n\
+  This speeds up source level stepping. If off, GDB issues slower\n\
+  stepping mechanisms instead, even if finish\n\
+  stepping is supported by the target.  The default is on."),
+                 set_finish_stepping,
+                 show_finish_stepping,
+                 &setlist,
+                 &showlist);
+
   /* Eventually initialize fileio.  See fileio.c */
  initialize_remote_fileio (remote_set_cmdlist, remote_show_cmdlist);




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