From 79aabb7308cd572fff21da5c93952a1bb0dc5b26 Mon Sep 17 00:00:00 2001 From: Tankut Baris Aktemur Date: Thu, 6 May 2021 10:13:06 +0200 Subject: [PATCH] gdb/mi: add a '--force' flag to the '-break-condition' command Add a '--force' flag to the '-break-condition' command to be able to force conditions. gdb/ChangeLog: 2021-05-06 Tankut Baris Aktemur * 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 * 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 * gdb.texinfo (GDB/MI Breakpoint Commands): Mention the '--force' flag of the '-break-condition' command. --- gdb/ChangeLog | 13 +++++++ gdb/NEWS | 7 ++++ gdb/breakpoint.c | 59 ++++++++++++++++++------------- gdb/breakpoint.h | 8 +++++ gdb/doc/ChangeLog | 5 +++ gdb/doc/gdb.texinfo | 6 ++-- gdb/mi/mi-cmd-break.c | 57 +++++++++++++++++++++++++++++ gdb/mi/mi-cmds.c | 4 +-- gdb/mi/mi-cmds.h | 1 + gdb/testsuite/ChangeLog | 5 +++ gdb/testsuite/gdb.mi/mi-break.exp | 11 ++++++ 11 files changed, 147 insertions(+), 29 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 87f366c4b68..14b1a3d0c8f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2021-05-06 Tankut Baris Aktemur + + * 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 * mi/mi-cmd-break.c (mi_cmd_break_insert_1): Recognize the diff --git a/gdb/NEWS b/gdb/NEWS index a814b41315d..784c1038920 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -39,6 +39,13 @@ 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 diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 9cc53f8ef54..35a891bb4b9 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -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 diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 3447e25da20..54c5e423e10 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -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); diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 85c09900185..d64504f1ffc 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2021-05-06 Tankut Baris Aktemur + + * gdb.texinfo (GDB/MI Breakpoint Commands): Mention the + '--force' flag of the '-break-condition' command. + 2021-05-06 Tankut Baris Aktemur * gdb.texinfo (GDB/MI Breakpoint Commands): Mention the diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index b7667f7d11e..56f37eb2288 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -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 diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c index c73548c2a40..5439937f66b 100644 --- a/gdb/mi/mi-cmd-break.c +++ b/gdb/mi/mi-cmd-break.c @@ -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 and/or " + "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, diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index df4290ae5dc..1ed8b6f9126 100644 --- a/gdb/mi/mi-cmds.c +++ b/gdb/mi/mi-cmds.c @@ -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, diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h index 4c05a4734a8..8da2e393919 100644 --- a/gdb/mi/mi-cmds.h +++ b/gdb/mi/mi-cmds.h @@ -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; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 7de5a0d4987..50526da45ef 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2021-05-06 Tankut Baris Aktemur + + * 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 * gdb.mi/mi-break.exp (test_forced_conditions): New proc that diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp index 3b264ecdebd..b6ef3483004 100644 --- a/gdb/testsuite/gdb.mi/mi-break.exp +++ b/gdb/testsuite/gdb.mi/mi-break.exp @@ -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} { -- 2.30.2