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]

[v3] PR8554: New command to save breakpoints to a file


On Friday 16 April 2010 00:01:44, Pedro Alves wrote:
> On Thursday 15 April 2010 23:49:32, Michael Snyder wrote:
> > BTW. "save_command" needs to print an error or something, not
> > simply return without doing anything.  If I type "save<return>",
> > I get a silent failure.
> 
> I think the common practice is to have it print "help save".
> At least, there are over 30 calls to help_list under gdb/
> that look like that.  E.g.,
> 
> (gdb) set print
> "set print" must be followed by the name of a print subcommand.
> List of set print subcommands:
> 
> set print address -- Set printing of addresses
> ...
> 
> I'll do that.

This is now done.

I've made a small change to check for
`user_settable_breakpoint' breakpoint instead of checking
if the breakpoint number isn't `<= 0' to skip internal and
momentary breakpoints.  I had never noticed that function
before, and it seems self-documenting to use it (the `info
breakpoints' implementation uses it similarly).

I've also extended the docs a bit to mention the watchpoints
with expressions involving locals may not be recreatable, and,
mentioned that the user is free to edit the generated file, in
case it wasn't obvious.

Eli, could you please look over the documentation/NEWS/help,
etc., bits?

-- 
Pedro Alves
2010-04-18  Pedro Alves  <pedro@codesourcery.com>

	PR breakpoints/8554.

	Implement `save-breakpoints'.

	gdb/
	* breakpoint.c (save_cmdlist): New.
	(breakpoint_set_cmdlist, breakpoint_show_cmdlist): Moved up close
	to save_cmdlist.
	(print_recreate_catch_fork): New.
	(catch_fork_breakpoint_ops): Install it.
	(print_recreate_catch_vfork): New.
	(catch_vfork_breakpoint_ops): Install it.
	(print_recreate_catch_syscall): New.
	(catch_syscall_breakpoint_ops): Install it.
	(print_recreate_catch_exec): New.
	(catch_exec_breakpoint_ops): Install it.
	(print_recreate_exception_catchpoint): New.
	(gnu_v3_exception_catchpoint_ops): Install it.
	(save_breakpoints): New, based on tracepoint_save_command, but
	handle all breakpoint types.
	(save_breakpoints_command): New.
	(tracepoint_save_command): Rename to...
	(save_tracepoints_command): ... this, and reimplement using
	save_breakpoints.
	(save_command): New.
	(_initialize_breakpoints): Install the "save" command prefix.
	Install the "save breakpoints" command.  Make "save-tracepoints" a
	deprecated alias for "save tracepoints".
	* breakpoint.h (struct breakpoint_ops): New field `print_recreate'.
	* ada-lang.c (print_recreate_exception): New.
	(print_recreate_catch_exception): New.
	(catch_exception_breakpoint_ops): Install it.
	(print_recreate_catch_exception_unhandled): New.
	(catch_exception_unhandled_breakpoint_ops): Install it.
	(print_recreate_catch_assert): New.
	(catch_assert_breakpoint_ops): Install it.

	* NEWS: Mention the new `save breakpoints' command.  Mention the
	new `save tracepoints' alias and that `save-tracepoints' is now
	deprecated.

	doc/
	* gdb.texinfo (Save Breakpoints): New node.
	(save-tracepoints): Rename to ...
	(save tracepoints): ... this.  Mention that `save-tracepoints' is
	a deprecated alias to `save tracepoints'.

	gdb/testsuite/
	* gdb.trace/save-trace.exp: Adjust.

---
 gdb/NEWS                               |   10 +
 gdb/ada-lang.c                         |   56 ++++++
 gdb/breakpoint.c                       |  283 ++++++++++++++++++++++++++++-----
 gdb/breakpoint.h                       |    3 
 gdb/doc/gdb.texinfo                    |   36 +++-
 gdb/testsuite/gdb.trace/save-trace.exp |    4 
 6 files changed, 343 insertions(+), 49 deletions(-)

Index: src/gdb/breakpoint.c
===================================================================
--- src.orig/gdb/breakpoint.c	2010-04-17 23:13:46.000000000 +0100
+++ src/gdb/breakpoint.c	2010-04-18 01:24:57.000000000 +0100
@@ -416,6 +416,10 @@ static int prev_breakpoint_count;
 
 static int tracepoint_count;
 
+static struct cmd_list_element *breakpoint_set_cmdlist;
+static struct cmd_list_element *breakpoint_show_cmdlist;
+static struct cmd_list_element *save_cmdlist;
+
 /* Return whether a breakpoint is an active enabled breakpoint.  */
 static int
 breakpoint_enabled (struct breakpoint *b)
@@ -5853,6 +5857,15 @@ print_mention_catch_fork (struct breakpo
   printf_filtered (_("Catchpoint %d (fork)"), b->number);
 }
 
+/* Implement the "print_recreate" breakpoint_ops method for fork
+   catchpoints.  */
+
+static void
+print_recreate_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 =
@@ -5862,7 +5875,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_recreate_catch_fork
 };
 
 /* Implement the "insert" breakpoint_ops method for vfork catchpoints.  */
@@ -5934,6 +5948,15 @@ print_mention_catch_vfork (struct breakp
   printf_filtered (_("Catchpoint %d (vfork)"), b->number);
 }
 
+/* Implement the "print_recreate" breakpoint_ops method for vfork
+   catchpoints.  */
+
+static void
+print_recreate_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 =
@@ -5943,7 +5966,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_recreate_catch_vfork
 };
 
 /* Implement the "insert" breakpoint_ops method for syscall
@@ -6182,6 +6206,33 @@ print_mention_catch_syscall (struct brea
                      b->number);
 }
 
+/* Implement the "print_recreate" breakpoint_ops method for syscall
+   catchpoints.  */
+
+static void
+print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp)
+{
+  fprintf_unfiltered (fp, "catch syscall");
+
+  if (b->syscalls_to_be_caught)
+    {
+      int i, iter;
+
+      for (i = 0;
+           VEC_iterate (int, b->syscalls_to_be_caught, i, iter);
+           i++)
+        {
+          struct syscall s;
+
+          get_syscall_by_number (iter, &s);
+          if (s.name)
+            fprintf_unfiltered (fp, " %s", s.name);
+          else
+            fprintf_unfiltered (fp, " %d", s.number);
+        }
+    }
+}
+
 /* The breakpoint_ops structure to be used in syscall catchpoints.  */
 
 static struct breakpoint_ops catch_syscall_breakpoint_ops =
@@ -6191,7 +6242,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_recreate_catch_syscall
 };
 
 /* Returns non-zero if 'b' is a syscall catchpoint.  */
@@ -6327,6 +6379,15 @@ print_mention_catch_exec (struct breakpo
   printf_filtered (_("Catchpoint %d (exec)"), b->number);
 }
 
+/* Implement the "print_recreate" breakpoint_ops method for exec
+   catchpoints.  */
+
+static void
+print_recreate_catch_exec (struct breakpoint *b, struct ui_file *fp)
+{
+  fprintf_unfiltered (fp, "catch exec");
+}
+
 static struct breakpoint_ops catch_exec_breakpoint_ops =
 {
   insert_catch_exec,
@@ -6334,7 +6395,8 @@ static struct breakpoint_ops catch_exec_
   breakpoint_hit_catch_exec,
   print_it_catch_exec,
   print_one_catch_exec,
-  print_mention_catch_exec
+  print_mention_catch_exec,
+  print_recreate_catch_exec
 };
 
 static void
@@ -8284,13 +8346,29 @@ print_mention_exception_catchpoint (stru
 			       : _(" (catch)"));
 }
 
+/* Implement the "print_recreate" breakpoint_ops method for throw and
+   catch catchpoints.  */
+
+static void
+print_recreate_exception_catchpoint (struct breakpoint *b, struct ui_file *fp)
+{
+  int bp_temp;
+  int bp_throw;
+
+  bp_temp = b->disposition == disp_del;
+  bp_throw = strstr (b->addr_string, "throw") != NULL;
+  fprintf_unfiltered (fp, bp_temp ? "tcatch " : "catch ");
+  fprintf_unfiltered (fp, bp_throw ? "throw" : "catch");
+}
+
 static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
   NULL, /* insert */
   NULL, /* remove */
   NULL, /* breakpoint_hit */
   print_exception_catchpoint,
   print_one_exception_catchpoint,
-  print_mention_exception_catchpoint
+  print_mention_exception_catchpoint,
+  print_recreate_exception_catchpoint
 };
 
 static int
@@ -10644,63 +10722,134 @@ get_tracepoint_by_number (char **arg, in
   return NULL;
 }
 
-/* save-tracepoints command */
+/* Save information on user settable breakpoints (watchpoints, etc) to
+   a new script file named FILENAME.  If FILTER is non-NULL, call it
+   on each breakpoint and only include the ones for which it returns
+   non-zero.  */
+
 static void
-tracepoint_save_command (char *args, int from_tty)
+save_breakpoints (char *filename, int from_tty,
+		  int (*filter) (const struct breakpoint *))
 {
   struct breakpoint *tp;
-  int any_tp = 0;
-  struct command_line *line;
+  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)"));
+  if (filename == 0 || *filename == 0)
+    error (_("Argument required (file name in which to save)"));
 
   /* See if we have anything to save.  */
-  ALL_TRACEPOINTS (tp)
+  ALL_BREAKPOINTS (tp)
   {
-    any_tp = 1;
-    break;
+    /* Skip internal and momentary breakpoints.  */
+    if (!user_settable_breakpoint (tp))
+      continue;
+
+    /* If we have a filter, only save the breakpoints it accepts.  */
+    if (filter && !filter (tp))
+      continue;
+
+    any = 1;
+
+    if (is_tracepoint (tp))
+      {
+	extra_trace_bits = 1;
+
+	/* We can stop searching.  */
+	break;
+      }
   }
-  if (!any_tp)
+
+  if (!any)
     {
-      warning (_("save-tracepoints: no tracepoints to save."));
+      warning (_("Nothing to save."));
       return;
     }
 
-  pathname = tilde_expand (args);
+  pathname = tilde_expand (filename);
   cleanup = make_cleanup (xfree, pathname);
   fp = gdb_fopen (pathname, "w");
   if (!fp)
-    error (_("Unable to open file '%s' for saving tracepoints (%s)"),
-	   args, safe_strerror (errno));
+    error (_("Unable to open file '%s' for saving (%s)"),
+	   filename, 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)
   {
-    if (tp->type == bp_fast_tracepoint)
-      fprintf_unfiltered (fp, "ftrace");
-    else
-      fprintf_unfiltered (fp, "trace");
+    /* Skip internal and momentary breakpoints.  */
+    if (tp->number <= 0)
+      continue;
 
-    if (tp->addr_string)
-      fprintf_unfiltered (fp, " %s", tp->addr_string);
+    /* If we have a filter, only save the breakpoints it accepts.  */
+    if (filter && !filter (tp))
+      continue;
+
+    if (tp->ops != NULL)
+      (tp->ops->print_recreate) (tp, fp);
     else
       {
-	sprintf_vma (tmp, tp->loc->address);
-	fprintf_unfiltered (fp, " *0x%s", tmp);
+	if (tp->type == bp_fast_tracepoint)
+	  fprintf_unfiltered (fp, "ftrace");
+	else if (tp->type == bp_tracepoint)
+	  fprintf_unfiltered (fp, "trace");
+	else 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
+	  internal_error (__FILE__, __LINE__,
+			  _("unhandled breakpoint type %d"), (int) tp->type);
+
+	if (tp->exp_string)
+	  fprintf_unfiltered (fp, " %s", tp->exp_string);
+	else if (tp->addr_string)
+	  fprintf_unfiltered (fp, " %s", tp->addr_string);
+	else
+	  {
+	    char tmp[40];
+
+	    sprintf_vma (tmp, tp->loc->address);
+	    fprintf_unfiltered (fp, " *0x%s", tmp);
+	  }
       }
 
-    if (tp->cond_string)
-      fprintf_unfiltered (fp, " if %s", tp->cond_string);
+    if (tp->thread != -1)
+      fprintf_unfiltered (fp, " thread %d", tp->thread);
+
+    if (tp->task != 0)
+      fprintf_unfiltered (fp, " task %d", tp->task);
 
     fprintf_unfiltered (fp, "\n");
 
+    /* Note, we can't rely on tp->number for anything, as we can't
+       assume the recreated breakpoint numbers will match.  Use $bpnum
+       instead.  */
+
+    if (tp->cond_string)
+      fprintf_unfiltered (fp, "  condition $bpnum %s\n", tp->cond_string);
+
+    if (tp->ignore_count)
+      fprintf_unfiltered (fp, "  ignore $bpnum %d\n", tp->ignore_count);
+
     if (tp->pass_count)
       fprintf_unfiltered (fp, "  passcount %d\n", tp->pass_count);
 
@@ -10708,7 +10857,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 +10871,46 @@ tracepoint_save_command (char *args, int
 
 	fprintf_unfiltered (fp, "  end\n");
       }
+
+    if (tp->enable_state == bp_disabled)
+      fprintf_unfiltered (fp, "disable\n");
+
+    /* If this is a multi-location breakpoint, check if the locations
+       should be individually disabled.  Watchpoint locations are
+       special, and not user visible.  */
+    if (!is_watchpoint (tp) && tp->loc && tp->loc->next)
+      {
+	struct bp_location *loc;
+	int n = 1;
+
+	for (loc = tp->loc; loc != NULL; loc = loc->next, n++)
+	  if (!loc->enabled)
+	    fprintf_unfiltered (fp, "disable $bpnum.%d\n", n);
+      }
   }
 
-  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 (_("Saved to file '%s'.\n"), filename);
+}
+
+/* The `save breakpoints' command.  */
+
+static void
+save_breakpoints_command (char *args, int from_tty)
+{
+  save_breakpoints (args, from_tty, NULL);
+}
+
+/* The `save tracepoints' command.  */
+
+static void
+save_tracepoints_command (char *args, int from_tty)
+{
+  save_breakpoints (args, from_tty, is_tracepoint);
 }
 
 /* Create a vector of all tracepoints.  */
@@ -10809,11 +10989,17 @@ clear_syscall_counts (struct inferior *i
   VEC_free (int, inf->syscalls_counts);
 }
 
+static void
+save_command (char *arg, int from_tty)
+{
+  printf_unfiltered (_("\
+\"save\" must be followed by the name of a save subcommand.\n"));
+  help_list (save_cmdlist, "save ", -1, gdb_stdout);
+}
+
 void
 _initialize_breakpoint (void)
 {
-  static struct cmd_list_element *breakpoint_set_cmdlist;
-  static struct cmd_list_element *breakpoint_show_cmdlist;
   struct cmd_list_element *c;
 
   observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
@@ -11227,11 +11413,28 @@ The trace will end when the tracepoint h
 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
 if TPNUM is omitted, passcount refers to the last tracepoint defined."));
 
-  c = add_com ("save-tracepoints", class_trace, tracepoint_save_command, _("\
+  add_prefix_cmd ("save", class_breakpoint, save_command,
+		  _("Save breakpoint definitions as a script."),
+		  &save_cmdlist, "save ",
+		  0/*allow-unknown*/, &cmdlist);
+
+  c = add_cmd ("breakpoints", class_breakpoint, save_breakpoints_command, _("\
+Save current breakpoint definitions as a script.\n\
+This includes all types of breakpoints (breakpoints, watchpoints, \n\
+catchpoints, tracepoints).  Use the 'source' command in another debug\n\
+session to restore them."),
+	       &save_cmdlist);
+  set_cmd_completer (c, filename_completer);
+
+  c = add_cmd ("tracepoints", class_trace, save_tracepoints_command, _("\
 Save current tracepoint definitions as a script.\n\
-Use the 'source' command in another debug session to restore them."));
+Use the 'source' command in another debug session to restore them."),
+	       &save_cmdlist);
   set_cmd_completer (c, filename_completer);
 
+  c = add_com_alias ("save-tracepoints", "save tracepoints", class_trace, 0);
+  deprecate_cmd (c, "save tracepoints");
+
   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-17 23:13:46.000000000 +0100
+++ src/gdb/breakpoint.h	2010-04-18 01:24:57.000000000 +0100
@@ -362,6 +362,9 @@ struct breakpoint_ops 
   /* Display information about this breakpoint after setting it (roughly
      speaking; this is called from "mention").  */
   void (*print_mention) (struct breakpoint *);
+
+  /* Print to FP the CLI command that recreates this breakpoint.  */
+  void (*print_recreate) (struct breakpoint *, struct ui_file *fp);
 };
 
 enum watchpoint_triggered
Index: src/gdb/ada-lang.c
===================================================================
--- src.orig/gdb/ada-lang.c	2010-04-17 23:13:46.000000000 +0100
+++ src/gdb/ada-lang.c	2010-04-18 01:24:57.000000000 +0100
@@ -10348,6 +10348,34 @@ print_mention_exception (enum exception_
     }
 }
 
+/* Implement the PRINT_RECREATE method in the breakpoint_ops structure
+   for all exception catchpoint kinds.  */
+
+static void
+print_recreate_exception (enum exception_catchpoint_kind ex,
+			  struct breakpoint *b, struct ui_file *fp)
+{
+  switch (ex)
+    {
+      case ex_catch_exception:
+	fprintf_filtered (fp, "catch exception");
+	if (b->exp_string != NULL)
+	  fprintf_filtered (fp, " %s", b->exp_string);
+	break;
+
+      case ex_catch_exception_unhandled:
+	fprintf_filtered (fp, "catch unhandled");
+	break;
+
+      case ex_catch_assert:
+	fprintf_filtered (fp, "catch assert");
+	break;
+
+      default:
+	internal_error (__FILE__, __LINE__, _("unexpected catchpoint type"));
+    }
+}
+
 /* Virtual table for "catch exception" breakpoints.  */
 
 static enum print_stop_action
@@ -10368,6 +10396,12 @@ print_mention_catch_exception (struct br
   print_mention_exception (ex_catch_exception, b);
 }
 
+static void
+print_recreate_catch_exception (struct breakpoint *b, struct ui_file *fp)
+{
+  print_recreate_exception (ex_catch_exception, b, fp);
+}
+
 static struct breakpoint_ops catch_exception_breakpoint_ops =
 {
   NULL, /* insert */
@@ -10375,7 +10409,8 @@ static struct breakpoint_ops catch_excep
   NULL, /* breakpoint_hit */
   print_it_catch_exception,
   print_one_catch_exception,
-  print_mention_catch_exception
+  print_mention_catch_exception,
+  print_recreate_catch_exception
 };
 
 /* Virtual table for "catch exception unhandled" breakpoints.  */
@@ -10399,13 +10434,21 @@ print_mention_catch_exception_unhandled 
   print_mention_exception (ex_catch_exception_unhandled, b);
 }
 
+static void
+print_recreate_catch_exception_unhandled (struct breakpoint *b,
+					  struct ui_file *fp)
+{
+  print_recreate_exception (ex_catch_exception_unhandled, b, fp);
+}
+
 static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops = {
   NULL, /* insert */
   NULL, /* remove */
   NULL, /* breakpoint_hit */
   print_it_catch_exception_unhandled,
   print_one_catch_exception_unhandled,
-  print_mention_catch_exception_unhandled
+  print_mention_catch_exception_unhandled,
+  print_recreate_catch_exception_unhandled
 };
 
 /* Virtual table for "catch assert" breakpoints.  */
@@ -10428,13 +10471,20 @@ print_mention_catch_assert (struct break
   print_mention_exception (ex_catch_assert, b);
 }
 
+static void
+print_recreate_catch_assert (struct breakpoint *b, struct ui_file *fp)
+{
+  print_recreate_exception (ex_catch_assert, b, fp);
+}
+
 static struct breakpoint_ops catch_assert_breakpoint_ops = {
   NULL, /* insert */
   NULL, /* remove */
   NULL, /* breakpoint_hit */
   print_it_catch_assert,
   print_one_catch_assert,
-  print_mention_catch_assert
+  print_mention_catch_assert,
+  print_recreate_catch_assert
 };
 
 /* Return non-zero if B is an Ada exception catchpoint.  */
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo	2010-04-17 23:13:46.000000000 +0100
+++ src/gdb/doc/gdb.texinfo	2010-04-18 01:26:00.000000000 +0100
@@ -3247,6 +3247,7 @@ all breakpoints in that range are operat
 * Disabling::                   Disabling breakpoints
 * Conditions::                  Break conditions
 * Break Commands::              Breakpoint command lists
+* Save Breakpoints::            How to save breakpoints in a file
 * Error in Breakpoints::        ``Cannot insert breakpoints''
 * Breakpoint-related Warnings:: ``Breakpoint address adjusted...''
 @end menu
@@ -4401,6 +4402,31 @@ cont
 end
 @end smallexample
 
+@node Save Breakpoints
+@subsection How to save breakpoints to a file
+
+To save breakpoint definitions to a file use the @w{@code{save
+breakpoints}} command.
+
+@table @code
+@kindex save breakpoints
+@cindex save breakpoints to a file for future sessions
+@item save breakpoints [@var{filename}]
+This command saves all current breakpoint definitions together with
+their commands and ignore counts, into a file @file{@var{filename}}
+suitable for use in a later debugging session.  This includes all
+types of breakpoints (breakpoints, watchpoints, catchpoints,
+tracepoints).  To read the saved breakpoint definitions, use the
+@code{source} command (@pxref{Command Files}).  Note that watchpoints
+with expressions involving local variables may fail to be recreated
+because it may not be possible to access the context where the
+watchpoint is valid anymore.  Because the saved breakpoint definitions
+are simply a sequence of @value{GDBN} commands that recreate the
+breakpoints, you can edit the file in your favorite editing program,
+and remove the breakpoint definitions you're not interested in, or
+that can no longer be recreated.
+@end table
+
 @c  @ifclear BARETARGET
 @node Error in Breakpoints
 @subsection ``Cannot insert breakpoints''
@@ -9980,7 +10006,7 @@ the buffer will fail.
 @menu
 * tfind::                       How to select a trace snapshot
 * tdump::                       How to display all data for a snapshot
-* save-tracepoints::            How to save tracepoints for a future run
+* save tracepoints::            How to save tracepoints for a future run
 @end menu
 
 @node tfind
@@ -10175,8 +10201,9 @@ list, and may fail if a while-stepping f
 same data that is collected at the tracepoint hit.
 @c This is getting pretty arcane, example would be good.
 
-@node save-tracepoints
-@subsection @code{save-tracepoints @var{filename}}
+@node save tracepoints
+@subsection @code{save tracepoints @var{filename}}
+@kindex save tracepoints
 @kindex save-tracepoints
 @cindex save tracepoints for future sessions
 
@@ -10184,7 +10211,8 @@ This command saves all current tracepoin
 their actions and passcounts, into a file @file{@var{filename}}
 suitable for use in a later debugging session.  To read the saved
 tracepoint definitions, use the @code{source} command (@pxref{Command
-Files}).
+Files}).  The @w{@code{save-tracepoints}} command is a deprecated
+alias for @w{@code{save tracepoints}}
 
 @node Tracepoint Variables
 @section Convenience Variables for Tracepoints
Index: src/gdb/NEWS
===================================================================
--- src.orig/gdb/NEWS	2010-04-17 23:13:46.000000000 +0100
+++ src/gdb/NEWS	2010-04-18 01:24:58.000000000 +0100
@@ -47,6 +47,16 @@ qGetTIBAddr
   single `break' command creates multiple breakpoints (e.g.,
   breakpoints on overloaded c++ functions).
 
+* New commands
+
+save breakpoints <filename>
+  Save all current breakpoint definitions to a file suitable for use
+  in a later debugging session.  To read the saved breakpoint
+  definitions, use the `source' command.
+
+`save tracepoints' is a new alias for `save-tracepoints'.  The latter
+is now deprecated.
+
 * Python scripting
 
 ** The GDB Python API now has access to breakpoints, symbols, symbol
Index: src/gdb/testsuite/gdb.trace/save-trace.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.trace/save-trace.exp	2010-04-17 23:13:46.000000000 +0100
+++ src/gdb/testsuite/gdb.trace/save-trace.exp	2010-04-18 01:24:58.000000000 +0100
@@ -129,7 +129,7 @@ gdb_verify_tracepoints "10.x: verify tra
 
 remote_file host delete savetrace.tr
 gdb_test "save-tracepoints savetrace.tr" \
-	"Tracepoints saved to file 'savetrace.tr'." \
+	"Saved to file 'savetrace.tr'." \
 	"10.1: save tracepoint definitions"
 
 # 10.2 Read back tracepoint definitions
@@ -148,7 +148,7 @@ remote_file host delete savetrace.tr
 set escapedfilename [string_to_regexp $objdir/savetrace.tr]
 remote_file host delete $objdir/savetrace.tr
 gdb_test "save-tracepoints $objdir/savetrace.tr" \
-	"Tracepoints saved to file '${escapedfilename}'." \
+	"Saved to file '${escapedfilename}'." \
 	"10.3: save tracepoint definitions, full path"
 
 gdb_delete_tracepoints


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