aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog33
-rw-r--r--gdb/extension.h5
-rw-r--r--gdb/frame.h37
-rw-r--r--gdb/python/py-framefilter.c90
-rw-r--r--gdb/stack.c126
-rw-r--r--gdb/stack.h12
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);