diff --git a/gdb/ChangeLog b/gdb/ChangeLog index c2cb13c97a..85bf5a96ba 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,22 @@ +2019-03-13 Simon Marchi + + * NEWS: Mention that the new default MI version is 3. Mention + changes to the output of commands and events that deal with + multi-location breakpoints. + * breakpoint.c: Include "mi/mi-out.h". + (print_one_breakpoint): Change output syntax if using MI version + >= 3. + * mi/mi-main.h (mi_cmd_fix_multi_location_breakpoint_output): + New. + (mi_multi_location_breakpoint_output_fixed): New. + * mi/mi-main.c (fix_multi_location_breakpoint_output): New. + (mi_cmd_fix_multi_location_breakpoint_output): New. + (mi_multi_location_breakpoint_output_fixed): New. + * mi/mi-cmds.c (mi_cmds): Register command + -fix-multi-location-breakpoint-output. + * mi/mi-out.c (mi_out_new): Instantiate version 3 when using + interpreter "mi". + 2019-03-13 Simon Marchi * mi/mi-out.h (mi_out_new): Change parameter to const char *. diff --git a/gdb/NEWS b/gdb/NEWS index 88ce9a7104..53d1c6e248 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -162,6 +162,8 @@ set style address intensity VALUE * MI changes + ** The default version of the MI interpreter is now 3 (-i=mi3). + ** The '-data-disassemble' MI command now accepts an '-a' option to disassemble the whole function surrounding the given program counter value or function name. Support for this feature can be @@ -171,6 +173,18 @@ set style address intensity VALUE ** Command responses and notifications that include a frame now include the frame's architecture in a new "arch" attribute. + ** The output of information about multi-location breakpoints (which is + syntactically incorrect in MI 2) has changed in MI 3. This affects + the following commands and events: + + - -break-insert + - -break-info + - =breakpoint-created + - =breakpoint-modified + + The -fix-multi-location-breakpoint-output command can be used to enable + this behavior with previous MI versions. + * New native configurations GNU/Linux/RISC-V riscv*-*-linux* diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 9be99ff4ef..dd122be35b 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -69,6 +69,7 @@ #include "thread-fsm.h" #include "tid-parse.h" #include "cli/cli-style.h" +#include "mi/mi-main.h" /* readline include files */ #include "readline/readline.h" @@ -6361,12 +6362,15 @@ print_one_breakpoint (struct breakpoint *b, int allflag) { struct ui_out *uiout = current_uiout; + bool use_fixed_output = mi_multi_location_breakpoint_output_fixed (uiout); - { - ui_out_emit_tuple tuple_emitter (uiout, "bkpt"); + gdb::optional bkpt_tuple_emitter (gdb::in_place, uiout, "bkpt"); + print_one_breakpoint_location (b, NULL, 0, last_loc, allflag); - print_one_breakpoint_location (b, NULL, 0, last_loc, allflag); - } + /* The mi2 broken format: the main breakpoint tuple ends here, the locations + are outside. */ + if (!use_fixed_output) + bkpt_tuple_emitter.reset (); /* If this breakpoint has custom print function, it's already printed. Otherwise, print individual @@ -6384,12 +6388,18 @@ print_one_breakpoint (struct breakpoint *b, && !is_hardware_watchpoint (b) && (b->loc->next || !b->loc->enabled)) { - struct bp_location *loc; - int n = 1; + gdb::optional locations_list; - for (loc = b->loc; loc; loc = loc->next, ++n) + /* For MI version <= 2, keep the behavior where GDB outputs an invalid + MI record. For later versions, place breakpoint locations in a + list. */ + if (uiout->is_mi_like_p () && use_fixed_output) + locations_list.emplace (uiout, "locations"); + + int n = 1; + for (bp_location *loc = b->loc; loc != NULL; loc = loc->next, ++n) { - ui_out_emit_tuple tuple_emitter (uiout, NULL); + ui_out_emit_tuple loc_tuple_emitter (uiout, NULL); print_one_breakpoint_location (b, loc, n, last_loc, allflag); } } diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 0380322dfe..81512fa98c 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,12 @@ +2019-03-13 Simon Marchi + + * gdb.texinfo (Mode Options): Mention mi3. + (Interpreters): Likewise. + (GDB/MI Development and Front Ends): Add entry for MI 3 in + version table. Document -fix-multi-location-breakpoint-output. + (GDB/MI Breakpoint Information): Document format of breakpoint + location output. + 2019-03-05 Simon Marchi * python.texi (Values From Inferior): Change synopsys of the diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index f2028f86b0..20f6122ce1 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -1268,12 +1268,12 @@ program or device. This option is meant to be set by programs which communicate with @value{GDBN} using it as a back end. @xref{Interpreters, , Command Interpreters}. -@samp{--interpreter=mi} (or @samp{--interpreter=mi2}) causes -@value{GDBN} to use the @dfn{@sc{gdb/mi} interface} (@pxref{GDB/MI, , -The @sc{gdb/mi} Interface}) included since @value{GDBN} version 6.0. The -previous @sc{gdb/mi} interface, included in @value{GDBN} version 5.3 and -selected with @samp{--interpreter=mi1}, is deprecated. Earlier -@sc{gdb/mi} interfaces are no longer supported. +@samp{--interpreter=mi} (or @samp{--interpreter=mi3}) causes +@value{GDBN} to use the @dfn{@sc{gdb/mi} interface} version 3 (@pxref{GDB/MI, , +The @sc{gdb/mi} Interface}) included since @value{GDBN} version 9.1. @sc{gdb/mi} +version 2 (@code{mi2}), included in @value{GDBN} 6.0 and version 1 (@code{mi1}), +included in @value{GDBN} 5.3, are also available. Earlier @sc{gdb/mi} +interfaces are no longer supported. @item -write @cindex @code{--write} @@ -26506,18 +26506,22 @@ used interpreter with @value{GDBN}. With no interpreter specified at runtime, @item mi @cindex mi interpreter -The newest @sc{gdb/mi} interface (currently @code{mi2}). Used primarily +The newest @sc{gdb/mi} interface (currently @code{mi3}). Used primarily by programs wishing to use @value{GDBN} as a backend for a debugger GUI or an IDE. For more information, see @ref{GDB/MI, ,The @sc{gdb/mi} Interface}. +@item mi3 +@cindex mi3 interpreter +The @sc{gdb/mi} interface introduced in @value{GDBN} 9.1. + @item mi2 @cindex mi2 interpreter -The current @sc{gdb/mi} interface. +The @sc{gdb/mi} interface introduced in @value{GDBN} 6.0. @item mi1 @cindex mi1 interpreter -The @sc{gdb/mi} interface included in @value{GDBN} 5.1, 5.2, and 5.3. +The @sc{gdb/mi} interface introduced in @value{GDBN} 5.1. @end table @@ -27839,8 +27843,36 @@ than a tuple. a tuple. @end itemize +@item +@center 3 +@tab +@center 9.1 +@tab + +@itemize +@item +The output of information about multi-location breakpoints has changed in the +responses to the @code{-break-insert} and @code{-break-info} commands, as well +as in the @code{=breakpoint-created} and @code{=breakpoint-modified} events. +The multiple locations are now placed in a @code{locations} field, whose value +is a list. +@end itemize + @end multitable +If your front end cannot yet migrate to a more recent version of the +MI protocol, you can nevertheless selectively enable specific features +available in those recent MI versions, using the following commands: + +@table @code + +@item -fix-multi-location-breakpoint-output +Use the output for multi-location breakpoints which was introduced by +MI 3, even when using MI versions 2 or 1. This command has no +effect when using MI version 3 or later. + +@end @table + The best way to avoid unexpected changes in MI that might break your front end is to make your project known to @value{GDBN} developers and follow development on @email{gdb@@sourceware.org} and @@ -28169,9 +28201,7 @@ following fields: @table @code @item number -The breakpoint number. For a breakpoint that represents one location -of a multi-location breakpoint, this will be a dotted pair, like -@samp{1.2}. +The breakpoint number. @item type The type of the breakpoint. For ordinary breakpoints this will be @@ -28271,6 +28301,52 @@ is not. @item what Some extra data, the exact contents of which are type-dependent. +@item locations +This field is present if the breakpoint has multiple locations. It is also +exceptionally present if the breakpoint is enabled and has a single, disabled +location. + +The value is a list of locations. The format of a location is decribed below. + +@end table + +A location in a multi-location breakpoint is represented as a tuple with the +following fields: + +@table @code + +@item number +The location number as a dotted pair, like @samp{1.2}. The first digit is the +number of the parent breakpoint. The second digit is the number of the +location within that breakpoint. + +@item enabled +This indicates whether the location is enabled, in which case the +value is @samp{y}, or disabled, in which case the value is @samp{n}. +Note that this is not the same as the field @code{enable}. + +@item addr +The address of this location as an hexidecimal number. + +@item func +If known, the function in which the location appears. +If not known, this field is not present. + +@item file +The name of the source file which contains this location, if known. +If not known, this field is not present. + +@item fullname +The full file name of the source file which contains this location, if +known. If not known, this field is not present. + +@item line +The line number at which this location appears, if known. +If not known, this field is not present. + +@item thread-groups +The thread groups this location is in. + @end table For example, here is what the output of @code{-break-insert} diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index bb7c20c777..fe30ac2e82 100644 --- a/gdb/mi/mi-cmds.c +++ b/gdb/mi/mi-cmds.c @@ -118,6 +118,8 @@ static struct mi_cmd mi_cmds[] = DEF_MI_CMD_MI ("file-list-shared-libraries", mi_cmd_file_list_shared_libraries), DEF_MI_CMD_CLI ("file-symbol-file", "symbol-file", 1), + DEF_MI_CMD_MI ("fix-multi-location-breakpoint-output", + mi_cmd_fix_multi_location_breakpoint_output), DEF_MI_CMD_MI ("gdb-exit", mi_cmd_gdb_exit), DEF_MI_CMD_CLI_1 ("gdb-set", "set", 1, &mi_suppress_notification.cmd_param_changed), diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index f4e5e48bc2..0655985174 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -2701,6 +2701,33 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc) } } +/* Whether to use the fixed output when printing information about a + multi-location breakpoint (see PR 9659). */ + +static bool fix_multi_location_breakpoint_output = false; + +/* See mi/mi-main.h. */ + +void +mi_cmd_fix_multi_location_breakpoint_output (const char *command, char **argv, + int argc) +{ + fix_multi_location_breakpoint_output = true; +} + +/* See mi/mi-main.h. */ + +bool +mi_multi_location_breakpoint_output_fixed (ui_out *uiout) +{ + mi_ui_out *mi_uiout = dynamic_cast (uiout); + + if (mi_uiout == nullptr) + return false; + + return mi_uiout->version () >= 3 || fix_multi_location_breakpoint_output; +} + void _initialize_mi_main (void) { diff --git a/gdb/mi/mi-main.h b/gdb/mi/mi-main.h index 72ddab9427..72c4e59428 100644 --- a/gdb/mi/mi-main.h +++ b/gdb/mi/mi-main.h @@ -54,4 +54,17 @@ struct mi_suppress_notification }; extern struct mi_suppress_notification mi_suppress_notification; +/* Implementation of -fix-multi-location-breakpoint-output. */ + +extern void mi_cmd_fix_multi_location_breakpoint_output (const char *command, + char **argv, int argc); + +/* Return whether -break-list, -break-insert, =breakpoint-created and + =breakpoint-modified should use the "fixed" output format (see PR + 9659). + + Return false if UIOUT is not an MI UI. */ + +extern bool mi_multi_location_breakpoint_output_fixed (ui_out *uiout); + #endif /* MI_MI_MAIN_H */ diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c index 4f8c9bff8e..e485beef69 100644 --- a/gdb/mi/mi-out.c +++ b/gdb/mi/mi-out.c @@ -297,10 +297,10 @@ mi_ui_out::~mi_ui_out () mi_ui_out * mi_out_new (const char *mi_version) { - if (streq (mi_version, INTERP_MI3)) + if (streq (mi_version, INTERP_MI3) || streq (mi_version, INTERP_MI)) return new mi_ui_out (3); - if (streq (mi_version, INTERP_MI2) || streq (mi_version, INTERP_MI)) + if (streq (mi_version, INTERP_MI2)) return new mi_ui_out (2); if (streq (mi_version, INTERP_MI1)) diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 15fbbe1b47..037f561595 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-03-13 Simon Marchi + + * mi-breakpoint-location-ena-dis.exp: Rename to ... + * mi-breakpoint-multiple-locations.exp: ... this. + (make_breakpoints_pattern): New proc. + (do_test): Add mi_version parameter, test -break-insert, + -break-info and =breakpoint-created. + 2019-03-12 Andrew Burgess * config/default.exp: Remove 'load_lib gdb.exp'. diff --git a/gdb/testsuite/gdb.mi/mi-breakpoint-location-ena-dis.exp b/gdb/testsuite/gdb.mi/mi-breakpoint-location-ena-dis.exp deleted file mode 100644 index eb781490fe..0000000000 --- a/gdb/testsuite/gdb.mi/mi-breakpoint-location-ena-dis.exp +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2018-2019 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Tests whether =breakpoint=modified notification is sent when a single -# breakpoint location is enabled or disabled via CLI. - -load_lib mi-support.exp -set MIFLAGS "-i=mi" - -gdb_exit -if {[mi_gdb_start]} { - continue -} - -# -# Start here -# -standard_testfile .cc - -if {[gdb_compile "$srcdir/$subdir/$srcfile" $binfile executable {debug c++}] != "" } { - return -1 -} - -mi_run_to_main - -mi_gdb_test "break add" \ - {(&.*)*.*~"Breakpoint 2 at.*\\n".*=breakpoint-created,bkpt=\{number="2",type="breakpoint".*\},\{number="2.1",enabled="y".*\}.*\n\^done} \ - "break add" - -# Modify enableness through MI commands shouldn't trigger MI -# notification. -mi_gdb_test "-break-disable 2.2" "\\^done" "-break-disable 2.2" -mi_gdb_test "-break-enable 2.2" "\\^done" "-break-enable 2.2" - -# Modify enableness through CLI commands should trigger MI -# notification. -mi_gdb_test "dis 2.2" \ - {.*=breakpoint-modified,bkpt=\{number="2",type="breakpoint".*\},\{number="2.1",enabled="y".*\},\{number="2.2",enabled="n".*\}.*\n\^done} \ - "dis 2.2" -mi_gdb_test "en 2.2" \ - {.*=breakpoint-modified,bkpt=\{number="2",type="breakpoint".*\},\{number="2.1",enabled="y".*\},\{number="2.2",enabled="y".*\}.*\n\^done} \ - "en 2.2" - -mi_gdb_exit diff --git a/gdb/testsuite/gdb.mi/mi-breakpoint-location-ena-dis.cc b/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.cc similarity index 100% rename from gdb/testsuite/gdb.mi/mi-breakpoint-location-ena-dis.cc rename to gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.cc diff --git a/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp b/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp new file mode 100644 index 0000000000..4fb8948801 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp @@ -0,0 +1,131 @@ +# Copyright 2018-2019 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Tests various things related to breakpoints with multiple locations. + +load_lib mi-support.exp +standard_testfile .cc + +if {[gdb_compile "$srcdir/$subdir/$srcfile" $binfile executable {debug c++}] != "" } { + return -1 +} + +# Generate the regexp pattern used to match the breakpoint description emitted +# in the various breakpoint command results/events. +# +# - EXPECT_FIXED_OUTPUT: If true (non-zero), we expect GDB to output the fixed +# output for multi-locations breakpoint, else we expect it to output the +# broken pre-mi3 format. +# - BP_NUM is the expected breakpoint number +# - LOC1_EN and LOC2_EN are the expected value of the enabled field, for the +# two locations. + + +proc make_breakpoints_pattern { expect_fixed_output bp_num loc1_en loc2_en } { + if $expect_fixed_output { + return "bkpt=\{number=\"${bp_num}\",type=\"breakpoint\",.*,locations=\\\[\{number=\"${bp_num}\\.1\",enabled=\"${loc1_en}\",.*\},\{number=\"${bp_num}\\.2\",enabled=\"${loc2_en}\",.*\}\\\]\}" + } else { + return "bkpt=\{number=\"${bp_num}\",type=\"breakpoint\",.*\},\{number=\"${bp_num}\\.1\",enabled=\"${loc1_en}\",.*\},\{number=\"${bp_num}\\.2\",enabled=\"${loc2_en}\",.*\}" + } +} + +# Run the test with the following parameters: +# +# - MI_VERSION: the version of the MI interpreter to use (e.g. "2") +# - USE_FIX_FLAG: Whether to issue the -fix-multi-location-breakpoint-output +# command after starting GDB +# - EXPECT_FIXED_OUTPUT: If true (non-zero), we expect GDB to output the fixed +# output for multi-locations breakpoint, else we expect it to output the +# broken pre-mi3 format. + +proc do_test { mi_version use_fix_flag expect_fixed_output } { + with_test_prefix "mi_version=${mi_version}" { + with_test_prefix "use_fix_flag=${use_fix_flag}" { + global MIFLAGS decimal + set MIFLAGS "-i=mi${mi_version}" + + gdb_exit + if {[mi_gdb_start]} { + return + } + + mi_run_to_main + + if $use_fix_flag { + mi_gdb_test "-fix-multi-location-breakpoint-output" "\\^done" \ + "send -fix-multi-location-breakpoint-output" + } + + # Check the breakpoint-created event. + set pattern [make_breakpoints_pattern $expect_fixed_output 2 y y] + mi_gdb_test "break add" \ + [multi_line "&\"break add\\\\n\"" \ + "~\"Breakpoint ${decimal} at.*\\(2 locations\\)\\\\n\"" \ + "=breakpoint-created,${pattern}" \ + "\\^done" ] \ + "break add" + + # Check the -break-info output. + mi_gdb_test "-break-info" \ + "\\^done,BreakpointTable=\{.*,body=\\\[${pattern}\\\]\}" \ + "-break-info" + + # Check the -break-insert response. + set pattern [make_breakpoints_pattern $expect_fixed_output 3 y y] + mi_gdb_test "-break-insert add" "\\^done,${pattern}" "insert breakpoint with MI command" + + # Modify enableness through MI commands shouldn't trigger MI + # notification. + mi_gdb_test "-break-disable 2.2" "\\^done" "-break-disable 2.2" + mi_gdb_test "-break-enable 2.2" "\\^done" "-break-enable 2.2" + + # Modify enableness through CLI commands should trigger MI + # notification. + set pattern [make_breakpoints_pattern $expect_fixed_output 2 y n] + mi_gdb_test "dis 2.2" \ + [multi_line "&\"dis 2.2\\\\n\"" \ + "=breakpoint-modified,${pattern}" \ + "\\^done" ] \ + "dis 2.2" + set pattern [make_breakpoints_pattern $expect_fixed_output 2 y y] + mi_gdb_test "en 2.2" \ + [multi_line "&\"en 2.2\\\\n\"" \ + "=breakpoint-modified,${pattern}" \ + "\\^done" ] \ + "en 2.2" + + mi_gdb_exit + } + } +} + +# Vanilla mi2 +do_test 2 0 0 + +# mi2 with -fix-multi-location-breakpoint-output +do_test 2 1 1 + +# Vanilla mi3 +do_test 3 0 1 + +# mi3 with -fix-multi-location-breakpoint-output +do_test 3 1 1 + +# Whatever MI version is currently the default one, vanilla +do_test "" 0 1 + +# Whatever MI version is currently the default one, with +# -fix-multi-location-breakpoint-output +do_test "" 1 1