From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by sourceware.org (Postfix) with ESMTPS id 94E45385828B for ; Tue, 4 Oct 2022 09:08:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 94E45385828B Received: by mail-ej1-x62d.google.com with SMTP id 13so27473249ejn.3 for ; Tue, 04 Oct 2022 02:08:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date; bh=zFgfWsv8Sl9aVOLyj3cxYofrM7dCKxN436zWp4D+GDM=; b=rmagv9kvSWLNvLOd8XPOJ7c/w8MtcWLSmUBkkZnAHgDGXGWny3Pl06Z8OtTxlqzIWA PCqx6SfVYmNjiHRFwUKDBklEh3I129a27EiDnfqLYjC3Vv4q48ZBEyIpdRl2q6mUjGBO +JI0VoDOMagQSYvh7vj+eHsJXpB7F7NNO5L6iSBtgbiuBznEV7UxQcq9onHFzKw1TJHS sHHeWyoS3rJIB+/7r+/qScyHWYqYA1wOmjFHQs/b9hKrTsyJNMpXpfh/Q33V4zSIv+VW OqFyzzU1rE8CjiIqFSUJRYkmSWWXmMi6O/pO9JkOENytSUEC4SUtmxsxa1O99OxX7RMS /dqw== X-Gm-Message-State: ACrzQf2Mwgklo6TJ8+oYAMt4y5MzLm+b0JcZ+46JjF4ktCzC245cf75p 2c1MYabOwf5EJDMSKqgqGGsdWTuCu0ruwiivZNqRu+0uX9zqxoRI X-Google-Smtp-Source: AMsMyM4iWVCTDrbp+H9nlR/NzcWj/pBaY4ylYUY2eXqIZBrVYMzqb04Irm9ZDw/BT6ypuvWHRwtbEhREpTRbk8ILoBw= X-Received: by 2002:a17:907:3fa9:b0:782:ed33:df8d with SMTP id hr41-20020a1709073fa900b00782ed33df8dmr18618213ejc.745.1664874518049; Tue, 04 Oct 2022 02:08:38 -0700 (PDT) MIME-Version: 1.0 References: <20220909080135.22921-1-grees@undo.io> <20220926124629.174047-1-grees@undo.io> In-Reply-To: <20220926124629.174047-1-grees@undo.io> From: Gareth Rees Date: Tue, 4 Oct 2022 10:08:26 +0100 Message-ID: Subject: [PING] [PATCH v4] [PR mi/29554] New PRINT-VALUES option '--scalar-values'. To: gdb-patches@sourceware.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 Oct 2022 09:10:14 -0000 Thanks to Andrew Burgess and Eli Zaretskii for reviewing. I've addressed all the comments, so let me know how I can help progress this patch. On Mon, 26 Sept 2022 at 13:46, Gareth Rees wrote: > > SUMMARY > > The '--simple-values' argument to '-stack-list-arguments' and similar > GDB/MI commands does not take reference types into account, so that > references to arbitrarily large structures are considered "simple" and > printed. This means that the '--simple-values' argument cannot be used > by IDEs when tracing the stack due to the time taken to print large > structures passed by reference. > > DETAILS > > Various GDB/MI commands ('-stack-list-arguments', '-stack-list-locals', > '-stack-list-variables' and so on) take a PRINT-VALUES argument which > may be '--no-values' (0), '--all-values' (1) or '--simple-values' (2). > In the '--simple-values' case, the command is supposed to print the > name, type, and value of variables with simple types, and print only the > name and type of variables with compound types. > > The '--simple-values' argument ought to be suitable for IDEs that need > to update their user interface with the program's call stack every time > the program stops. However, it does not take C++ reference types into > account, and this makes the argument unsuitable for this purpose. > > For example, consider the following C++ program: > > struct s { > int v[10]; > }; > > int > sum(const struct s &s) > { > int total =3D 0; > for (int i =3D 0; i < 10; ++i) total +=3D s.v[i]; > return total; > } > > int > main(void) > { > struct s s =3D { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } }; > return sum(s); > } > > If we start GDB in MI mode and continue to 'sum', the behaviour of > '-stack-list-arguments' is as follows: > > (gdb) > -stack-list-arguments --simple-values > ^done,stack-args=3D[frame=3D{level=3D"0",args=3D[{name=3D"s",type=3D"= const s &",value=3D"@0x7fffffffe310: {v =3D {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}= }"}]},frame=3D{level=3D"1",args=3D[]}] > > Note that the value of the argument 's' was printed, even though 's' is > a reference to a structure, which is not a simple value. > > See https://github.com/microsoft/MIEngine/pull/673 for a case where this > behaviour caused Microsoft to avoid the use of '--simple-values' in > their MIEngine debug adapter, because it caused Visual Studio Code to > take too long to refresh the call stack in the user interface. > > SOLUTIONS > > There are two ways we could fix this problem, depending on whether we > consider the current behaviour to be a bug that can be fixed. > > 1. If the current behaviour is a bug that can be fixed, then we can > update the behaviour of '--simple-values' so that it takes > reference types into account: that is, a value is simple if it is > neither an array, struct, or union, nor a reference to an array, > struct or union. > > In this case we must add a feature to the '-list-features' command so > that IDEs can detect that it is safe to use the '--simple-values' > argument when refreshing the call stack. > > 2. If the current behaviour is not a bug, or cannot be changed due to > backwards compatibility concerns, then we can add a new option for > the PRINT-VALUES argument, for example, '--scalar-values' (3), that > would be suitable for use by IDEs. > > In this case we must add a feature to the '-list-features' command so > that IDEs can detect that the '--scalar-values' argument is > available for use when refreshing the call stack. > > PATCH > > This patch implements solution (2), adding a '--scalar-values' option > for the PRINT-VALUES argument to '-stack-list-arguments' and similar > commands. This option prints the value only for scalars and so matches > the behaviour of the 'scalars' argument to the 'set print > frame-arguments' command. References to structures are not scalars, > and so the option is suitable for use by IDEs. > > Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=3D29554 > --- > gdb/NEWS | 9 +++ > gdb/doc/gdb.texinfo | 59 ++++++++++++-------- > gdb/extension.h | 3 + > gdb/mi/mi-cmd-stack.c | 35 ++++++++---- > gdb/mi/mi-cmd-var.c | 26 ++++++--- > gdb/mi/mi-cmds.h | 8 ++- > gdb/mi/mi-main.c | 54 ++++++++++-------- > gdb/mi/mi-parse.c | 8 ++- > gdb/python/py-framefilter.c | 23 ++++---- > gdb/testsuite/gdb.mi/mi-stack.exp | 17 +++++- > gdb/testsuite/gdb.mi/print-scalar-values.cc | 58 +++++++++++++++++++ > gdb/testsuite/gdb.mi/print-scalar-values.exp | 51 +++++++++++++++++ > 12 files changed, 272 insertions(+), 79 deletions(-) > create mode 100644 gdb/testsuite/gdb.mi/print-scalar-values.cc > create mode 100644 gdb/testsuite/gdb.mi/print-scalar-values.exp > > diff --git a/gdb/NEWS b/gdb/NEWS > index dee0ac2ecd8..62b15094dee 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -114,6 +114,15 @@ maintenance info line-table > entry corresponds to an address where a breakpoint should be placed > to be at the first instruction past a function's prologue. > > +* MI changes > + > + ** The '-stack-list-arguments', '-stack-list-locals', > + '-stack-list-variables', and '-var-list-children' commands > + support the '--scalar-values' option, which requests the command > + to print values only for scalar types. Support for this feature > + can be verified by using the '-list-features' command, which > + should contain "scalar-values". > + > * New targets > > GNU/Linux/LoongArch (gdbserver) loongarch*-*-linux* > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > index 238a49b027d..b2b53de1022 100644 > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -33326,12 +33326,14 @@ larger than the actual number of frames. On th= e other hand, > @var{high-frame} may be larger than the actual number of frames, in > which case only existing frames will be returned. > > -If @var{print-values} is 0 or @code{--no-values}, print only the names o= f > -the variables; if it is 1 or @code{--all-values}, print also their > -values; and if it is 2 or @code{--simple-values}, print the name, > -type and value for simple data types, and the name and type for arrays, > -structures and unions. If the option @code{--no-frame-filters} is > -supplied, then Python frame filters will not be executed. > +If @var{print-values} is 0 or @code{--no-values}, print only the names > +of the variables; if it is 1 or @code{--all-values}, print also their > +values; if it is 2 or @code{--simple-values}, print the name, type and > +value for simple data types, and the name and type for arrays, > +structures and unions; and if it is 3 or @code{--scalar-values}, print > +the name, type and value for scalar data types, and the name and type > +otherwise. If the option @code{--no-frame-filters} is supplied, then > +Python frame filters will not be executed. > > If the @code{--skip-unavailable} option is specified, arguments that > are not available are not listed. Partially available arguments > @@ -33549,13 +33551,15 @@ Show a single frame: > Display the local variable names for the selected frame. If > @var{print-values} is 0 or @code{--no-values}, print only the names of > the variables; if it is 1 or @code{--all-values}, print also their > -values; and if it is 2 or @code{--simple-values}, print the name, > -type and value for simple data types, and the name and type for arrays, > -structures and unions. In this last case, a frontend can immediately > -display the value of simple data types and create variable objects for > -other data types when the user wishes to explore their values in > -more detail. If the option @code{--no-frame-filters} is supplied, then > -Python frame filters will not be executed. > +values; if it is 2 or @code{--simple-values}, print the name, type and > +value for simple data types, and the name and type for arrays, > +structures and unions; and if it is 3 or @code{--scalar-values}, print > +the name, type and value for scalar data types, and the name and type > +otherwise. In the last two cases, a frontend can immediately display > +the value of simple or scalar data types and create variable objects > +for other data types when the user wishes to explore their values in > +more detail. If the option @code{--no-frame-filters} is supplied, > +then Python frame filters will not be executed. > > If the @code{--skip-unavailable} option is specified, local variables > that are not available are not listed. Partially available local > @@ -33594,13 +33598,16 @@ This command is deprecated in favor of the > -stack-list-variables [ --no-frame-filters ] [ --skip-unavailable ] @va= r{print-values} > @end smallexample > > -Display the names of local variables and function arguments for the sele= cted frame. If > -@var{print-values} is 0 or @code{--no-values}, print only the names of > -the variables; if it is 1 or @code{--all-values}, print also their > -values; and if it is 2 or @code{--simple-values}, print the name, > -type and value for simple data types, and the name and type for arrays, > -structures and unions. If the option @code{--no-frame-filters} is > -supplied, then Python frame filters will not be executed. > +Display the names of local variables and function arguments for the > +selected frame. If @var{print-values} is 0 or @code{--no-values}, > +print only the names of the variables; if it is 1 or > +@code{--all-values}, print also their values; if it is 2 or > +@code{--simple-values}, print the name, type and value for simple data > +types, and the name and type for arrays, structures and unions; and if > +it is 3 or @code{--scalar-values}, print the name, type and value for > +scalar data types, and the name and type otherwise. If the option > +@code{--no-frame-filters} is supplied, then Python frame filters will > +not be executed. > > If the @code{--skip-unavailable} option is specified, local variables > and arguments that are not available are not listed. Partially > @@ -34029,9 +34036,10 @@ create variable objects for them, if they do not= already exist. With > a single argument or if @var{print-values} has a value of 0 or > @code{--no-values}, print only the names of the variables; if > @var{print-values} is 1 or @code{--all-values}, also print their > -values; and if it is 2 or @code{--simple-values} print the name and > -value for simple data types and just the name for arrays, structures > -and unions. > +values; if it is 2 or @code{--simple-values} print the name and value > +for simple data types and just the name for arrays, structures and > +unions; and if it is 3 or @code{--scalar-values}, print the name and > +value for scalar data types, and just the name otherwise. > > @var{from} and @var{to}, if specified, indicate the range of children > to report. If @var{from} or @var{to} is less than zero, the range is > @@ -37295,6 +37303,11 @@ option (@pxref{GDB/MI Program Execution}). > @item data-disassemble-a-option > Indicates that the @code{-data-disassemble} command supports the @option= {-a} > option (@pxref{GDB/MI Data Manipulation}). > +@item scalar-values > +Indicates that the @code{-stack-list-arguments}, > +@code{-stack-list-locals}, @code{-stack-list-variables}, and > +@code{-var-list-children} commands support the > +@option{--scalar-values} option (@pxref{GDB/MI Stack Manipulation}). > @end ftable > > @subheading The @code{-list-target-features} Command > diff --git a/gdb/extension.h b/gdb/extension.h > index 47839ea50be..16d12f00f41 100644 > --- a/gdb/extension.h > +++ b/gdb/extension.h > @@ -121,6 +121,9 @@ enum ext_lang_frame_args > arguments when invoked from the MI. */ > MI_PRINT_SIMPLE_VALUES =3D PRINT_SIMPLE_VALUES, > > + /* Print only scalar values for arguments when invoked from the MI. = */ > + MI_PRINT_SCALAR_VALUES =3D PRINT_SCALAR_VALUES, > + > /* Print only scalar values for arguments when invoked from the CLI.= */ > CLI_SCALAR_VALUES, > > diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c > index 0fe204dbc66..d3ae350f166 100644 > --- a/gdb/mi/mi-cmd-stack.c > +++ b/gdb/mi/mi-cmd-stack.c > @@ -494,6 +494,7 @@ list_arg_or_local (const struct frame_arg *arg, enum = what_to_list what, > gdb_assert ((values =3D=3D PRINT_NO_VALUES && arg->val =3D=3D NULL > && arg->error =3D=3D NULL) > || values =3D=3D PRINT_SIMPLE_VALUES > + || values =3D=3D PRINT_SCALAR_VALUES > || (values =3D=3D PRINT_ALL_VALUES > && (arg->val !=3D NULL || arg->error !=3D NULL))); > gdb_assert (arg->entry_kind =3D=3D print_entry_values_no > @@ -525,7 +526,8 @@ list_arg_or_local (const struct frame_arg *arg, enum = what_to_list what, > if (what =3D=3D all && arg->sym->is_argument ()) > uiout->field_signed ("arg", 1); > > - if (values =3D=3D PRINT_SIMPLE_VALUES) > + if (values =3D=3D PRINT_SIMPLE_VALUES > + || values =3D=3D PRINT_SCALAR_VALUES) > { > check_typedef (arg->sym->type ()); > type_print (arg->sym->type (), "", &stb, -1); > @@ -557,6 +559,25 @@ list_arg_or_local (const struct frame_arg *arg, enum= what_to_list what, > } > } > > +/* Print SYM according to VALUES? */ > + > +static bool > +print_symbol_p (struct symbol *sym, enum print_values values) > +{ > + switch (values) > + { > + default: > + case PRINT_NO_VALUES: > + return false; > + case PRINT_ALL_VALUES: > + return true; > + case PRINT_SIMPLE_VALUES: > + return mi_simple_values_type_p (sym->type ()); > + case PRINT_SCALAR_VALUES: > + return val_print_scalar_type_p (sym->type ()); > + } > +} > + > /* Print a list of the objects for the frame FI in a certain form, > which is determined by VALUES. The objects can be locals, > arguments or both, which is determined by WHAT. If SKIP_UNAVAILABLE > @@ -571,7 +592,6 @@ list_args_or_locals (const frame_print_options &fp_op= ts, > const struct block *block; > struct symbol *sym; > struct block_iterator iter; > - struct type *type; > const char *name_of_result; > struct ui_out *uiout =3D current_uiout; > > @@ -647,21 +667,12 @@ list_args_or_locals (const frame_print_options &fp_= opts, > entryarg.sym =3D sym2; > entryarg.entry_kind =3D print_entry_values_no; > > - switch (values) > + if (print_symbol_p (sym, values)) > { > - case PRINT_SIMPLE_VALUES: > - type =3D check_typedef (sym2->type ()); > - if (type->code () !=3D TYPE_CODE_ARRAY > - && type->code () !=3D TYPE_CODE_STRUCT > - && type->code () !=3D TYPE_CODE_UNION) > - { > - case PRINT_ALL_VALUES: > if (sym->is_argument ()) > read_frame_arg (fp_opts, sym2, fi, &arg, &entryarg); > else > read_frame_local (sym2, fi, &arg); > - } > - break; > } > > if (arg.entry_kind !=3D print_entry_values_only) > diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c > index 3db09cf7815..064d13a3729 100644 > --- a/gdb/mi/mi-cmd-var.c > +++ b/gdb/mi/mi-cmd-var.c > @@ -32,6 +32,7 @@ > #include "mi-parse.h" > #include "gdbsupport/gdb_optional.h" > #include "inferior.h" > +#include "valprint.h" > > static void varobj_update_one (struct varobj *var, > enum print_values print_values, > @@ -334,15 +335,26 @@ mi_print_value_p (struct varobj *var, enum print_va= lues print_values) > type =3D varobj_get_gdb_type (var); > if (type =3D=3D NULL) > return 1; > + else if (print_values =3D=3D PRINT_SCALAR_VALUES) > + return val_print_scalar_type_p (type); > else > - { > - type =3D check_typedef (type); > + return mi_simple_values_type_p (type); > +} > + > +/* See mi-cmds.h. */ > > - /* For PRINT_SIMPLE_VALUES, only print the value if it has a type > - and that type is not a compound type. */ > - return (type->code () !=3D TYPE_CODE_ARRAY > - && type->code () !=3D TYPE_CODE_STRUCT > - && type->code () !=3D TYPE_CODE_UNION); > +bool > +mi_simple_values_type_p (struct type *type) > +{ > + type =3D check_typedef (type); > + switch (type->code ()) > + { > + case TYPE_CODE_ARRAY: > + case TYPE_CODE_STRUCT: > + case TYPE_CODE_UNION: > + return false; > + default: > + return true; > } > } > > diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h > index 9ffb11bf997..56c3ccb8b8a 100644 > --- a/gdb/mi/mi-cmds.h > +++ b/gdb/mi/mi-cmds.h > @@ -29,7 +29,8 @@ > enum print_values { > PRINT_NO_VALUES, > PRINT_ALL_VALUES, > - PRINT_SIMPLE_VALUES > + PRINT_SIMPLE_VALUES, > + PRINT_SCALAR_VALUES > }; > > typedef void (mi_cmd_argv_ftype) (const char *command, char **argv, int = argc); > @@ -226,4 +227,9 @@ using remove_mi_cmd_entries_ftype > =3D gdb::function_view; > extern void remove_mi_cmd_entries (remove_mi_cmd_entries_ftype callback)= ; > > +/* Return true if type is suitable for printing with PRINT_SIMPLE_VALUES= : that > + is, if type is not an array, structure or union. */ > + > +extern bool mi_simple_values_type_p (struct type *type); > + > #endif /* MI_MI_CMDS_H */ > diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c > index b758f398e2a..2e70bcde2da 100644 > --- a/gdb/mi/mi-main.c > +++ b/gdb/mi/mi-main.c > @@ -1663,6 +1663,7 @@ mi_cmd_list_features (const char *command, char **a= rgv, int argc) > uiout->field_string (NULL, "undefined-command-error-code"); > uiout->field_string (NULL, "exec-run-start-option"); > uiout->field_string (NULL, "data-disassemble-a-option"); > + uiout->field_string (NULL, "scalar-values"); > > if (ext_lang_initialized_p (get_ext_lang_defn (EXT_LANG_PYTHON))) > uiout->field_string (NULL, "python"); > @@ -2456,20 +2457,39 @@ mi_cmd_ada_task_info (const char *command, char *= *argv, int argc) > print_ada_task_info (current_uiout, argv[0], current_inferior ()); > } > > +/* Print VAL according to VALUES? */ > + > +static bool > +print_value_p (struct value *val, enum print_values values) > +{ > + switch (values) > + { > + default: > + case PRINT_NO_VALUES: > + return false; > + case PRINT_ALL_VALUES: > + return true; > + case PRINT_SIMPLE_VALUES: > + return mi_simple_values_type_p (value_type (val)); > + case PRINT_SCALAR_VALUES: > + return val_print_scalar_type_p (value_type (val)); > + } > +} > + > /* Print EXPRESSION according to VALUES. */ > > static void > print_variable_or_computed (const char *expression, enum print_values va= lues) > { > struct value *val; > - struct type *type; > struct ui_out *uiout =3D current_uiout; > > string_file stb; > > expression_up expr =3D parse_expression (expression); > > - if (values =3D=3D PRINT_SIMPLE_VALUES) > + if (values =3D=3D PRINT_SIMPLE_VALUES > + || values =3D=3D PRINT_SCALAR_VALUES) > val =3D evaluate_type (expr.get ()); > else > val =3D evaluate_expression (expr.get ()); > @@ -2482,31 +2502,19 @@ print_variable_or_computed (const char *expressio= n, enum print_values values) > switch (values) > { > case PRINT_SIMPLE_VALUES: > - type =3D check_typedef (value_type (val)); > + case PRINT_SCALAR_VALUES: > type_print (value_type (val), "", &stb, -1); > uiout->field_stream ("type", stb); > - if (type->code () !=3D TYPE_CODE_ARRAY > - && type->code () !=3D TYPE_CODE_STRUCT > - && type->code () !=3D TYPE_CODE_UNION) > - { > - struct value_print_options opts; > - > - get_no_prettyformat_print_options (&opts); > - opts.deref_ref =3D 1; > - common_val_print (val, &stb, 0, &opts, current_language); > - uiout->field_stream ("value", stb); > - } > break; > - case PRINT_ALL_VALUES: > - { > - struct value_print_options opts; > + } > > - get_no_prettyformat_print_options (&opts); > - opts.deref_ref =3D 1; > - common_val_print (val, &stb, 0, &opts, current_language); > - uiout->field_stream ("value", stb); > - } > - break; > + if (print_value_p (val, values)) > + { > + struct value_print_options opts; > + get_no_prettyformat_print_options (&opts); > + opts.deref_ref =3D 1; > + common_val_print (val, &stb, 0, &opts, current_language); > + uiout->field_stream ("value", stb); > } > } > > diff --git a/gdb/mi/mi-parse.c b/gdb/mi/mi-parse.c > index dfa7b462714..dd70e4648a1 100644 > --- a/gdb/mi/mi-parse.c > +++ b/gdb/mi/mi-parse.c > @@ -29,6 +29,7 @@ > #include "language.h" > > static const char mi_no_values[] =3D "--no-values"; > +static const char mi_scalar_values[] =3D "--scalar-values"; > static const char mi_simple_values[] =3D "--simple-values"; > static const char mi_all_values[] =3D "--all-values"; > > @@ -383,8 +384,11 @@ mi_parse_print_values (const char *name) > else if (strcmp (name, "2") =3D=3D 0 > || strcmp (name, mi_simple_values) =3D=3D 0) > return PRINT_SIMPLE_VALUES; > + else if (strcmp (name, "3") =3D=3D 0 > + || strcmp (name, mi_scalar_values) =3D=3D 0) > + return PRINT_SCALAR_VALUES; > else > error (_("Unknown value for PRINT_VALUES: must be: \ > -0 or \"%s\", 1 or \"%s\", 2 or \"%s\""), > - mi_no_values, mi_all_values, mi_simple_values); > +0 or \"%s\", 1 or \"%s\", 2 or \"%s\", 3 or \"%s\""), > + mi_no_values, mi_all_values, mi_simple_values, mi_scalar_valu= es); > } > diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c > index 366f3745b9d..a746f309187 100644 > --- a/gdb/python/py-framefilter.c > +++ b/gdb/python/py-framefilter.c > @@ -232,17 +232,17 @@ py_print_value (struct ui_out *out, struct value *v= al, > /* MI does not print certain values, differentiated by type, > depending on what ARGS_TYPE indicates. Test type against option. > For CLI print all values. */ > - if (args_type =3D=3D MI_PRINT_SIMPLE_VALUES > + if (args_type =3D=3D MI_PRINT_SCALAR_VALUES > + || args_type =3D=3D MI_PRINT_SIMPLE_VALUES > || args_type =3D=3D MI_PRINT_ALL_VALUES) > { > - struct type *type =3D check_typedef (value_type (val)); > - > if (args_type =3D=3D MI_PRINT_ALL_VALUES) > should_print =3D 1; > + else if (args_type =3D=3D MI_PRINT_SCALAR_VALUES > + && val_print_scalar_type_p (value_type (val))) > + should_print =3D 1; > else if (args_type =3D=3D MI_PRINT_SIMPLE_VALUES > - && type->code () !=3D TYPE_CODE_ARRAY > - && type->code () !=3D TYPE_CODE_STRUCT > - && type->code () !=3D TYPE_CODE_UNION) > + && mi_simple_values_type_p (value_type (val))) > should_print =3D 1; > } > else if (args_type !=3D NO_VALUES) > @@ -371,10 +371,12 @@ py_print_single_arg (struct ui_out *out, > if (print_args_field) > out->field_signed ("arg", 1); > > - /* For MI print the type, but only for simple values. This seems > - weird, but this is how MI choose to format the various output > + /* For MI print the type, but only for scalar and simple values. This > + seems weird, but this is how MI chooses to format the various outpu= t > types. */ > - if (args_type =3D=3D MI_PRINT_SIMPLE_VALUES && val !=3D NULL) > + if ((args_type =3D=3D MI_PRINT_SCALAR_VALUES > + || args_type =3D=3D MI_PRINT_SIMPLE_VALUES) > + && val !=3D NULL) > py_print_type (out, val); > > if (val !=3D NULL) > @@ -603,7 +605,8 @@ enumerate_locals (PyObject *iter, > out->field_string ("name", sym_name.get ()); > out->text (" =3D "); > > - if (args_type =3D=3D MI_PRINT_SIMPLE_VALUES) > + if (args_type =3D=3D MI_PRINT_SCALAR_VALUES > + || args_type =3D=3D MI_PRINT_SIMPLE_VALUES) > py_print_type (out, val); > > /* CLI always prints values for locals. MI uses the > diff --git a/gdb/testsuite/gdb.mi/mi-stack.exp b/gdb/testsuite/gdb.mi/mi-= stack.exp > index d04c8153c65..8aa4e2234ff 100644 > --- a/gdb/testsuite/gdb.mi/mi-stack.exp > +++ b/gdb/testsuite/gdb.mi/mi-stack.exp > @@ -93,6 +93,9 @@ proc test_stack_args_listing {} { > # -stack-list-arguments 1 1 1 > # -stack-list-arguments 1 1 3 > # -stack-list-arguments > + # -stack-list-arguments 1 1 300 > + # -stack-list-arguments 2 1 1 > + # -stack-list-arguments 3 1 1 > > mi_gdb_test "231-stack-list-arguments 0" \ > "231\\^done,stack-args=3D\\\[frame=3D\{level=3D\"0\",args=3D\\\[\= \\]\},frame=3D\{level=3D\"1\",args=3D\\\[name=3D\"strarg\"\\\]\},frame=3D\{= level=3D\"2\",args=3D\\\[name=3D\"intarg\",name=3D\"strarg\"\\\]\},frame=3D= \{level=3D\"3\",args=3D\\\[name=3D\"intarg\",name=3D\"strarg\",name=3D\"flt= arg\"\\\]\},frame=3D\{level=3D\"4\",args=3D\\\[\\\]\}\\\]" \ > @@ -125,6 +128,14 @@ proc test_stack_args_listing {} { > mi_gdb_test "235-stack-list-arguments 1 1 300" \ > "235\\^done,stack-args=3D\\\[frame=3D\{level=3D\"1\",args=3D\\\[\= {name=3D\"strarg\",value=3D\"$hex \\\\\"A string argument.\\\\\"\"\}\\\]\},= frame=3D\{level=3D\"2\",args=3D\\\[\{name=3D\"intarg\",value=3D\"2\"\},\{na= me=3D\"strarg\",value=3D\"$hex \\\\\"A string argument.\\\\\"\"\}\\\]\},fra= me=3D\{level=3D\"3\",args=3D\\\[\{name=3D\"intarg\",value=3D\"2\"\},\{name= =3D\"strarg\",value=3D\"$hex \\\\\"A string argument.\\\\\"\"\},\{name=3D\"= fltarg\",value=3D\"3.5\"\}\\\]\},frame=3D\{level=3D\"4\",args=3D\\\[\\\]\}\= \\]" \ > "stack args listing 1 1 300" > + > + mi_gdb_test "236-stack-list-arguments 2 1 1" \ > + "236\\^done,stack-args=3D\\\[frame=3D\{level=3D\"1\",args=3D\\\[\= {name=3D\"strarg\",type=3D\"char \\*\",value=3D\"$hex \\\\\"A string argume= nt.\\\\\"\"\}\\\]\}\\\]" \ > + "stack args listing --simple-values 1 1" > + > + mi_gdb_test "237-stack-list-arguments 3 1 1" \ > + "237\\^done,stack-args=3D\\\[frame=3D\{level=3D\"1\",args=3D\\\[\= {name=3D\"strarg\",type=3D\"char \\*\",value=3D\"$hex \\\\\"A string argume= nt.\\\\\"\"\}\\\]\}\\\]" \ > + "stack args listing --scalar-values 1 1" > } > > proc test_stack_info_depth {} { > @@ -163,7 +174,7 @@ proc test_stack_locals_listing {} { > # -stack-list-locals 0 (--no-values) > # -stack-list-locals 1 (--all-values) > # -stack-list-locals 2 (--simple-values) > - # -stack-list-arguments > + # -stack-list-locals 3 (--scalar-values) > > mi_gdb_test "232-stack-list-locals 0" \ > "232\\^done,locals=3D\\\[name=3D\"A\",name=3D\"B\",name=3D\"C\",n= ame=3D\"D\"\\\]" \ > @@ -183,6 +194,10 @@ proc test_stack_locals_listing {} { > "232\\^done,locals=3D\\\[\{name=3D\"A\",type=3D\"int\",value=3D\"= 1\"\},\{name=3D\"B\",type=3D\"int\",value=3D\"2\"\},\{name=3D\"C\",type=3D\= "int\",value=3D\"3\"\},\{name=3D\"D\",type=3D\"int \\\[3\\\]\"\}\\\]" \ > "stack locals listing, simple types: names and values, complex ty= pe: names and types" > > + mi_gdb_test "233-stack-list-locals --scalar-values" \ > + "233\\^done,locals=3D\\\[\{name=3D\"A\",type=3D\"int\",value=3D\"= 1\"\},\{name=3D\"B\",type=3D\"int\",value=3D\"2\"\},\{name=3D\"C\",type=3D\= "int\",value=3D\"3\"\},\{name=3D\"D\",type=3D\"int \\\[3\\\]\"\}\\\]" \ > + "stack locals listing, scalar types: names and values, otherwise:= names and types" > + > mi_gdb_test "234-stack-list-locals" \ > "234\\^error,msg=3D\"-stack-list-locals: Usage.*PRINT_VALUES.*\""= \ > "stack locals listing wrong" > diff --git a/gdb/testsuite/gdb.mi/print-scalar-values.cc b/gdb/testsuite/= gdb.mi/print-scalar-values.cc > new file mode 100644 > index 00000000000..fd9daf1d962 > --- /dev/null > +++ b/gdb/testsuite/gdb.mi/print-scalar-values.cc > @@ -0,0 +1,58 @@ > +/* This test case is part of GDB, the GNU debugger. > + > + Copyright 2022 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 .= */ > + > +/* PRINT_SCALAR_VALUES test program. > + > + Test that PRINT_SCALAR_VALUES distinguishes scalar and non-scalar > + types, including C++ reference and rvalue reference types. > + > + In the function f(), arguments i, ir, and irr are ints or references > + to ints, and their values should be printed by PRINT_SCALAR_VALUES; > + but the other arguments are non-scalar, and so their values should > + not be printed by PRINT_SCALAR_VALUES. */ > + > +struct s > +{ > + int v; > +}; > + > +union u > +{ > + int v; > +}; > + > +int > +f (int i, int &ir, int &&irr, > + int a[1], int (&ar)[1], int (&&arr)[1], > + struct s s, struct s &sr, struct s &&srr, > + union u u, union u &ur, union u &&urr) > +{ > + return (i + ir + irr > + + a[0] + ar[0] + arr[0] > + + s.v + sr.v + srr.v > + + u.v + ur.v + urr.v); > +} > + > +int > +main (void) > +{ > + int i =3D 1, j =3D 2; > + int a[1] =3D { 4 }, b[1] =3D { 5 }; > + struct s s =3D { 7 }, t =3D { 8 }; > + union u u =3D { 10 }, v =3D { 11 }; > + return f (i, j, 3, a, b, { 6 }, s, t, { 9 }, u, v, { 12 }); > +} > diff --git a/gdb/testsuite/gdb.mi/print-scalar-values.exp b/gdb/testsuite= /gdb.mi/print-scalar-values.exp > new file mode 100644 > index 00000000000..3398218c063 > --- /dev/null > +++ b/gdb/testsuite/gdb.mi/print-scalar-values.exp > @@ -0,0 +1,51 @@ > +# Copyright 2022 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 . > + > +# PRINT_SCALAR_VALUES test. > +# > +# Test that PRINT_SCALAR_VALUES distinguishes scalar and non-scalar > +# types, including C++ reference and rvalue reference types. > +# > +# In the function f(), arguments i, ir, and irr are ints or references > +# to ints, and their values should be printed by PRINT_SCALAR_VALUES; > +# but the other arguments are non-scalar, and so their values should not > +# be printed by PRINT_SCALAR_VALUES. > + > +if { [skip_cplus_tests] } { continue } > + > +load_lib mi-support.exp > +standard_testfile .cc > + > +if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile executable {debug = c++}] !=3D "" } { > + untested "failed to compile" > + return -1 > +} > + > +mi_clean_restart $binfile > + > +mi_runto_main > + > +mi_gdb_test "-break-insert f" "\\^done.*" "set breakpoint on f" > + > +mi_send_resuming_command "exec-continue" "exec-continue to breakpoint on= f" > + > +mi_expect_stop "breakpoint-hit" "f" ".*" ".*" ".*" {.* disp=3D"keep"} \ > + "run until breakpoint on f" > + > +mi_gdb_test "-stack-list-arguments --scalar-values" \ > + "\\^done,stack-args=3D\\\[frame=3D\{level=3D\"0\",args=3D\\\[\{name= =3D\"i\",type=3D\"int\",value=3D\"1\"\},\{name=3D\"ir\",type=3D\"int &\",va= lue=3D\"@$hex: 2\"\},\{name=3D\"irr\",type=3D\"int &&\",value=3D\"@$hex: 3\= "\},\{name=3D\"a\",type=3D\"int \\*\",value=3D\"$hex\"\},\{name=3D\"ar\",ty= pe=3D\"int \\(&\\)\\\[1\\\]\"\},\{name=3D\"arr\",type=3D\"int \\(&&\\)\\\[1= \\\]\"\},\{name=3D\"s\",type=3D\"s\"\},\{name=3D\"sr\",type=3D\"s &\"\},\{n= ame=3D\"srr\",type=3D\"s &&\"\},\{name=3D\"u\",type=3D\"u\"\},\{name=3D\"ur= \",type=3D\"u &\"\},\{name=3D\"urr\",type=3D\"u &&\"\}\\\]\},frame=3D\{leve= l=3D\"1\",args=3D\\\[\\\]\}\\\]" \ > + "stack list arguments, scalar types: names, types and values, compou= nd types: names and types" > + > +mi_gdb_exit > -- > 2.26.0 >