[patch][python] Add breakpoint support.

Pedro Alves pedro@codesourcery.com
Thu Apr 8 23:40:00 GMT 2010


On Friday 09 April 2010 00:25:47, Joel Brobecker wrote:
> > I'd just like to point out that we already have code in the tree (and
> > for a decade) that dumps tracepoints into a file; the file can be
> > sourced as a cli script afterwards.  See breakpoint.c:tracepoint_save_command.
> > Since the tracepoint/breakpoints merge, it is trivial to extend that function
> > to dump breakpoints as well.
> 
> I almost did implement things that way, and it's certainly better
> than nothing. Maybe I'm letting best be the enemy of good, but there
> are issues with a pure CLI script approach that a user cannot control.
> For instance, what if one of the breakpoints now fails? A CLI script
> would abort early, leaving some of the breakpoints not restored.
> If some of the breakpoints were in DSOs that only get loaded at runtime,
> should they be created as pending? I can't remember what the default
> is when from_tty is not set...  I like the python approach because it
> allows us to provide a more configurable approach than a pure CLI script
> would give us.

Yeah... being a fundamental and frequently asked for feature,
that python bit would ideally be a part of gdb itself, meaning,
we should consider where to put/install python commands that gdb
always auto-loads, etc.

in any case, here's a 10 minute (functinal, but incomplete,
catchpoints not dumped completely) patch, FTR.

-- 
Pedro Alves

---
 gdb/breakpoint.c |  132 ++++++++++++++++++++++++++++++++++++++++++++++---------
 gdb/breakpoint.h |    4 +
 2 files changed, 115 insertions(+), 21 deletions(-)

Index: src/gdb/breakpoint.c
===================================================================
--- src.orig/gdb/breakpoint.c	2010-04-08 23:27:37.000000000 +0100
+++ src/gdb/breakpoint.c	2010-04-09 00:26:01.000000000 +0100
@@ -5838,6 +5838,12 @@ print_mention_catch_fork (struct breakpo
   printf_filtered (_("Catchpoint %d (fork)"), b->number);
 }
 
+static void
+print_create_catch_fork (struct breakpoint *b, struct ui_file *fp)
+{
+  fprintf_unfiltered (fp, "catch fork");
+}
+
 /* The breakpoint_ops structure to be used in fork catchpoints.  */
 
 static struct breakpoint_ops catch_fork_breakpoint_ops =
@@ -5847,7 +5853,8 @@ static struct breakpoint_ops catch_fork_
   breakpoint_hit_catch_fork,
   print_it_catch_fork,
   print_one_catch_fork,
-  print_mention_catch_fork
+  print_mention_catch_fork,
+  print_create_catch_fork
 };
 
 /* Implement the "insert" breakpoint_ops method for vfork catchpoints.  */
@@ -5919,6 +5926,12 @@ print_mention_catch_vfork (struct breakp
   printf_filtered (_("Catchpoint %d (vfork)"), b->number);
 }
 
+static void
+print_create_catch_vfork (struct breakpoint *b, struct ui_file *fp)
+{
+  fprintf_unfiltered (fp, "catch vfork");
+}
+
 /* The breakpoint_ops structure to be used in vfork catchpoints.  */
 
 static struct breakpoint_ops catch_vfork_breakpoint_ops =
@@ -5928,7 +5941,8 @@ static struct breakpoint_ops catch_vfork
   breakpoint_hit_catch_vfork,
   print_it_catch_vfork,
   print_one_catch_vfork,
-  print_mention_catch_vfork
+  print_mention_catch_vfork,
+  print_create_catch_vfork
 };
 
 /* Implement the "insert" breakpoint_ops method for syscall
@@ -6167,6 +6181,12 @@ print_mention_catch_syscall (struct brea
                      b->number);
 }
 
+static void
+print_create_catch_syscall (struct breakpoint *b, struct ui_file *fp)
+{
+  fprintf_unfiltered (fp, "catch vfork");
+}
+
 /* The breakpoint_ops structure to be used in syscall catchpoints.  */
 
 static struct breakpoint_ops catch_syscall_breakpoint_ops =
@@ -6176,7 +6196,8 @@ static struct breakpoint_ops catch_sysca
   breakpoint_hit_catch_syscall,
   print_it_catch_syscall,
   print_one_catch_syscall,
-  print_mention_catch_syscall
+  print_mention_catch_syscall,
+  print_create_catch_syscall
 };
 
 /* Returns non-zero if 'b' is a syscall catchpoint.  */
@@ -10644,30 +10665,43 @@ get_tracepoint_by_number (char **arg, in
   return NULL;
 }
 
-/* save-tracepoints command */
+/* The save-breakpoints command.  */
+
 static void
-tracepoint_save_command (char *args, int from_tty)
+breakpoint_save (char *args, int from_tty,
+		 int (*filter) (const struct breakpoint *))
 {
-  struct breakpoint *tp;
-  int any_tp = 0;
-  struct command_line *line;
+  struct breakpoint *bp;
+  int any = 0;
   char *pathname;
   char tmp[40];
   struct cleanup *cleanup;
   struct ui_file *fp;
+  int extra_trace_bits = 0;
 
   if (args == 0 || *args == 0)
-    error (_("Argument required (file name in which to save tracepoints)"));
+    error (_("Argument required (file name in which to save breakpoints)"));
 
   /* See if we have anything to save.  */
-  ALL_TRACEPOINTS (tp)
+  ALL_BREAKPOINTS (tp)
   {
-    any_tp = 1;
+    if (tp->number <= 0)
+      continue;
+
+    /* If we have a filter, only list the breakpoints it accepts.  */
+    if (filter && !filter (tp))
+      continue;
+
+    if (is_tracepoint (tp))
+      extra_trace_bits = 1;
+
+    any = 1;
     break;
   }
-  if (!any_tp)
+
+  if (!any)
     {
-      warning (_("save-tracepoints: no tracepoints to save."));
+      warning (_("No breakpoints to save."));
       return;
     }
 
@@ -10675,18 +10709,53 @@ tracepoint_save_command (char *args, int
   cleanup = make_cleanup (xfree, pathname);
   fp = gdb_fopen (pathname, "w");
   if (!fp)
-    error (_("Unable to open file '%s' for saving tracepoints (%s)"),
+    error (_("Unable to open file '%s' for saving breakpoints (%s)"),
 	   args, safe_strerror (errno));
   make_cleanup_ui_file_delete (fp);
 
-  save_trace_state_variables (fp);
+  if (extra_trace_bits)
+    save_trace_state_variables (fp);
 
-  ALL_TRACEPOINTS (tp)
+  ALL_BREAKPOINTS (tp)
   {
+    /* Skip internal and momentary breakpoints.  */
+    if (tp->number <= 0)
+      continue;
+
+    /* If we have a filter, only list the breakpoints it accepts.  */
+    if (filter && !filter (tp))
+      continue;
+
     if (tp->type == bp_fast_tracepoint)
       fprintf_unfiltered (fp, "ftrace");
-    else
+    else if (tp->type == bp_tracepoint)
       fprintf_unfiltered (fp, "trace");
+    if (tp->type == bp_breakpoint && tp->disposition == disp_del)
+      fprintf_unfiltered (fp, "tbreak");
+    else if (tp->type == bp_breakpoint)
+      fprintf_unfiltered (fp, "break");
+    else if (tp->type == bp_hardware_breakpoint && tp->disposition == disp_del)
+      fprintf_unfiltered (fp, "thbreak");
+    else if (tp->type == bp_hardware_breakpoint)
+      fprintf_unfiltered (fp, "hbreak");
+    else if (tp->type == bp_watchpoint)
+      fprintf_unfiltered (fp, "watch");
+    else if (tp->type == bp_hardware_watchpoint)
+      fprintf_unfiltered (fp, "watch");
+    else if (tp->type == bp_read_watchpoint)
+      fprintf_unfiltered (fp, "rwatch");
+    else if (tp->type == bp_access_watchpoint)
+      fprintf_unfiltered (fp, "awatch");
+    else if (tp->type == bp_hardware_breakpoint)
+      fprintf_unfiltered (fp, "hbreak");
+    else if (tp->type == bp_hardware_breakpoint)
+      fprintf_unfiltered (fp, "hbreak");
+    else if (tp->type == bp_catchpoint)
+      (tp->ops->print_create) (tp, fp);
+    else
+      internal_error (__FILE__, __LINE__,
+		      _("unhandled breakpoint type %d"),
+		      (int) tp->type);
 
     if (tp->addr_string)
       fprintf_unfiltered (fp, " %s", tp->addr_string);
@@ -10708,7 +10777,7 @@ tracepoint_save_command (char *args, int
       {
 	volatile struct gdb_exception ex;	
 
-	fprintf_unfiltered (fp, "  actions\n");
+	fprintf_unfiltered (fp, "  commands\n");
 	
 	ui_out_redirect (uiout, fp);
 	TRY_CATCH (ex, RETURN_MASK_ERROR)
@@ -10722,15 +10791,31 @@ tracepoint_save_command (char *args, int
 
 	fprintf_unfiltered (fp, "  end\n");
       }
+
+    if (tp->enable_state == bp_disabled)
+      fprintf_unfiltered (fp, "disable %d\n", tp->number);
   }
 
-  if (*default_collect)
+  if (extra_trace_bits && *default_collect)
     fprintf_unfiltered (fp, "set default-collect %s\n", default_collect);
 
   do_cleanups (cleanup);
   if (from_tty)
-    printf_filtered (_("Tracepoints saved to file '%s'.\n"), args);
-  return;
+    printf_filtered (_("Breakpoints saved to file '%s'.\n"), args);
+}
+
+/* save-breakpoints command */
+static void
+save_breakpoints_command (char *args, int from_tty)
+{
+  breakpoint_save (args, from_tty, NULL);
+}
+
+/* save-tracepoints command */
+static void
+tracepoint_save_command (char *args, int from_tty)
+{
+  breakpoint_save (args, from_tty, is_tracepoint);
 }
 
 /* Create a vector of all tracepoints.  */
@@ -11232,6 +11317,11 @@ Save current tracepoint definitions as a
 Use the 'source' command in another debug session to restore them."));
   set_cmd_completer (c, filename_completer);
 
+  c = add_com ("save-breakpoints", class_breakpoint, save_breakpoints_command, _("\
+Save current breakpoint definitions as a script.\n\
+Use the 'source' command in another debug session to restore them."));
+  set_cmd_completer (c, filename_completer);
+
   add_prefix_cmd ("breakpoint", class_maintenance, set_breakpoint_cmd, _("\
 Breakpoint specific settings\n\
 Configure various breakpoint-specific variables such as\n\
Index: src/gdb/breakpoint.h
===================================================================
--- src.orig/gdb/breakpoint.h	2010-04-09 00:00:42.000000000 +0100
+++ src/gdb/breakpoint.h	2010-04-09 00:07:35.000000000 +0100
@@ -362,6 +362,10 @@ struct breakpoint_ops 
   /* Display information about this breakpoint after setting it (roughly
      speaking; this is called from "mention").  */
   void (*print_mention) (struct breakpoint *);
+
+  /* Display information about this breakpoint after setting it (roughly
+     speaking; this is called from "mention").  */
+  void (*print_create) (struct breakpoint *, struct ui_file *fp);
 };
 
 enum watchpoint_triggered



More information about the Gdb-patches mailing list