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]

Re: [2/2] RFC: let "commands" affect multiple breakpoints


On Wednesday 24 March 2010 21:21:08, Tom Tromey wrote:
> I'm checking in the appended.  This is the revised patch, rebased on top
> of Volodya's patches.

Thanks.

<In an earlier email, Tom said:>

> I do have a question though.  With this change, gdb prints somewhat less
> nice text for "commands":
> 
> Tom> +  l = read_command_lines (_("Type commands for all specified breakpoints"),
> Tom> +                          info->from_tty, 1);
> 
> Tom> -  char *tmpbuf = xstrprintf ("Type commands for when breakpoint %d is hit, one per line.", 
> Tom> -                           bnum);
> 
> Any suggestions for something better here?

I have a suggestion for this, in form of a patch.  How
about we just print the breakpoint range?  I find this:

 (top-gdb) rbreak main
 ...
 ...
 (top-gdb) commands
 Type commands for breakpoint(s) 3-80, one per line.
 End with a line saying just "end".
 >

nicer than:

 (top-gdb) commands
 Type commands for all specified breakpoints
 End with a line saying just "end".
 >

as in the latter case, I didn't specify any breakpoints, so
"specified breakpoints" sounds vague, and doesn't quickly
imply that it will create commands for all previously created
breakpoints.

> 	* NEWS: Mention changes to `commands' and `rbreak'.
> 	* gdb.texinfo (Break Commands): Update.

I'm also suggesting to adjusting these to better explain that
this applies when "break" (or similars) creates more than one
breakpoint.  That is different to creating a breakpoint with
multiple locations ("multiple locations" are described both
in the manual and in NEWS); in the multiple locations case,
"commands" already applied to all locations.  I'm adding
a cross reference to where the case where multiple breakpoints
are created is described; that section has a nice example.

WDYT?

-- 
Pedro Alves

2010-03-25  Pedro Alves  <pedro@codesourcery.com>

	gdb/
	* breakpoint.c (multi_start, multi_end, last_was_multi): Delete.
	(prev_breakpoint_count): New.
	(set_breakpoint_count): Adjust.
	(rbreak_start_breakpoint_count): New.
	(start_rbreak_breakpoints): Adjust.
	(end_rbreak_breakpoints): Adjust.
	(struct commands_info) <arg>: New field.
	(do_map_commands_command): Tweak output to include breakpoint spec
	range.
	(commands_command_1): Adjust.  Avoid setting an xfree cleanup if
	ARG was empty on entry.  Set INFO's arg.
	(create_breakpoint): Adjust.

	* NEWS: Clarify `commands' changes.

	gdb/doc/
	* gdb.texinfo (Break Commands): Clarify `commands' changes, and
	add cross reference.

	gdb/testsuite/
	* gdb.base/commands.exp: Adjust.
	* gdb.cp/extern-c.exp: Adjust.

---
 gdb/NEWS                            |    7 ++-
 gdb/breakpoint.c                    |   72 +++++++++++++++++++++++-------------
 gdb/doc/gdb.texinfo                 |    5 +-
 gdb/testsuite/gdb.base/commands.exp |    6 +--
 gdb/testsuite/gdb.cp/extern-c.exp   |    2 -
 5 files changed, 58 insertions(+), 34 deletions(-)

Index: src/gdb/breakpoint.c
===================================================================
--- src.orig/gdb/breakpoint.c	2010-03-25 14:50:13.000000000 +0000
+++ src/gdb/breakpoint.c	2010-03-25 16:43:09.000000000 +0000
@@ -390,13 +390,11 @@ VEC(bp_location_p) *moribund_locations =
 
 static int breakpoint_count;
 
-/* If the last command to create a breakpoint created multiple
-   breakpoints, this holds the start and end breakpoint numbers.  */
-static int multi_start;
-static int multi_end;
-/* True if the last breakpoint set was part of a group set with a
-   single command, e.g., "rbreak".  */
-static int last_was_multi;
+/* The value of `breakpoint_count' before the last command that
+   created breakpoints.  If the last (break-like) command created more
+   than one breakpoint, then the difference between BREAKPOINT_COUNT
+   and PREV_BREAKPOINT_COUNT is more than one.  */
+static int prev_breakpoint_count;
 
 /* Number of last tracepoint made.  */
 
@@ -414,29 +412,31 @@ breakpoint_enabled (struct breakpoint *b
 static void
 set_breakpoint_count (int num)
 {
+  prev_breakpoint_count = breakpoint_count;
   breakpoint_count = num;
-  last_was_multi = 0;
   set_internalvar_integer (lookup_internalvar ("bpnum"), num);
 }
 
+/* Used by `start_rbreak_breakpoints' below, to record the current
+   breakpoint count before "rbreak" creates any breakpoint.  */
+static int rbreak_start_breakpoint_count;
+
 /* Called at the start an "rbreak" command to record the first
    breakpoint made.  */
+
 void
 start_rbreak_breakpoints (void)
 {
-  multi_start = breakpoint_count + 1;
+  rbreak_start_breakpoint_count = breakpoint_count;
 }
 
 /* Called at the end of an "rbreak" command to record the last
    breakpoint made.  */
+
 void
 end_rbreak_breakpoints (void)
 {
-  if (breakpoint_count >= multi_start)
-    {
-      multi_end = breakpoint_count;
-      last_was_multi = 1;
-    }
+  prev_breakpoint_count = rbreak_start_breakpoint_count;
 }
 
 /* Used in run_command to zero the hit count when a new run starts. */
@@ -896,9 +896,14 @@ struct commands_info
 {
   /* True if the command was typed at a tty.  */
   int from_tty;
+
+  /* The breakpoint range spec.  */
+  char *arg;
+
   /* Non-NULL if the body of the commands are being read from this
      already-parsed command.  */
   struct command_line *control;
+
   /* The command lines read from the user, or NULL if they have not
      yet been read.  */
   struct counted_command_line *cmd;
@@ -919,12 +924,23 @@ do_map_commands_command (struct breakpoi
       if (info->control != NULL)
 	l = copy_command_lines (info->control->body_list[0]);
       else
+	{
+	  struct cleanup *old_chain;
+	  char *str;
+
+	  str = xstrprintf (_("Type commands for breakpoint(s) %s, one per line."),
+			    info->arg);
+
+	  old_chain = make_cleanup (xfree, str);
+
+	  l = read_command_lines (str,
+				  info->from_tty, 1,
+				  (breakpoint_is_tracepoint (b)
+				   ? check_tracepoint_command : 0),
+				  b);
 
-	l = read_command_lines (_("Type commands for all specified breakpoints"),
-				info->from_tty, 1,
-				(breakpoint_is_tracepoint (b)
-				 ? check_tracepoint_command : 0),
-				b);
+	  do_cleanups (old_chain);
+	}
 
       info->cmd = alloc_counted_command_line (l);
     }
@@ -957,13 +973,19 @@ commands_command_1 (char *arg, int from_
 
   if (arg == NULL || !*arg)
     {
-      if (last_was_multi)
-	arg = xstrprintf ("%d-%d", multi_start, multi_end);
+      if (breakpoint_count - prev_breakpoint_count > 1)
+	arg = xstrprintf ("%d-%d", prev_breakpoint_count + 1, breakpoint_count);
       else if (breakpoint_count > 0)
 	arg = xstrprintf ("%d", breakpoint_count);
-      make_cleanup (xfree, arg);
+      else
+	arg = NULL;
+
+      if (arg != NULL)
+	make_cleanup (xfree, arg);
     }
 
+  info.arg = arg;
+
   map_breakpoint_numbers (arg, do_map_commands_command, &info);
 
   if (info.cmd == NULL)
@@ -7176,7 +7198,7 @@ create_breakpoint (struct gdbarch *gdbar
   int not_found = 0;
   enum bptype type_wanted;
   int task = 0;
-  int first_bp_set = breakpoint_count + 1;
+  int prev_bkpt_count = breakpoint_count;
 
   sals.sals = NULL;
   sals.nelts = 0;
@@ -7336,9 +7358,7 @@ create_breakpoint (struct gdbarch *gdbar
     {
       warning (_("Multiple breakpoints were set.\n"
 		 "Use the \"delete\" command to delete unwanted breakpoints."));
-      multi_start = first_bp_set;
-      multi_end = breakpoint_count;
-      last_was_multi = 1;
+      prev_breakpoint_count = prev_bkpt_count;
     }
 
   /* That's it.  Discard the cleanups for data inserted into the
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo	2010-03-25 15:45:15.000000000 +0000
+++ src/gdb/doc/gdb.texinfo	2010-03-25 16:54:03.000000000 +0000
@@ -4343,8 +4343,9 @@ watchpoint, or catchpoint set (not to th
 encountered).  If the most recent breakpoints were set with a single
 command, then the @code{commands} will apply to all the breakpoints
 set by that command.  This applies to breakpoints set by
-@code{rbreak}, and also breakpoints set with @code{break} that have
-multiple locations.
+@code{rbreak}, and also applies when a single @code{break} command
+creates multiple breakpoints (@pxref{Ambiguous Expressions,,Ambiguous
+Expressions}).
 @end table
 
 Pressing @key{RET} as a means of repeating the last @value{GDBN} command is
Index: src/gdb/testsuite/gdb.base/commands.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.base/commands.exp	2010-03-25 16:07:22.000000000 +0000
+++ src/gdb/testsuite/gdb.base/commands.exp	2010-03-25 16:15:57.000000000 +0000
@@ -299,7 +299,7 @@ proc watchpoint_command_test {} {
 
     send_gdb "commands $wp_id\n"
     gdb_expect {
-      -re "Type commands for all specified breakpoints.*>" {
+      -re "Type commands for breakpoint.*, one per line.*>" {
 	  pass "begin commands on watch"
       }
       -re "$gdb_prompt $" {fail "begin commands on watch"}
@@ -452,7 +452,7 @@ proc bp_deleted_in_command_test {} {
     
     send_gdb "commands\n"
     gdb_expect {
-      -re "Type commands for all specified breakpoints.*>" {
+      -re "Type commands for breakpoint.*>" {
           pass "begin commands in bp_deleted_in_command_test"
       }
       -re "$gdb_prompt $" {fail "begin commands in bp_deleted_in_command_test"}
@@ -519,7 +519,7 @@ proc temporary_breakpoint_commands {} {
     
     send_gdb "commands\n"
     gdb_expect {
-	-re "Type commands for all specified breakpoints.*>" {
+	-re "Type commands for breakpoint.*>" {
 	    pass "begin commands in bp_deleted_in_command_test"
 	}
 	-re "$gdb_prompt $" {fail "begin commands in bp_deleted_in_command_test"}
Index: src/gdb/testsuite/gdb.cp/extern-c.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.cp/extern-c.exp	2010-03-25 16:07:33.000000000 +0000
+++ src/gdb/testsuite/gdb.cp/extern-c.exp	2010-03-25 16:18:27.000000000 +0000
@@ -48,7 +48,7 @@ gdb_test "rbreak c_funcs" \
 # Test that "commands" without an argument puts commands on both
 # breakpoints.
 gdb_test_multiple "commands" "set commands on multiple breakpoints" {
-  -re "Type commands for all specified breakpoints\r\nEnd with a line saying just \"end\".\r\n>$" {
+  -re "Type commands for breakpoint\\(s\\) 3-4, one per line\.\r\nEnd with a line saying just \"end\".\r\n>$" {
     gdb_test_multiple "set \$counter = \$counter + 1\nend" \
       "command details for multiple breakpoints" {
 	-re "$gdb_prompt $" {
Index: src/gdb/NEWS
===================================================================
--- src.orig/gdb/NEWS	2010-03-25 16:44:23.000000000 +0000
+++ src/gdb/NEWS	2010-03-25 16:52:29.000000000 +0000
@@ -14,8 +14,11 @@
   register EAX or 64-bit register RAX.
 
 * The `commands' command now accepts a range of breakpoints to modify.
-  A plain `commands' following an `rbreak' will affect all the
-  breakpoints set by `rbreak'.
+  A plain `commands' following a command that creates multiple
+  breakpoints affects all the breakpoints set by that command.  This
+  applies to breakpoints set by `rbreak', and also applies when a
+  single `break' command creates multiple breakpoints (e.g.,
+  breakpoints on overloaded c++ functions).
 
 * Python scripting
 


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