diff options
author | Yao Qi <yao@codesourcery.com> | 2013-08-27 05:20:57 +0000 |
---|---|---|
committer | Yao Qi <yao@codesourcery.com> | 2013-08-27 05:20:57 +0000 |
commit | 6211c335ec2c2428b70b65819f69b72d349527d5 (patch) | |
tree | 7b2a8d7a521ed2ebba5f2db2fa7f432c197c0199 /gdb/mi | |
parent | 242f1fd7ee29538968e32155c99a36c3d7604eb5 (diff) | |
download | gdb-6211c335ec2c2428b70b65819f69b72d349527d5.zip gdb-6211c335ec2c2428b70b65819f69b72d349527d5.tar.gz gdb-6211c335ec2c2428b70b65819f69b72d349527d5.tar.bz2 |
Add options to skip unavailable locals
This is the patch to add new option '--skip-unavailable' to MI
commands '-stack-list-{locals, arguments, variables}'. This patch
extends list_args_or_locals to add a new parameter 'skip_unavailable',
and don't list locals or arguments if values are unavailable and
'skip_unavailable' is true.
This is inspecting a trace frame (tfind mode), where only a few
locals have been collected.
-stack-list-locals, no switch vs new switch:
-stack-list-locals --simple-values
^done,locals=[{name="array",type="unsigned char [2]"},{name="i",type="int",value="<unavailable>"}]
-stack-list-locals --skip-unavailable --simple-values
^done,locals=[{name="array",type="unsigned char [2]"}]
-stack-list-arguments, no switch vs new switch:
-stack-list-arguments --simple-values
^done,stack-args=[frame={level="0",args=[{name="j",type="int",value="4"},{name="s",type="char *",value="<unavailable>"}]},frame={level="1",args=[]}]
-stack-list-arguments --skip-unavailable --simple-values
^done,stack-args=[frame={level="0",args=[{name="j",type="int",value="4"}]},frame={level="1",args=[]}]
-stack-list-variables, no switch vs new switch:
-stack-list-variables --simple-values
^done,variables=[{name="j",arg="1",type="int",value="4"},{name="s",arg="1",type="char *",value="<unavailable>"},{name="array",type="unsigned char [2]"},{name="i",type="int",value="<unavailable>"}]
-stack-list-variables --skip-unavailable --simple-values
^done,variables=[{name="j",arg="1",type="int",value="4"},{name="array",type="unsigned char [2]"}]
tests are added to test these new options.
gdb:
2013-08-27 Pedro Alves <pedro@codesourcery.com>
Yao Qi <yao@codesourcery.com>
* 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 <pedro@codesourcery.com>
Yao Qi <yao@codesourcery.com>
* 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 <yao@codesourcery.com>
* 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'.
Diffstat (limited to 'gdb/mi')
-rw-r--r-- | gdb/mi/mi-cmd-stack.c | 77 |
1 files changed, 57 insertions, 20 deletions
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); } |