From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8659 invoked by alias); 27 Aug 2013 05:22:56 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 8650 invoked by uid 89); 27 Aug 2013 05:22:55 -0000 Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 27 Aug 2013 05:22:55 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00,KHOP_THREADED,RDNS_NONE,SPF_HELO_FAIL autolearn=no version=3.3.2 X-HELO: relay1.mentorg.com Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1VEBju-0000NK-2B from Yao_Qi@mentor.com ; Mon, 26 Aug 2013 22:22:50 -0700 Received: from SVR-ORW-FEM-05.mgc.mentorg.com ([147.34.97.43]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Mon, 26 Aug 2013 22:22:49 -0700 Received: from qiyao.dyndns.org (147.34.91.1) by svr-orw-fem-05.mgc.mentorg.com (147.34.97.43) with Microsoft SMTP Server id 14.2.247.3; Mon, 26 Aug 2013 22:22:44 -0700 Message-ID: <521C3731.5040505@codesourcery.com> Date: Tue, 27 Aug 2013 05:22:00 -0000 From: Yao Qi User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130110 Thunderbird/17.0.2 MIME-Version: 1.0 To: Pedro Alves CC: Subject: Re: [PATCH 2/2] Add options to skip unavailable locals References: <51FA557F.5@redhat.com> <1377402123-3740-1-git-send-email-yao@codesourcery.com> <1377402123-3740-3-git-send-email-yao@codesourcery.com> <521B84EE.70805@redhat.com> In-Reply-To: <521B84EE.70805@redhat.com> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit X-SW-Source: 2013-08/txt/msg00771.txt.bz2 On 08/27/2013 12:40 AM, Pedro Alves wrote: > Looks good to me. A few tiny-tiny suggestions below: > >> > * NEWS: Mention the new option "--skip-unavailable" to MI >> > commands '-stack-list-locals' '-stack-list-arguments' and > ^ > Missing comma. > Added. >> > '-stack-list-variables'. > > >> > Errors are printed as if they would be the parameter value. Use >> >- zeroed ARG iff it should not be printed according to VALUES. */ >> >+ zeroed ARG iff it should not be printed according to VALUES. If >> >+ SKIP_UNAVAILABLE is true, print ARG if it is available. */ > "is true, only print ARG" > "only" is added here... >> > >> > static void >> > list_arg_or_local (const struct frame_arg *arg, enum what_to_list what, >> >- enum print_values values) >> >+ enum print_values values, int skip_unavailable) >> > { > > >> > /* 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. */ >> >+ arguments or both, which is determined by WHAT. If SKIP_UNAVAILABLE >> >+ is true, print the arguments or local variables whose values are >> >+ available. */ > "is true, only print the" > and here. Thanks for the review, Pedro. Patch below is what I committed. -- Yao (齐尧) gdb: 2013-08-27 Pedro Alves Yao Qi * mi/mi-cmd-stack.c (list_args_or_locals): Adjust prototype. (parse_no_frames_option): Remove. (mi_cmd_stack_list_locals): Handle --skip-unavailable. (mi_cmd_stack_list_args): Adjust. (mi_cmd_stack_list_variables): Handle --skip-unavailable. (list_arg_or_local): Add new parameter 'skip_unavailable'. Return early if SKIP_UNAVAILABLE is true and ARG->val is unavailable. Caller update. (list_args_or_locals): New parameter 'skip_unavailable'. Handle it. * valprint.c (scalar_type_p): Rename to ... (val_print_scalar_type_p): ... this. Make extern. (val_print, value_check_printable): Adjust. * valprint.h (val_print_scalar_type_p): Declare. * value.c (value_entirely_unavailable): New function. * value.h (value_entirely_unavailable): Declare. * NEWS: Mention the new option "--skip-unavailable" to MI commands '-stack-list-locals', '-stack-list-arguments' and '-stack-list-variables'. gdb/doc: 2013-08-27 Pedro Alves Yao Qi * gdb.texinfo (GDB/MI Stack Manipulation) <-stack-list-locals>: Document new --skip-unavailable option. <-stack-list-variables>: Document new --skip-unavailable option. gdb/testsuite: 2013-08-27 Yao Qi * gdb.trace/entry-values.exp: Test unavailable entry value is not shown when option '--skip-unavailable' is specified. * gdb.trace/mi-trace-unavailable.exp (test_trace_unavailable): Add tests for new option '--skip-unavailable'. --- gdb/NEWS | 4 + gdb/doc/gdb.texinfo | 17 ++++- gdb/mi/mi-cmd-stack.c | 77 ++++++++++++++++------ gdb/testsuite/gdb.trace/entry-values.exp | 5 ++ gdb/testsuite/gdb.trace/mi-trace-unavailable.exp | 9 +++ gdb/valprint.c | 8 +- gdb/valprint.h | 2 + gdb/value.c | 20 ++++++ gdb/value.h | 4 + 9 files changed, 119 insertions(+), 27 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index 75016c1..ca8baea 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -93,6 +93,10 @@ show range-stepping ** The new command -trace-frame-collected dumps collected variables, computed expressions, tvars, memory and registers in a traceframe. + ** The commands -stack-list-locals, -stack-list-arguments and + -stack-list-variables now accept an option "--skip-unavailable". + When used, only the available locals or arguments are displayed. + * New system-wide configuration scripts A GDB installation now provides scripts suitable for use as system-wide configuration scripts for the following systems: diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index c88ee65..21250fe 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -31249,7 +31249,7 @@ For a stack with frame levels 0 through 11: @subsubheading Synopsis @smallexample - -stack-list-arguments [ --no-frame-filters ] @var{print-values} + -stack-list-arguments [ --no-frame-filters ] [ --skip-unavailable ] @var{print-values} [ @var{low-frame} @var{high-frame} ] @end smallexample @@ -31269,6 +31269,9 @@ 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 the @code{--skip-unavailable} option is specified, arguments that +are not available are not listed. Partially available arguments +are still displayed, however. Use of this command to obtain arguments in a single frame is deprecated in favor of the @samp{-stack-list-variables} command. @@ -31453,7 +31456,7 @@ Show a single frame: @subsubheading Synopsis @smallexample - -stack-list-locals [ --no-frame-filters ] @var{print-values} + -stack-list-locals [ --no-frame-filters ] [ --skip-unavailable ] @var{print-values} @end smallexample Display the local variable names for the selected frame. If @@ -31467,6 +31470,10 @@ 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 +variables are still displayed, however. + This command is deprecated in favor of the @samp{-stack-list-variables} command. @@ -31497,7 +31504,7 @@ This command is deprecated in favor of the @subsubheading Synopsis @smallexample - -stack-list-variables [ --no-frame-filters ] @var{print-values} + -stack-list-variables [ --no-frame-filters ] [ --skip-unavailable ] @var{print-values} @end smallexample Display the names of local variables and function arguments for the selected frame. If @@ -31508,6 +31515,10 @@ 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 the @code{--skip-unavailable} option is specified, local variables +and arguments that are not available are not listed. Partially +available arguments and local variables are still displayed, however. + @subsubheading Example @smallexample diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c index 2df97e2..7bf9ab8 100644 --- a/gdb/mi/mi-cmd-stack.c +++ b/gdb/mi/mi-cmd-stack.c @@ -39,9 +39,10 @@ enum what_to_list { locals, arguments, all }; -static void list_args_or_locals (enum what_to_list what, +static void list_args_or_locals (enum what_to_list what, enum print_values values, - struct frame_info *fi); + struct frame_info *fi, + int skip_unavailable); /* True if we want to allow Python-based frame filters. */ static int frame_filters = 0; @@ -202,17 +203,21 @@ mi_cmd_stack_list_locals (char *command, char **argv, int argc) enum py_bt_status result = PY_BT_ERROR; int print_value; int oind = 0; + int skip_unavailable = 0; + int i; if (argc > 1) { int i; enum opt { - NO_FRAME_FILTERS + NO_FRAME_FILTERS, + SKIP_UNAVAILABLE, }; static const struct mi_opt opts[] = { {"-no-frame-filters", NO_FRAME_FILTERS, 0}, + {"-skip-unavailable", SKIP_UNAVAILABLE, 0}, { 0, 0, 0 } }; @@ -229,6 +234,8 @@ mi_cmd_stack_list_locals (char *command, char **argv, int argc) { case NO_FRAME_FILTERS: raw_arg = oind; + case SKIP_UNAVAILABLE: + skip_unavailable = 1; break; } } @@ -237,7 +244,8 @@ mi_cmd_stack_list_locals (char *command, char **argv, int argc) /* After the last option is parsed, there should be only 'print-values'. */ if (argc - oind != 1) - error (_("-stack-list-locals: Usage: [--no-frame-filters] PRINT_VALUES")); + error (_("-stack-list-locals: Usage: [--no-frame-filters] " + "[--skip-unavailable] PRINT_VALUES")); frame = get_selected_frame (NULL); print_value = mi_parse_print_values (argv[oind]); @@ -254,7 +262,8 @@ mi_cmd_stack_list_locals (char *command, char **argv, int argc) if "--no-frame-filters" has been specified from the command. */ if (! frame_filters || raw_arg || result == PY_BT_NO_FILTERS) { - list_args_or_locals (locals, print_value, frame); + list_args_or_locals (locals, print_value, frame, + skip_unavailable); } } @@ -274,14 +283,17 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc) struct ui_out *uiout = current_uiout; int raw_arg = 0; int oind = 0; + int skip_unavailable = 0; enum py_bt_status result = PY_BT_ERROR; enum opt { NO_FRAME_FILTERS, + SKIP_UNAVAILABLE, }; static const struct mi_opt opts[] = { {"-no-frame-filters", NO_FRAME_FILTERS, 0}, + {"-skip-unavailable", SKIP_UNAVAILABLE, 0}, { 0, 0, 0 } }; @@ -298,12 +310,16 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc) case NO_FRAME_FILTERS: raw_arg = oind; break; + case SKIP_UNAVAILABLE: + skip_unavailable = 1; + break; } } if (argc - oind != 1 && argc - oind != 3) error (_("-stack-list-arguments: Usage: " \ - "[--no-frame-filters] PRINT_VALUES [FRAME_LOW FRAME_HIGH]")); + "[--no-frame-filters] [--skip-unavailable] " + "PRINT_VALUES [FRAME_LOW FRAME_HIGH]")); if (argc - oind == 3) { @@ -364,7 +380,7 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc) QUIT; cleanup_frame = make_cleanup_ui_out_tuple_begin_end (uiout, "frame"); ui_out_field_int (uiout, "level", i); - list_args_or_locals (arguments, print_values, fi); + list_args_or_locals (arguments, print_values, fi, skip_unavailable); do_cleanups (cleanup_frame); } } @@ -384,17 +400,20 @@ mi_cmd_stack_list_variables (char *command, char **argv, int argc) enum py_bt_status result = PY_BT_ERROR; int print_value; int oind = 0; + int skip_unavailable = 0; if (argc > 1) { int i; enum opt { - NO_FRAME_FILTERS + NO_FRAME_FILTERS, + SKIP_UNAVAILABLE, }; static const struct mi_opt opts[] = { {"-no-frame-filters", NO_FRAME_FILTERS, 0}, + {"-skip-unavailable", SKIP_UNAVAILABLE, 0}, { 0, 0, 0 } }; @@ -411,6 +430,9 @@ mi_cmd_stack_list_variables (char *command, char **argv, int argc) case NO_FRAME_FILTERS: raw_arg = oind; break; + case SKIP_UNAVAILABLE: + skip_unavailable = 1; + break; } } } @@ -418,8 +440,8 @@ mi_cmd_stack_list_variables (char *command, char **argv, int argc) /* After the last option is parsed, there should be only 'print-values'. */ if (argc - oind != 1) - error (_("-stack-list-variables: Usage: " \ - "[--no-frame-filters] PRINT_VALUES")); + error (_("-stack-list-variables: Usage: [--no-frame-filters] " \ + "[--skip-unavailable] PRINT_VALUES")); frame = get_selected_frame (NULL); print_value = mi_parse_print_values (argv[oind]); @@ -436,7 +458,8 @@ mi_cmd_stack_list_variables (char *command, char **argv, int argc) if "--no-frame-filters" has been specified from the command. */ if (! frame_filters || raw_arg || result == PY_BT_NO_FILTERS) { - list_args_or_locals (all, print_value, frame); + list_args_or_locals (all, print_value, frame, + skip_unavailable); } } @@ -444,19 +467,17 @@ mi_cmd_stack_list_variables (char *command, char **argv, int argc) WHAT and VALUES see list_args_or_locals. Errors are printed as if they would be the parameter value. Use - zeroed ARG iff it should not be printed according to VALUES. */ + zeroed ARG iff it should not be printed according to VALUES. If + SKIP_UNAVAILABLE is true, only print ARG if it is available. */ static void list_arg_or_local (const struct frame_arg *arg, enum what_to_list what, - enum print_values values) + enum print_values values, int skip_unavailable) { struct cleanup *old_chain; struct ui_out *uiout = current_uiout; struct ui_file *stb; - stb = mem_fileopen (); - old_chain = make_cleanup_ui_file_delete (stb); - gdb_assert (!arg->val || !arg->error); gdb_assert ((values == PRINT_NO_VALUES && arg->val == NULL && arg->error == NULL) @@ -467,6 +488,20 @@ list_arg_or_local (const struct frame_arg *arg, enum what_to_list what, || (arg->entry_kind == print_entry_values_only && (arg->val || arg->error))); + if (skip_unavailable && arg->val != NULL + && (value_entirely_unavailable (arg->val) + /* A scalar object that does not have all bits available is + also considered unavailable, because all bits contribute + to its representation. */ + || (val_print_scalar_type_p (value_type (arg->val)) + && !value_bytes_available (arg->val, + value_embedded_offset (arg->val), + TYPE_LENGTH (value_type (arg->val)))))) + return; + + stb = mem_fileopen (); + old_chain = make_cleanup_ui_file_delete (stb); + if (values != PRINT_NO_VALUES || what == all) make_cleanup_ui_out_tuple_begin_end (uiout, NULL); @@ -516,11 +551,13 @@ list_arg_or_local (const struct frame_arg *arg, enum what_to_list what, /* 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. */ + arguments or both, which is determined by WHAT. If SKIP_UNAVAILABLE + is true, only print the arguments or local variables whose values + are available. */ static void list_args_or_locals (enum what_to_list what, enum print_values values, - struct frame_info *fi) + struct frame_info *fi, int skip_unavailable) { struct block *block; struct symbol *sym; @@ -623,9 +660,9 @@ list_args_or_locals (enum what_to_list what, enum print_values values, } if (arg.entry_kind != print_entry_values_only) - list_arg_or_local (&arg, what, values); + list_arg_or_local (&arg, what, values, skip_unavailable); if (entryarg.entry_kind != print_entry_values_no) - list_arg_or_local (&entryarg, what, values); + list_arg_or_local (&entryarg, what, values, skip_unavailable); xfree (arg.error); xfree (entryarg.error); } diff --git a/gdb/testsuite/gdb.trace/entry-values.exp b/gdb/testsuite/gdb.trace/entry-values.exp index bb62e5d..85306ad 100644 --- a/gdb/testsuite/gdb.trace/entry-values.exp +++ b/gdb/testsuite/gdb.trace/entry-values.exp @@ -276,4 +276,9 @@ gdb_test "tfind" "Found trace frame 0, .*" "tfind start" # Since 'global2' is not collected, j@entry is expected to be 'unavailable'. gdb_test "bt 1" "#0 .* foo \\(i=\[-\]?$decimal, i@entry=2, j=\[-\]?$decimal, j@entry=\\).*" +# Test that unavailable "j@entry" is not shown when command option +# --skip-unavailable is used. +gdb_test "interpreter-exec mi \"-stack-list-arguments --skip-unavailable --simple-values\"" \ + "\r\n\\^done,stack-args=\\\[frame={level=\"0\",args=\\\[{name=\"i\",type=\"int\",value=\".*\"},{name=\"i@entry\",type=\"int\",value=\"2\"},{name=\"j\",type=\"int\",value=\".*\"}\\\]},frame=.*\\\].*" + gdb_test "tfind" "Target failed to find requested trace frame\..*" diff --git a/gdb/testsuite/gdb.trace/mi-trace-unavailable.exp b/gdb/testsuite/gdb.trace/mi-trace-unavailable.exp index d96ec8b..c69891b 100644 --- a/gdb/testsuite/gdb.trace/mi-trace-unavailable.exp +++ b/gdb/testsuite/gdb.trace/mi-trace-unavailable.exp @@ -106,16 +106,25 @@ proc test_trace_unavailable { data_source } { mi_gdb_test "-stack-list-locals --simple-values" \ ".*\\^done,locals=\\\[\{name=\"array\",type=\"unsigned char \\\[2\\\]\"\},\{name=\"i\",type=\"int\",value=\"\"\}\\\]" \ "-stack-list-locals --simple-values" + mi_gdb_test "-stack-list-locals --skip-unavailable --simple-values" \ + ".*\\^done,locals=\\\[\{name=\"array\",type=\"unsigned char \\\[2\\\]\"\}\\\]" \ + "-stack-list-locals --skip-unavailable --simple-values" # Test MI command '-stack-list-arguments'. mi_gdb_test "-stack-list-arguments --simple-values" \ ".*\\^done,stack-args=\\\[frame=\{level=\"0\",args=\\\[\{name=\"j\",type=\"int\",value=\"4\"\},\{name=\"s\",type=\"char \\\*\",value=\"\"\}\\\]\},.*\}.*" \ "-stack-list-arguments --simple-values" + mi_gdb_test "-stack-list-arguments --skip-unavailable --simple-values" \ + ".*\\^done,stack-args=\\\[frame=\{level=\"0\",args=\\\[\{name=\"j\",type=\"int\",value=\"4\"\}\\\]\},.*\}.*" \ + "-stack-list-arguments --skip-unavailable --simple-values" # Test MI command '-stack-list-variables'. mi_gdb_test "-stack-list-variables --simple-values" \ ".*\\^done,variables=\\\[\{name=\"j\",arg=\"1\",type=\"int\",value=\"4\"\},\{name=\"s\",arg=\"1\",type=\"char \\\*\",value=\"\"\},\{name=\"array\",type=\"unsigned char \\\[2\\\]\"\},\{name=\"i\",type=\"int\",value=\"\"\}\\\]" \ "-stack-list-variables --simple-values" + mi_gdb_test "-stack-list-variables --skip-unavailable --simple-values" \ + ".*\\^done,variables=\\\[\{name=\"j\",arg=\"1\",type=\"int\",value=\"4\"\},\{name=\"array\",type=\"unsigned char \\\[2\\\]\"\}\\\]" \ + "-stack-list-variables --skip-unavailable --simple-values" mi_gdb_test "-trace-find frame-number 1" \ ".*\\^done,found=\"1\",tracepoint=\"${decimal}\",traceframe=\"1\",frame=\{.*" \ diff --git a/gdb/valprint.c b/gdb/valprint.c index 753ae34..0f6d65e 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -275,8 +275,8 @@ show_symbol_print (struct ui_file *file, int from_tty, we want to print scalar arguments, but not aggregate arguments. This function distinguishes between the two. */ -static int -scalar_type_p (struct type *type) +int +val_print_scalar_type_p (struct type *type) { CHECK_TYPEDEF (type); while (TYPE_CODE (type) == TYPE_CODE_REF) @@ -770,7 +770,7 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, /* Handle summary mode. If the value is a scalar, print it; otherwise, print an ellipsis. */ - if (options->summary && !scalar_type_p (type)) + if (options->summary && !val_print_scalar_type_p (type)) { fprintf_filtered (stream, "..."); return; @@ -802,7 +802,7 @@ value_check_printable (struct value *val, struct ui_file *stream, if (value_entirely_optimized_out (val)) { - if (options->summary && !scalar_type_p (value_type (val))) + if (options->summary && !val_print_scalar_type_p (value_type (val))) fprintf_filtered (stream, "..."); else val_print_optimized_out (stream); diff --git a/gdb/valprint.h b/gdb/valprint.h index 2959098..e7073b6 100644 --- a/gdb/valprint.h +++ b/gdb/valprint.h @@ -211,4 +211,6 @@ extern void generic_printstr (struct ui_file *stream, struct type *type, extern void output_command_const (const char *args, int from_tty); +extern int val_print_scalar_type_p (struct type *type); + #endif diff --git a/gdb/value.c b/gdb/value.c index 09ab1bb..d96c07b 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -353,6 +353,26 @@ value_entirely_available (struct value *value) return 0; } +int +value_entirely_unavailable (struct value *value) +{ + /* We can only tell whether the whole value is available when we try + to read it. */ + if (value->lazy) + value_fetch_lazy (value); + + if (VEC_length (range_s, value->unavailable) == 1) + { + struct range *t = VEC_index (range_s, value->unavailable, 0); + + if (t->offset == 0 + && t->length == TYPE_LENGTH (value_enclosing_type (value))) + return 1; + } + + return 0; +} + void mark_value_bytes_unavailable (struct value *value, int offset, int length) { diff --git a/gdb/value.h b/gdb/value.h index bef193c..f03cf76 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -435,6 +435,10 @@ extern int value_bytes_available (const struct value *value, whole object is unavailable. */ extern int value_entirely_available (struct value *value); +/* Like value_entirely_available, but return false if any byte in the + whole object is available. */ +extern int value_entirely_unavailable (struct value *value); + /* Mark VALUE's content bytes starting at OFFSET and extending for LENGTH bytes as unavailable. */ -- 1.7.7.6