2012-02-14 Stan Shebs <stan@codesourcery.com>
authorStan Shebs <shebs@codesourcery.com>
Tue, 14 Feb 2012 23:28:15 +0000 (23:28 +0000)
committerStan Shebs <shebs@codesourcery.com>
Tue, 14 Feb 2012 23:28:15 +0000 (23:28 +0000)
* NEWS: Mention enable count command.
* breakpoint.h (struct breakpoint): New field enable_count.
* breakpoint.c (enable_breakpoint_disp): Add count argument.
(enable_breakpoint): Add arg to call.
(struct disp_data): New struct.
(do_enable_breakpoint_disp): Interp arg as disp_data and unpack.
(do_map_enable_once_breakpoint): Create a struct and pass it.
(do_map_enable_delete_breakpoint): Ditto.
(do_map_enable_count_breakpoint): New function.
(enable_count_command): New function.
(bpstat_stop_status): Decrement enable_count.
(print_one_breakpoint_location): Report enable count.
(_initialize_breakpoint): Add enable count command.

* gdb.texinfo (Disabling Breakpoints): Document enable count.

* gdb.base/ena-dis-br.exp: Add enable count test.

gdb/ChangeLog
gdb/NEWS
gdb/breakpoint.c
gdb/breakpoint.h
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/ena-dis-br.exp

index 279e223c2ab01e647c41934c332b2c4f0e14c5cf..a8fb900f2392b1d9e6aafb2b2f454bf232f802d3 100644 (file)
@@ -1,3 +1,19 @@
+2012-02-14  Stan Shebs  <stan@codesourcery.com>
+
+       * NEWS: Mention enable count command.
+       * breakpoint.h (struct breakpoint): New field enable_count.
+       * breakpoint.c (enable_breakpoint_disp): Add count argument.
+       (enable_breakpoint): Add arg to call.
+       (struct disp_data): New struct.
+       (do_enable_breakpoint_disp): Interp arg as disp_data and unpack.
+       (do_map_enable_once_breakpoint): Create a struct and pass it.
+       (do_map_enable_delete_breakpoint): Ditto.
+       (do_map_enable_count_breakpoint): New function.
+       (enable_count_command): New function.
+       (bpstat_stop_status): Decrement enable_count.
+       (print_one_breakpoint_location): Report enable count.
+       (_initialize_breakpoint): Add enable count command.
+
 2012-02-14  Kevin Buettner  <kevinb@redhat.com>
 
        * rl78-tdep.c (reggroups.h): Include.
index 46ef6d8d046876e6407afb83e0ccf827e2c7c1ce..ec7863a782566af78b90e07881107f7991fdf6c9 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -49,6 +49,9 @@
   ** "catch load" and "catch unload" can be used to stop when a shared
      library is loaded or unloaded, respectively.
 
+  ** "enable count" can be used to auto-disable a breakpoint after
+     several hits.
+
 *** Changes in GDB 7.4
 
 * GDB now handles ambiguous linespecs more consistently; the existing
index 9a878e15d735d9ca1f7f2a8e9de57ad8545bafe2..485476581c47deaa05f1f65b93b3cfb6fdaae5d9 100644 (file)
@@ -83,6 +83,8 @@ static void enable_delete_command (char *, int);
 
 static void enable_once_command (char *, int);
 
+static void enable_count_command (char *, int);
+
 static void disable_command (char *, int);
 
 static void enable_command (char *, int);
@@ -207,7 +209,8 @@ static void hbreak_command (char *, int);
 
 static void thbreak_command (char *, int);
 
-static void enable_breakpoint_disp (struct breakpoint *, enum bpdisp);
+static void enable_breakpoint_disp (struct breakpoint *, enum bpdisp,
+                                   int count);
 
 static void stop_command (char *arg, int from_tty);
 
@@ -4335,7 +4338,9 @@ bpstat_stop_status (struct address_space *aspace,
              /* We will stop here.  */
              if (b->disposition == disp_disable)
                {
-                 if (b->enable_state != bp_permanent)
+                 --(b->enable_count);
+                 if (b->enable_count <= 0
+                     && b->enable_state != bp_permanent)
                    b->enable_state = bp_disabled;
                  removed_any = 1;
                }
@@ -5039,6 +5044,23 @@ print_one_breakpoint_location (struct breakpoint *b,
       ui_out_text (uiout, " hits\n");
     }
 
+  /* Note that an enable count of 1 corresponds to "enable once"
+     behavior, which is reported by the combination of enablement and
+     disposition, so we don't need to mention it here.  */
+  if (!part_of_multiple && b->enable_count > 1)
+    {
+      annotate_field (8);
+      ui_out_text (uiout, "\tdisable after ");
+      /* Tweak the wording to clarify that ignore and enable counts
+        are distinct, and have additive effect.  */
+      if (b->ignore_count)
+       ui_out_text (uiout, "additional ");
+      else
+       ui_out_text (uiout, "next ");
+      ui_out_field_int (uiout, "enable", b->enable_count);
+      ui_out_text (uiout, " hits\n");
+    }
+
   if (!part_of_multiple && is_tracepoint (b))
     {
       struct tracepoint *tp = (struct tracepoint *) b;
@@ -12884,7 +12906,8 @@ disable_command (char *args, int from_tty)
 }
 
 static void
-enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition)
+enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
+                       int count)
 {
   int target_resources_ok;
 
@@ -12937,6 +12960,7 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition)
     }
 
   bpt->disposition = disposition;
+  bpt->enable_count = count;
   update_global_location_list (1);
   breakpoints_changed ();
   
@@ -12947,7 +12971,7 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition)
 void
 enable_breakpoint (struct breakpoint *bpt)
 {
-  enable_breakpoint_disp (bpt, bpt->disposition);
+  enable_breakpoint_disp (bpt, bpt->disposition, 0);
 }
 
 static void
@@ -12997,18 +13021,27 @@ enable_command (char *args, int from_tty)
     map_breakpoint_numbers (args, do_map_enable_breakpoint, NULL);
 }
 
+/* This struct packages up disposition data for application to multiple
+   breakpoints.  */
+
+struct disp_data
+{
+  enum bpdisp disp;
+  int count;
+};
+
 static void
 do_enable_breakpoint_disp (struct breakpoint *bpt, void *arg)
 {
-  enum bpdisp disp = *(enum bpdisp *) arg;
+  struct disp_data disp_data = *(struct disp_data *) arg;
 
-  enable_breakpoint_disp (bpt, disp);
+  enable_breakpoint_disp (bpt, disp_data.disp, disp_data.count);
 }
 
 static void
 do_map_enable_once_breakpoint (struct breakpoint *bpt, void *ignore)
 {
-  enum bpdisp disp = disp_disable;
+  struct disp_data disp = { disp_disable, 1 };
 
   iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
 }
@@ -13019,10 +13052,26 @@ enable_once_command (char *args, int from_tty)
   map_breakpoint_numbers (args, do_map_enable_once_breakpoint, NULL);
 }
 
+static void
+do_map_enable_count_breakpoint (struct breakpoint *bpt, void *countptr)
+{
+  struct disp_data disp = { disp_disable, *(int *) countptr };
+
+  iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
+}
+
+static void
+enable_count_command (char *args, int from_tty)
+{
+  int count = get_number (&args);
+
+  map_breakpoint_numbers (args, do_map_enable_count_breakpoint, &count);
+}
+
 static void
 do_map_enable_delete_breakpoint (struct breakpoint *bpt, void *ignore)
 {
-  enum bpdisp disp = disp_del;
+  struct disp_data disp = { disp_del, 1 };
 
   iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
 }
@@ -14291,6 +14340,12 @@ Enable breakpoints and delete when hit.  Give breakpoint numbers.\n\
 If a breakpoint is hit while enabled in this fashion, it is deleted."),
           &enablebreaklist);
 
+  add_cmd ("count", no_class, enable_count_command, _("\
+Enable breakpoints for COUNT hits.  Give count and then breakpoint numbers.\n\
+If a breakpoint is hit while enabled in this fashion,\n\
+the count is decremented; when it reaches zero, the breakpoint is disabled."),
+          &enablebreaklist);
+
   add_cmd ("delete", no_class, enable_delete_command, _("\
 Enable breakpoints and delete when hit.  Give breakpoint numbers.\n\
 If a breakpoint is hit while enabled in this fashion, it is deleted."),
@@ -14301,6 +14356,12 @@ Enable breakpoints for one hit.  Give breakpoint numbers.\n\
 If a breakpoint is hit while enabled in this fashion, it becomes disabled."),
           &enablelist);
 
+  add_cmd ("count", no_class, enable_count_command, _("\
+Enable breakpoints for COUNT hits.  Give count and then breakpoint numbers.\n\
+If a breakpoint is hit while enabled in this fashion,\n\
+the count is decremented; when it reaches zero, the breakpoint is disabled."),
+          &enablelist);
+
   add_prefix_cmd ("disable", class_breakpoint, disable_command, _("\
 Disable some breakpoints.\n\
 Arguments are breakpoint numbers with spaces in between.\n\
index aa66790730e44b9dd3cfb5f129b6fc71a22bf8aa..07e3fc94d3b6b38e8215ff06280c62d9422e7235 100644 (file)
@@ -596,6 +596,11 @@ struct breakpoint
     /* Number of stops at this breakpoint that should
        be continued automatically before really stopping.  */
     int ignore_count;
+
+    /* Number of stops at this breakpoint before it will be
+       disabled.  */
+    int enable_count;
+
     /* Chain of command lines to execute when this breakpoint is
        hit.  */
     struct counted_command_line *commands;
index 0aac7d256daa3197c6f660fa9e8bd27d696c4b65..6c394948424ec04ca8adba186fa95a4de2054bc0 100644 (file)
@@ -1,3 +1,7 @@
+2012-02-14  Stan Shebs  <stan@codesourcery.com>
+
+       * gdb.texinfo (Disabling Breakpoints): Document enable count.
+
 2012-02-13  Pedro Alves  <palves@redhat.com>
 
        * gdb.texinfo (MIPS boards): Refer to mips-elf instead of
index 9edc6ad5a655c617b7e23faa8f0fce067fa173bf..437382207aa8a33e1e60fa77e8d54251821d27a0 100644 (file)
@@ -3505,6 +3505,11 @@ has been hit.  This is especially useful in conjunction with the
 hits, look at the breakpoint info to see how many times the breakpoint
 was hit, and then run again, ignoring one less than that number.  This
 will get you quickly to the last hit of that breakpoint.
+
+@noindent
+For a breakpoints with an enable count (xref) greater than 1,
+@code{info break} also displays that count.
+
 @end table
 
 @value{GDBN} allows you to set any number of breakpoints at the same place in
@@ -4252,8 +4257,8 @@ do not know which numbers to use.
 Disabling and enabling a breakpoint that has multiple locations
 affects all of its locations.
 
-A breakpoint, watchpoint, or catchpoint can have any of four different
-states of enablement:
+A breakpoint, watchpoint, or catchpoint can have any of several
+different states of enablement:
 
 @itemize @bullet
 @item
@@ -4265,6 +4270,9 @@ Disabled.  The breakpoint has no effect on your program.
 Enabled once.  The breakpoint stops your program, but then becomes
 disabled.
 @item
+Enabled for a count.  The breakpoint stops your program for the next
+N times, then becomes disabled.
+@item
 Enabled for deletion.  The breakpoint stops your program, but
 immediately after it does so it is deleted permanently.  A breakpoint
 set with the @code{tbreak} command starts out in this state.
@@ -4292,6 +4300,14 @@ become effective once again in stopping your program.
 Enable the specified breakpoints temporarily.  @value{GDBN} disables any
 of these breakpoints immediately after stopping your program.
 
+@item enable @r{[}breakpoints@r{]} count @var{count} @var{range}@dots{}
+Enable the specified breakpoints temporarily.  @value{GDBN} records
+@var{count} with each of the specified breakpoints, and decrements a
+breakpoint's count when it is hit.  When any count reaches 0,
+@value{GDBN} disables that breakpoint.  If a breakpoint has an ignore
+count (@pxref{Conditions, ,Break Conditions}), that will be
+decremented to 0 before @var{count} is affected.
+
 @item enable @r{[}breakpoints@r{]} delete @var{range}@dots{}
 Enable the specified breakpoints to work once, then die.  @value{GDBN}
 deletes any of these breakpoints as soon as your program stops there.
index 35b1df5dae92e5b8231d34cce574f24eea0ea030..463a6aeb8bcca0a8efa0e4667fee0aeb41064c7f 100644 (file)
@@ -1,3 +1,7 @@
+2012-02-14  Stan Shebs  <stan@codesourcery.com>
+
+       * gdb.base/ena-dis-br.exp: Add enable count test.
+
 2012-02-13  Pedro Alves  <palves@redhat.com>
 
        * config/mips-idt.exp: Delete.
index 2e5cdb1717e9227fb82eee02981bb18a7a1ed29c..2cf3e9a17d2499e1b03176d59e2a0de1016e1dab 100644 (file)
@@ -46,6 +46,7 @@ gdb_reinitialize_dir $srcdir/$subdir
 gdb_load ${binfile}
 
 set bp_location1 [gdb_get_line_number "set breakpoint 1 here"]
+set bp_location7 [gdb_get_line_number "set breakpoint 7 here"]
 set bp_location8 [gdb_get_line_number "set breakpoint 8 here" $srcfile1]
 set bp_location9 [gdb_get_line_number "set breakpoint 9 here" $srcfile1]
 set bp_location11 [gdb_get_line_number "set breakpoint 11 here"]
@@ -162,6 +163,31 @@ gdb_test "info break $bp" \
     "\[0-9\]*\[ \t\]+breakpoint\[ \t\]+keep\[ \t\]+n.*" \
     "info break marker4"
 
+if ![runto_main] then {
+    fail "enable/disable break tests suppressed"
+}
+
+# Test enable count by stopping at a location until it is disabled
+# and passes through.
+
+set bp [break_at $bp_location7 "line $bp_location7"]
+
+set bp2 [break_at marker1 " line ($bp_location15|$bp_location16)"]
+
+gdb_test_no_output "enable count 2 $bp" "disable break with count"
+
+gdb_test "continue" \
+    ".*factorial .*:$bp_location7.*" \
+    "continue from enable count, first time"
+
+gdb_test "continue" \
+    ".*factorial .*:$bp_location7.*" \
+    "continue from enable count, second time"
+
+gdb_test "continue" \
+    ".*marker1 .*:($bp_location15|$bp_location16).*" \
+    "continue through enable count, now disabled"
+
 # Verify that we can set a breakpoint with an ignore count N, which
 # should cause the next N triggers of the bp to be ignored.  (This is
 # a flavor of enablement/disablement, after all.)
This page took 0.07253 seconds and 4 git commands to generate.