diff options
-rw-r--r-- | gdb/ChangeLog | 33 | ||||
-rw-r--r-- | gdb/extension.h | 5 | ||||
-rw-r--r-- | gdb/frame.h | 37 | ||||
-rw-r--r-- | gdb/python/py-framefilter.c | 90 | ||||
-rw-r--r-- | gdb/stack.c | 126 | ||||
-rw-r--r-- | gdb/stack.h | 12 |
6 files changed, 263 insertions, 40 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index be242e5..4cd32d4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,36 @@ +2019-07-29 Philippe Waroquiers <philippe.waroquiers@skynet.be> + + * frame.h (enum print_what): New value 'SHORT_LOCATION', update + comments. + (print_frame_info_auto, print_frame_info_source_line, + print_frame_info_location, print_frame_info_source_and_location, + print_frame_info_location_and_address, print_frame_info_short_location): + New declarations. + (struct frame_print_options): New member print_frame_info. + * extension.h (enum ext_lang_frame_args): New value CLI_PRESENCE. + * stack.h (get_user_print_what_frame_info): New declaration. + (frame_show_address): New declaration. + * stack.c (print_frame_arguments_choices): New value 'presence'. + (print_frame_info_auto, print_frame_info_source_line, + print_frame_info_location, print_frame_info_source_and_location, + print_frame_info_location_and_address, print_frame_info_short_location, + print_frame_info_choices, print_frame_info_print_what): New definitions. + (print_frame_args): Only print dots for args if print frame-arguments + is 'presence'. + (frame_print_option_defs): New element for "frame-info". + (get_user_print_what_frame_info): New function. + (frame_show_address): Make non static. Move comment to stack.h. + (print_frame_info_to_print_what): New function. + (print_frame_info): Update comment. Use fp_opts.print_frame_info + to decide what to print. + (backtrace_command_1): Handle the new print_frame_arguments_presence + value. + (_initialize_stack): Call add_setshow_enum_cmd for frame-info. + * python/py-framefilter.c (py_print_args): Handle CLI_PRESENCE. + (py_print_frame): In non-mi mode, use LOCATION as default for + print_what, similarly to frame information printed directly by + backtrace command. Handle frame-info user option in non MI mode. + 2019-07-27 Kevin Buettner <kevinb@redhat.com> * linux-thread-db.c (thread_db_target::thread_handle_to_thread_info): diff --git a/gdb/extension.h b/gdb/extension.h index 5e914f5..581afc2 100644 --- a/gdb/extension.h +++ b/gdb/extension.h @@ -125,7 +125,10 @@ enum ext_lang_frame_args CLI_SCALAR_VALUES, /* Print all values for arguments when invoked from the CLI. */ - CLI_ALL_VALUES + CLI_ALL_VALUES, + + /* Only indicate the presence of arguments when invoked from the CLI. */ + CLI_PRESENCE }; /* The possible results of diff --git a/gdb/frame.h b/gdb/frame.h index a79eeee..ccc2850 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -677,18 +677,28 @@ extern struct gdbarch *frame_unwind_arch (frame_info *next_frame); extern struct gdbarch *frame_unwind_caller_arch (struct frame_info *frame); -/* Values for the source flag to be used in print_frame_info_base(). */ +/* Values for the source flag to be used in print_frame_info (). + For all the cases below, the address is never printed if + 'set print address' is off. When 'set print address' is on, + the address is printed if the program counter is not at the + beginning of the source line of the frame + and PRINT_WHAT is != LOC_AND_ADDRESS. */ enum print_what - { - /* Print only the source line, like in stepi. */ - SRC_LINE = -1, - /* Print only the location, i.e. level, address (sometimes) - function, args, file, line, line num. */ + { + /* Print only the address, source line, like in stepi. */ + SRC_LINE = -1, + /* Print only the location, i.e. level, address, + function, args (as controlled by 'set print frame-arguments'), + file, line, line num. */ LOCATION, /* Print both of the above. */ - SRC_AND_LOC, - /* Print location only, but always include the address. */ - LOC_AND_ADDRESS + SRC_AND_LOC, + /* Print location only, print the address even if the program counter + is at the beginning of the source line. */ + LOC_AND_ADDRESS, + /* Print only level and function, + i.e. location only, without address, file, line, line num. */ + SHORT_LOCATION }; /* Allocate zero initialized memory from the frame cache obstack. @@ -772,6 +782,14 @@ extern const char print_frame_arguments_all[]; extern const char print_frame_arguments_scalars[]; extern const char print_frame_arguments_none[]; +/* The possible choices of "set print frame-info". */ +extern const char print_frame_info_auto[]; +extern const char print_frame_info_source_line[]; +extern const char print_frame_info_location[]; +extern const char print_frame_info_source_and_location[]; +extern const char print_frame_info_location_and_address[]; +extern const char print_frame_info_short_location[]; + /* The possible choices of "set print entry-values". */ extern const char print_entry_values_no[]; extern const char print_entry_values_only[]; @@ -787,6 +805,7 @@ extern const char print_entry_values_default[]; struct frame_print_options { const char *print_frame_arguments = print_frame_arguments_scalars; + const char *print_frame_info = print_frame_info_auto; const char *print_entry_values = print_entry_values_default; /* If non-zero, don't invoke pretty-printers for frame diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index 840faf9..a2a96ac 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -25,6 +25,8 @@ #include "python.h" #include "ui-out.h" #include "valprint.h" +#include "stack.h" +#include "source.h" #include "annotate.h" #include "hashtab.h" #include "demangle.h" @@ -713,9 +715,21 @@ py_print_args (PyObject *filter, annotate_frame_args (); out->text (" ("); - if (args_iter != Py_None - && (enumerate_args (args_iter.get (), out, args_type, 0, frame) - == EXT_LANG_BT_ERROR)) + if (args_type == CLI_PRESENCE) + { + if (args_iter != Py_None) + { + gdbpy_ref<> item (PyIter_Next (args_iter.get ())); + + if (item != NULL) + out->text ("..."); + else if (PyErr_Occurred ()) + return EXT_LANG_BT_ERROR; + } + } + else if (args_iter != Py_None + && (enumerate_args (args_iter.get (), out, args_type, 0, frame) + == EXT_LANG_BT_ERROR)) return EXT_LANG_BT_ERROR; out->text (")"); @@ -748,7 +762,16 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, struct gdbarch *gdbarch = NULL; struct frame_info *frame = NULL; struct value_print_options opts; + int print_level, print_frame_info, print_args, print_locals; + /* Note that the below default in non-mi mode is the same as the + default value for the backtrace command (see the call to print_frame_info + in backtrace_command_1). + Having the same default ensures that 'bt' and 'bt no-filters' + have the same behaviour when some filters exist but do not apply + to a frame. */ + enum print_what print_what + = out->is_mi_like_p () ? LOC_AND_ADDRESS : LOCATION; gdb::unique_xmalloc_ptr<char> function_to_free; /* Extract print settings from FLAGS. */ @@ -758,6 +781,17 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, print_locals = (flags & PRINT_LOCALS) ? 1 : 0; get_user_print_options (&opts); + if (print_frame_info) + { + gdb::optional<enum print_what> user_frame_info_print_what; + + get_user_print_what_frame_info (&user_frame_info_print_what); + if (!out->is_mi_like_p () && user_frame_info_print_what.has_value ()) + { + /* Use the specific frame information desired by the user. */ + print_what = *user_frame_info_print_what; + } + } /* Get the underlying frame. This is needed to determine GDB architecture, and also, in the cases of frame variables/arguments to @@ -771,6 +805,8 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, if (frame == NULL) return EXT_LANG_BT_ERROR; + symtab_and_line sal = find_frame_sal (frame); + gdbarch = get_frame_arch (frame); /* stack-list-variables. */ @@ -815,9 +851,19 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, } } + /* For MI, each piece is controlled individually. */ + bool location_print = (print_frame_info + && !out->is_mi_like_p () + && (print_what == LOCATION + || print_what == SRC_AND_LOC + || print_what == LOC_AND_ADDRESS + || print_what == SHORT_LOCATION)); + /* Print frame level. MI does not require the level if locals/variables only are being printed. */ - if ((print_frame_info || print_args) && print_level) + if (print_level + && (location_print + || (out->is_mi_like_p () && (print_frame_info || print_args)))) { struct frame_info **slot; int level; @@ -843,16 +889,21 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, } } - if (print_frame_info) + if (location_print || (out->is_mi_like_p () && print_frame_info)) { /* Print address to the address field. If an address is not provided, print nothing. */ if (opts.addressprint && has_addr) { - annotate_frame_address (); - out->field_core_addr ("addr", gdbarch, address); - annotate_frame_address_end (); - out->text (" in "); + if (!sal.symtab + || frame_show_address (frame, sal) + || print_what == LOC_AND_ADDRESS) + { + annotate_frame_address (); + out->field_core_addr ("addr", gdbarch, address); + annotate_frame_address_end (); + out->text (" in "); + } } /* Print frame function name. */ @@ -904,14 +955,17 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, /* Frame arguments. Check the result, and error if something went wrong. */ - if (print_args) + if (print_args && (location_print || out->is_mi_like_p ())) { if (py_print_args (filter, out, args_type, frame) == EXT_LANG_BT_ERROR) return EXT_LANG_BT_ERROR; } /* File name/source/line number information. */ - if (print_frame_info) + bool print_location_source + = ((location_print && print_what != SHORT_LOCATION) + || (out->is_mi_like_p () && print_frame_info)); + if (print_location_source) { annotate_frame_source_begin (); @@ -963,12 +1017,24 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, (gdbarch_bfd_arch_info (gdbarch))->printable_name); } + bool source_print + = (! out->is_mi_like_p () + && (print_what == SRC_LINE || print_what == SRC_AND_LOC)); + if (source_print) + { + if (print_location_source) + out->text ("\n"); /* Newline after the location source. */ + print_source_lines (sal.symtab, sal.line, sal.line + 1, 0); + } + /* For MI we need to deal with the "children" list population of elided frames, so if MI output detected do not send newline. */ if (! out->is_mi_like_p ()) { annotate_frame_end (); - out->text ("\n"); + /* print_source_lines has already printed a newline. */ + if (!source_print) + out->text ("\n"); } if (print_locals) diff --git a/gdb/stack.c b/gdb/stack.c index 06f10a1..7833ca4 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -61,15 +61,44 @@ const char print_frame_arguments_all[] = "all"; const char print_frame_arguments_scalars[] = "scalars"; const char print_frame_arguments_none[] = "none"; +const char print_frame_arguments_presence[] = "presence"; static const char *const print_frame_arguments_choices[] = { print_frame_arguments_all, print_frame_arguments_scalars, print_frame_arguments_none, + print_frame_arguments_presence, NULL }; +/* The possible choices of "set print frame-info", and the value + of this setting. */ + +const char print_frame_info_auto[] = "auto"; +const char print_frame_info_source_line[] = "source-line"; +const char print_frame_info_location[] = "location"; +const char print_frame_info_source_and_location[] = "source-and-location"; +const char print_frame_info_location_and_address[] = "location-and-address"; +const char print_frame_info_short_location[] = "short-location"; + +static const char *const print_frame_info_choices[] = +{ + print_frame_info_auto, + print_frame_info_source_line, + print_frame_info_location, + print_frame_info_source_and_location, + print_frame_info_location_and_address, + print_frame_info_short_location, + NULL +}; + +/* print_frame_info_print_what[i] maps a choice to the corresponding + print_what enum. */ +static const gdb::optional<enum print_what> print_frame_info_print_what[] = + {{}, /* Empty value for "auto". */ + SRC_LINE, LOCATION, SRC_AND_LOC, LOC_AND_ADDRESS, SHORT_LOCATION}; + /* The possible choices of "set print entry-values", and the value of this setting. */ @@ -137,6 +166,17 @@ or both. Note that one or both of these values may be <optimized out>."), N_("If set, frame arguments are printed in raw form, bypassing any\n\ pretty-printers for that value.") }, + + enum_option_def { + "frame-info", + print_frame_info_choices, + [] (frame_print_options *opt) { return &opt->print_frame_info; }, + NULL, /* show_cmd_cb */ + N_("Set printing of frame information."), + N_("Show printing of frame information."), + NULL /* help_doc */ + } + }; /* Options for the "backtrace" command. */ @@ -209,10 +249,9 @@ static struct symtab *last_displayed_symtab = 0; static int last_displayed_line = 0; -/* Return 1 if we should display the address in addition to the location, - because we are in the middle of a statement. */ +/* See stack.h. */ -static int +int frame_show_address (struct frame_info *frame, struct symtab_and_line sal) { @@ -631,9 +670,14 @@ print_frame_args (const frame_print_options &fp_opts, long highest_offset = -1; /* Number of ints of arguments that we have printed so far. */ int args_printed = 0; + /* True if we should print arg names. If false, we only indicate + the presence of arguments by printing ellipsis. */ + bool print_names + = fp_opts.print_frame_arguments != print_frame_arguments_presence; /* True if we should print arguments, false otherwise. */ bool print_args - = fp_opts.print_frame_arguments != print_frame_arguments_none; + = (print_names + && fp_opts.print_frame_arguments != print_frame_arguments_none); if (func) { @@ -653,6 +697,13 @@ print_frame_args (const frame_print_options &fp_opts, if (!SYMBOL_IS_ARGUMENT (sym)) continue; + if (!print_names) + { + uiout->text ("..."); + first = 0; + break; + } + switch (SYMBOL_CLASS (sym)) { case LOC_ARG: @@ -801,8 +852,11 @@ print_frame_args (const frame_print_options &fp_opts, else start = highest_offset; - print_frame_nameless_args (frame, start, num - args_printed, - first, stream); + if (!print_names && !first && num > 0) + uiout->text ("..."); + else + print_frame_nameless_args (frame, start, num - args_printed, + first, stream); } } @@ -859,13 +913,37 @@ do_gdb_disassembly (struct gdbarch *gdbarch, } } +/* Converts the PRINT_FRAME_INFO choice to an optional enum print_what. + Value not present indicates to the caller to use default values + specific to the command being executed. */ + +static gdb::optional<enum print_what> +print_frame_info_to_print_what (const char *print_frame_info) +{ + for (int i = 0; print_frame_info_choices[i] != NULL; i++) + if (print_frame_info == print_frame_info_choices[i]) + return print_frame_info_print_what[i]; + + internal_error (__FILE__, __LINE__, + "Unexpected print frame-info value `%s'.", + print_frame_info); +} + +/* See stack.h. */ + +void +get_user_print_what_frame_info (gdb::optional<enum print_what> *what) +{ + *what + = print_frame_info_to_print_what + (user_frame_print_options.print_frame_info); +} + /* Print information about frame FRAME. The output is format according - to PRINT_LEVEL and PRINT_WHAT and PRINT_ARGS. The meaning of - PRINT_WHAT is: - - SRC_LINE: Print only source line. - LOCATION: Print only location. - SRC_AND_LOC: Print location and source line. + to PRINT_LEVEL and PRINT_WHAT and PRINT_ARGS. For the meaning of + PRINT_WHAT, see enum print_what comments in frame.h. + Note that PRINT_WHAT is overriden if FP_OPTS.print_frame_info + != print_frame_info_auto. Used in "where" output, and to emit breakpoint or step messages. */ @@ -881,6 +959,13 @@ print_frame_info (const frame_print_options &fp_opts, int location_print; struct ui_out *uiout = current_uiout; + if (!current_uiout->is_mi_like_p () + && fp_opts.print_frame_info != print_frame_info_auto) + { + /* Use the specific frame information desired by the user. */ + print_what = *print_frame_info_to_print_what (fp_opts.print_frame_info); + } + if (get_frame_type (frame) == DUMMY_FRAME || get_frame_type (frame) == SIGTRAMP_FRAME || get_frame_type (frame) == ARCH_FRAME) @@ -944,10 +1029,10 @@ print_frame_info (const frame_print_options &fp_opts, to get the line containing FRAME->pc. */ symtab_and_line sal = find_frame_sal (frame); - location_print = (print_what == LOCATION + location_print = (print_what == LOCATION + || print_what == SRC_AND_LOC || print_what == LOC_AND_ADDRESS - || print_what == SRC_AND_LOC); - + || print_what == SHORT_LOCATION); if (location_print || !sal.symtab) print_frame (fp_opts, frame, print_level, print_what, print_args, sal); @@ -1258,7 +1343,7 @@ print_frame (const frame_print_options &fp_opts, QUIT; } uiout->text (")"); - if (sal.symtab) + if (print_what != SHORT_LOCATION && sal.symtab) { const char *filename_display; @@ -1281,7 +1366,8 @@ print_frame (const frame_print_options &fp_opts, annotate_frame_source_end (); } - if (pc_p && (funname == NULL || sal.symtab == NULL)) + if (print_what != SHORT_LOCATION + && pc_p && (funname == NULL || sal.symtab == NULL)) { char *lib = solib_name_from_address (get_frame_program_space (frame), get_frame_pc (frame)); @@ -1891,8 +1977,12 @@ backtrace_command_1 (const frame_print_options &fp_opts, arg_type = CLI_SCALAR_VALUES; else if (fp_opts.print_frame_arguments == print_frame_arguments_all) arg_type = CLI_ALL_VALUES; - else + else if (fp_opts.print_frame_arguments == print_frame_arguments_presence) + arg_type = CLI_PRESENCE; + else if (fp_opts.print_frame_arguments == print_frame_arguments_none) arg_type = NO_VALUES; + else + gdb_assert (0); result = apply_ext_lang_frame_filter (get_current_frame (), flags, arg_type, current_uiout, diff --git a/gdb/stack.h b/gdb/stack.h index 9ac77c0..dda4fc9 100644 --- a/gdb/stack.h +++ b/gdb/stack.h @@ -42,6 +42,18 @@ void iterate_over_block_local_vars (const struct block *block, iterate_over_block_arg_local_vars_cb cb, void *cb_data); +/* Initialize *WHAT to be a copy of the user desired print what frame info. + If !WHAT.has_value (), the printing function chooses a default set of + information to print, otherwise the printing function should print + the relevant information. */ + +void get_user_print_what_frame_info (gdb::optional<enum print_what> *what); + +/* Return 1 if we should display the address in addition to the location, + because we are in the middle of a statement. */ + +int frame_show_address (struct frame_info *frame, struct symtab_and_line sal); + /* Get or set the last displayed symtab and line, which is, e.g. where we set a * breakpoint when `break' is supplied with no arguments. */ void clear_last_displayed_sal (void); |