gdb/mi: add a '--force' flag to the '-break-condition' command
authorTankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Thu, 6 May 2021 08:13:06 +0000 (10:13 +0200)
committerTankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Thu, 6 May 2021 08:46:40 +0000 (10:46 +0200)
Add a '--force' flag to the '-break-condition' command to be
able to force conditions.

gdb/ChangeLog:
2021-05-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

* mi/mi-cmd-break.c (mi_cmd_break_condition): New function.
* mi/mi-cmds.c: Change the binding of "-break-condition" to
mi_cmd_break_condition.
* mi/mi-cmds.h (mi_cmd_break_condition): Declare.
* breakpoint.h (set_breakpoint_condition): Declare a new
overload.
* breakpoint.c (set_breakpoint_condition): New overloaded function
extracted out from ...
(condition_command): ... this.
* NEWS: Mention the change.

gdb/testsuite/ChangeLog:
2021-05-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

* gdb.mi/mi-break.exp (test_forced_conditions): Add a test
for the -break-condition command's "--force" flag.

gdb/doc/ChangeLog:
2021-05-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

* gdb.texinfo (GDB/MI Breakpoint Commands): Mention the
'--force' flag of the '-break-condition' command.

gdb/ChangeLog
gdb/NEWS
gdb/breakpoint.c
gdb/breakpoint.h
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/mi/mi-cmd-break.c
gdb/mi/mi-cmds.c
gdb/mi/mi-cmds.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.mi/mi-break.exp

index 87f366c4b68399b0efb45a035b9d53b2f3fb7a6e..14b1a3d0c8f99bf9fda202051d6cf75797a50eb4 100644 (file)
@@ -1,3 +1,16 @@
+2021-05-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
+
+       * mi/mi-cmd-break.c (mi_cmd_break_condition): New function.
+       * mi/mi-cmds.c: Change the binding of "-break-condition" to
+       mi_cmd_break_condition.
+       * mi/mi-cmds.h (mi_cmd_break_condition): Declare.
+       * breakpoint.h (set_breakpoint_condition): Declare a new
+       overload.
+       * breakpoint.c (set_breakpoint_condition): New overloaded function
+       extracted out from ...
+       (condition_command): ... this.
+       * NEWS: Mention the change.
+
 2021-05-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
 
        * mi/mi-cmd-break.c (mi_cmd_break_insert_1): Recognize the
index a814b41315dd68f5d532d32fea90ce565ccaf3ec..784c1038920f580307935a7eaad1b87b74b8206a 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
     is equivalent to the '-force-condition' flag of the CLI's "break"
     command.
 
+ ** '-break-condition --force'
+
+    The MI -break-condition command now supports a '--force' flag to
+    forcibly define a condition even when the condition is invalid at
+    all locations of the selected breakpoint.  This is equivalent to
+    the '-force' flag of the CLI's "cond" command.
+
 * GDB now supports core file debugging for x86_64 Cygwin programs.
 
 * GDB will now look for the .gdbinit file in a config directory before
index 9cc53f8ef54ed3c21b2b672431bac260009a8cab..35a891bb4b9568bbcbc0f6c2a88870ff7b9ebfef 100644 (file)
@@ -973,6 +973,39 @@ set_breakpoint_condition (struct breakpoint *b, const char *exp,
   gdb::observers::breakpoint_modified.notify (b);
 }
 
+/* See breakpoint.h.  */
+
+void
+set_breakpoint_condition (int bpnum, const char *exp, int from_tty,
+                         bool force)
+{
+  struct breakpoint *b;
+  ALL_BREAKPOINTS (b)
+    if (b->number == bpnum)
+      {
+       /* Check if this breakpoint has a "stop" method implemented in an
+          extension language.  This method and conditions entered into GDB
+          from the CLI are mutually exclusive.  */
+       const struct extension_language_defn *extlang
+         = get_breakpoint_cond_ext_lang (b, EXT_LANG_NONE);
+
+       if (extlang != NULL)
+         {
+           error (_("Only one stop condition allowed.  There is currently"
+                    " a %s stop condition defined for this breakpoint."),
+                  ext_lang_capitalized_name (extlang));
+         }
+       set_breakpoint_condition (b, exp, from_tty, force);
+
+       if (is_breakpoint (b))
+         update_global_location_list (UGLL_MAY_INSERT);
+
+       return;
+      }
+
+  error (_("No breakpoint number %d."), bpnum);
+}
+
 /* The options for the "condition" command.  */
 
 struct condition_command_opts
@@ -1066,7 +1099,6 @@ condition_completer (struct cmd_list_element *cmd,
 static void
 condition_command (const char *arg, int from_tty)
 {
-  struct breakpoint *b;
   const char *p;
   int bnum;
 
@@ -1085,30 +1117,7 @@ condition_command (const char *arg, int from_tty)
   if (bnum == 0)
     error (_("Bad breakpoint argument: '%s'"), arg);
 
-  ALL_BREAKPOINTS (b)
-    if (b->number == bnum)
-      {
-       /* Check if this breakpoint has a "stop" method implemented in an
-          extension language.  This method and conditions entered into GDB
-          from the CLI are mutually exclusive.  */
-       const struct extension_language_defn *extlang
-         = get_breakpoint_cond_ext_lang (b, EXT_LANG_NONE);
-
-       if (extlang != NULL)
-         {
-           error (_("Only one stop condition allowed.  There is currently"
-                    " a %s stop condition defined for this breakpoint."),
-                  ext_lang_capitalized_name (extlang));
-         }
-       set_breakpoint_condition (b, p, from_tty, cc_opts.force_condition);
-
-       if (is_breakpoint (b))
-         update_global_location_list (UGLL_MAY_INSERT);
-
-       return;
-      }
-
-  error (_("No breakpoint number %d."), bnum);
+  set_breakpoint_condition (bnum, p, from_tty, cc_opts.force_condition);
 }
 
 /* Check that COMMAND do not contain commands that are suitable
index 3447e25da205b93821308abae52b9898ace4a542..54c5e423e10aebf25ba32a758d0392a5bc53ee0d 100644 (file)
@@ -1656,6 +1656,14 @@ extern void breakpoint_retire_moribund (void);
 extern void set_breakpoint_condition (struct breakpoint *b, const char *exp,
                                      int from_tty, bool force);
 
+/* Set break condition for the breakpoint with number BPNUM to EXP.
+   Raise an error if no breakpoint with the given number is found.
+   Also raise an error if the breakpoint already has stop conditions.
+   If FORCE, define the condition even if it is invalid in
+   all of the breakpoint locations.  */
+extern void set_breakpoint_condition (int bpnum, const char *exp,
+                                     int from_tty, bool force);
+
 /* Checks if we are catching syscalls or not.
    Returns 0 if not, greater than 0 if we are.  */
 extern int catch_syscall_enabled (void);
index 85c09900185a4f1e497a9b8f90547e64001443c0..d64504f1ffcf1c9e72c6043da6d07a0f79b8525d 100644 (file)
@@ -1,3 +1,8 @@
+2021-05-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
+
+       * gdb.texinfo (GDB/MI Breakpoint Commands): Mention the
+       '--force' flag of the '-break-condition' command.
+
 2021-05-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
 
        * gdb.texinfo (GDB/MI Breakpoint Commands): Mention the
index b7667f7d11e776c4ef58040cc846a0ff202663d5..56f37eb22886a4a309bbdb128b325e7449ca7147 100644 (file)
@@ -30532,13 +30532,15 @@ times="0"@}
 @subsubheading Synopsis
 
 @smallexample
- -break-condition @var{number} @var{expr}
+ -break-condition [ --force ] @var{number} @var{expr}
 @end smallexample
 
 Breakpoint @var{number} will stop the program only if the condition in
 @var{expr} is true.  The condition becomes part of the
 @samp{-break-list} output (see the description of the @samp{-break-list}
-command below).
+command below).  If the @samp{--force} flag is passed, the condition
+is forcibly defined even when it is invalid for all locations of
+breakpoint @var{number}.
 
 @subsubheading @value{GDBN} Command
 
index c73548c2a40cc26e96832af022633ba49a016b79..5439937f66bc8530f16b8b4160652a81339eda3c 100644 (file)
@@ -386,6 +386,63 @@ mi_cmd_dprintf_insert (const char *command, char **argv, int argc)
   mi_cmd_break_insert_1 (1, command, argv, argc);
 }
 
+/* Implements the -break-condition command.
+   See the MI manual for the list of options.  */
+
+void
+mi_cmd_break_condition (const char *command, char **argv, int argc)
+{
+  enum option
+    {
+      FORCE_CONDITION_OPT,
+    };
+
+  static const struct mi_opt opts[] =
+  {
+    {"-force", FORCE_CONDITION_OPT, 0},
+    { 0, 0, 0 }
+  };
+
+  /* Parse arguments.  */
+  int oind = 0;
+  char *oarg;
+  bool force_condition = false;
+
+  while (true)
+    {
+      int opt = mi_getopt ("-break-condition", argc, argv,
+                          opts, &oind, &oarg);
+      if (opt < 0)
+       break;
+
+      switch (opt)
+       {
+       case FORCE_CONDITION_OPT:
+         force_condition = true;
+         break;
+       }
+    }
+
+  /* There must be at least two more args: a bpnum and a condition
+     expression.  */
+  if (oind + 1 >= argc)
+    error (_("-break-condition: Missing the <number> and/or <expr> "
+            "argument"));
+
+  int bpnum = atoi (argv[oind]);
+
+  /* The rest form the condition expr.  */
+  std::string expr (argv[oind + 1]);
+  for (int i = oind + 2; i < argc; ++i)
+    {
+      expr += " ";
+      expr += argv[i];
+    }
+
+  set_breakpoint_condition (bpnum, expr.c_str (), 0 /* from_tty */,
+                           force_condition);
+}
+
 enum wp_type
 {
   REG_WP,
index df4290ae5dcc05ac04763edb253b93df75e7fd5a..1ed8b6f91262676113820f9dbb94d6d7df8a1049 100644 (file)
@@ -45,8 +45,8 @@ static struct mi_cmd mi_cmds[] =
   DEF_MI_CMD_MI ("add-inferior", mi_cmd_add_inferior),
   DEF_MI_CMD_CLI_1 ("break-after", "ignore", 1,
                    &mi_suppress_notification.breakpoint),
-  DEF_MI_CMD_CLI_1 ("break-condition","cond", 1,
-                 &mi_suppress_notification.breakpoint),
+  DEF_MI_CMD_MI_1 ("break-condition", mi_cmd_break_condition,
+                  &mi_suppress_notification.breakpoint),
   DEF_MI_CMD_MI_1 ("break-commands", mi_cmd_break_commands,
                   &mi_suppress_notification.breakpoint),
   DEF_MI_CMD_CLI_1 ("break-delete", "delete breakpoint", 1,
index 4c05a4734a83ed802a09df0a8ad60ebfba054e3f..8da2e3939197d8c4e74d531e7acea25fafb4fdea 100644 (file)
@@ -36,6 +36,7 @@ extern mi_cmd_argv_ftype mi_cmd_ada_task_info;
 extern mi_cmd_argv_ftype mi_cmd_add_inferior;
 extern mi_cmd_argv_ftype mi_cmd_break_insert;
 extern mi_cmd_argv_ftype mi_cmd_dprintf_insert;
+extern mi_cmd_argv_ftype mi_cmd_break_condition;
 extern mi_cmd_argv_ftype mi_cmd_break_commands;
 extern mi_cmd_argv_ftype mi_cmd_break_passcount;
 extern mi_cmd_argv_ftype mi_cmd_break_watch;
index 7de5a0d49879613e4f05abe83c5757cdbce04466..50526da45ef904ac6765fa76dcd2a2414e0ed53c 100644 (file)
@@ -1,3 +1,8 @@
+2021-05-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
+
+       * gdb.mi/mi-break.exp (test_forced_conditions): Add a test
+       for the -break-condition command's "--force" flag.
+
 2021-05-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
 
        * gdb.mi/mi-break.exp (test_forced_conditions): New proc that
index 3b264ecdebd206b1f37b236c1751133deb3355e6..b6ef34830047b62f698cf21358e5358d4dbec078 100644 (file)
@@ -424,6 +424,17 @@ proc_with_prefix test_forced_conditions {} {
     mi_gdb_test "-dprintf-insert -c bad --force-condition callme \"Hello\"" \
         "${warning}\\^done,$bp" \
         "dprintf with forced condition"
+
+    # Define a plain breakpoint first, and a condition later.
+    mi_create_breakpoint "callme" "define a bp" ""
+    mi_gdb_test "-break-condition --force 16 bad == 42" \
+        "${warning}\\^done" \
+        "invalid condition is forced"
+    set args [list -cond "bad == 42" -locations "\\\[$loc\\\]"]
+    set bp [eval mi_make_breakpoint_multi $args]
+    mi_gdb_test "-break-info 16" \
+       "\\^done,[mi_make_breakpoint_table [list $bp]]" \
+        "invalid condition is defined"
 }
 
 proc test_break {mi_mode} {