* [RFAv2 1/3] Implement 'set print frame-info|frame-arguments presence'.
2019-05-11 18:56 [RFAv2 0/3] Implement 'set print frame-info|frame-arguments Philippe Waroquiers
2019-05-11 18:56 ` [RFAv2 3/3] Document 'set print frame-info|frame-arguments presence' Philippe Waroquiers
2019-05-11 18:56 ` [RFAv2 2/3] Test " Philippe Waroquiers
@ 2019-05-11 18:56 ` Philippe Waroquiers
2019-06-04 17:15 ` Tom Tromey
2 siblings, 1 reply; 9+ messages in thread
From: Philippe Waroquiers @ 2019-05-11 18:56 UTC (permalink / raw)
To: gdb-patches; +Cc: Philippe Waroquiers
New settings allow to better control what frame information is printed.
'set print frame-info' allows to override the default frame information
printed when a GDB command prints a frame.
It is now possible to have very short frame information by using the
new 'set print frame-arguments presence' and 'set print frame-info short_loc'.
Combined with 'set print address off', a backtrace will only show
the essential information to see the function call chain, e.g.:
(gdb) set print address off
(gdb) set print frame-arguments presence
(gdb) set print frame-info short_loc
(gdb) bt
#0 break_me ()
#1 call_me (...)
#2 main ()
(gdb)
This is handy in particular for big backtraces with functions having
many arguments.
Python frame filter printing logic has been updated to respect the new
setting in non MI mode.
---
gdb/ChangeLog | 21 +++++++
gdb/extension.h | 5 +-
gdb/frame.h | 28 +++++++---
gdb/python/py-framefilter.c | 84 ++++++++++++++++++++++++----
gdb/stack.c | 106 +++++++++++++++++++++++++++++-------
gdb/stack.h | 12 ++++
6 files changed, 215 insertions(+), 41 deletions(-)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 9492412efb..9ba008a35c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -6765,3 +6765,24 @@ version-control: never
coding: utf-8
End:
+2019-05-04 Philippe Waroquiers <philippe.waroquiers@skynet.be>
+
+ * NEWS: Mention 'set|show print frame-info'. Mention new
+ 'presence' value for 'frame-arguments'.
+ * frame.h (enum print_what): New value 'SHORT_LOCATION', update
+ comments.
+ * 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_args): Only print dots for args if print frame-arguments
+ is 'presence'.
+ (get_user_print_what_frame_info): New function.
+ (frame_show_address): Make non static. Move comment to stack.h.
+ (print_what_frame_info_string, print_what_frame_info)
+ (set_print_frame_info_command): New variables and function.
+ (print_frame_info): Update comment. Use print_what_frame_info
+ to decide what to print.
+ (_initialize_stack): Call add_setshow_enum_cmd for frame-info.
+ * py-framefilter.c (py_print_args): Handle CLI_PRESENCE.
+ (py_print_frame): Handle frame-info user option in non MI mode.
diff --git a/gdb/extension.h b/gdb/extension.h
index 2f1b71851c..405346ff6a 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 0a0baf46a0..4c0ee4d53e 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -675,18 +675,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.
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index 017ea90f61..1e20f6f4ce 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"
@@ -712,9 +714,19 @@ 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)
+ {
+ if (PyIter_Next (args_iter.get ()) != 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 (")");
@@ -747,7 +759,12 @@ 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 this print_what default implies that 'bt' and 'bt no-filters'
+ shows different information, as the default for 'bt no-filters
+ is LOCATION. */
+ enum print_what print_what = LOC_AND_ADDRESS;
gdb::unique_xmalloc_ptr<char> function_to_free;
/* Extract print settings from FLAGS. */
@@ -757,6 +774,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
@@ -770,6 +798,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. */
@@ -814,9 +844,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 +883,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 +949,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 +1011,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 408c795e38..2c19e961c2 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -57,7 +57,7 @@
of this setting. */
static const char *const print_frame_arguments_choices[] =
- {"all", "scalars", "none", NULL};
+ {"all", "scalars", "none", "presence", NULL};
static const char *print_frame_arguments = "scalars";
/* If non-zero, don't invoke pretty-printers for frame arguments. */
@@ -123,10 +123,9 @@ static struct symtab *last_displayed_symtab = 0;
static int last_displayed_line = 0;
\f
-/* 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)
{
@@ -539,8 +538,11 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
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. */
+ int print_names = strcmp (print_frame_arguments, "presence");
/* True if we should print arguments, false otherwise. */
- int print_args = strcmp (print_frame_arguments, "none");
+ int print_args = print_names && strcmp (print_frame_arguments, "none");
if (func)
{
@@ -560,6 +562,13 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
if (!SYMBOL_IS_ARGUMENT (sym))
continue;
+ if (!print_names)
+ {
+ uiout->text ("...");
+ first = 0;
+ break;
+ }
+
switch (SYMBOL_CLASS (sym))
{
case LOC_ARG:
@@ -708,8 +717,11 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
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);
}
}
@@ -766,13 +778,51 @@ do_gdb_disassembly (struct gdbarch *gdbarch,
}
}
+/* The possible choices of "set print frame-info", and the value
+ of this setting. */
+
+static const char *const print_frame_info_choices[] =
+ {"auto", "source-line", "location", "source-and-location",
+ "location-and-address", "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};
+static const char *print_what_frame_info_string = "auto";
+static gdb::optional<enum print_what> print_what_frame_info;
+
+/* Set command. Change the current frame info to print. */
+
+static void
+set_print_frame_info_command (const char *ignore,
+ int from_tty, struct cmd_list_element *c)
+{
+
+ for (int i = 0; print_frame_info_choices[i] != NULL; i++)
+ {
+ if (strcmp (print_what_frame_info_string,
+ print_frame_info_choices[i]) == 0)
+ {
+ print_what_frame_info = print_frame_info_print_what[i];
+ return;
+ }
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "Unexpected set print frame-info `%s'.",
+ print_what_frame_info_string);
+}
+
+void
+get_user_print_what_frame_info (gdb::optional<enum print_what> *what)
+{
+ *what = print_what_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.
Used in "where" output, and to emit breakpoint or step
messages. */
@@ -787,6 +837,12 @@ print_frame_info (struct frame_info *frame, int print_level,
int location_print;
struct ui_out *uiout = current_uiout;
+ if (!current_uiout->is_mi_like_p () && print_what_frame_info.has_value ())
+ {
+ /* Use the specific frame information desired by the user. */
+ print_what = *print_what_frame_info;
+ }
+
if (get_frame_type (frame) == DUMMY_FRAME
|| get_frame_type (frame) == SIGTRAMP_FRAME
|| get_frame_type (frame) == ARCH_FRAME)
@@ -850,10 +906,10 @@ print_frame_info (struct frame_info *frame, int print_level,
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 (frame, print_level, print_what, print_args, sal);
@@ -1210,7 +1266,7 @@ print_frame (struct frame_info *frame, int print_level,
QUIT;
}
uiout->text (")");
- if (sal.symtab)
+ if (print_what != SHORT_LOCATION && sal.symtab)
{
const char *filename_display;
@@ -1233,7 +1289,8 @@ print_frame (struct frame_info *frame, int print_level,
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));
@@ -1833,8 +1890,12 @@ backtrace_command_1 (const char *count_exp, frame_filter_flags flags,
arg_type = CLI_SCALAR_VALUES;
else if (!strcmp (print_frame_arguments, "all"))
arg_type = CLI_ALL_VALUES;
- else
+ else if (!strcmp (print_frame_arguments, "presence"))
+ arg_type = CLI_PRESENCE;
+ else if (!strcmp (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,
@@ -3106,6 +3167,13 @@ Usage: func NAME"));
_("Show printing of non-scalar frame arguments"),
NULL, NULL, NULL, &setprintlist, &showprintlist);
+ add_setshow_enum_cmd ("frame-info", class_stack,
+ print_frame_info_choices, &print_what_frame_info_string,
+ _("Set printing of frame information"),
+ _("Show printing of frame information"),
+ NULL, set_print_frame_info_command, NULL,
+ &setprintlist, &showprintlist);
+
add_setshow_boolean_cmd ("frame-arguments", no_class,
&print_raw_frame_arguments, _("\
Set whether to print frame arguments in raw form."), _("\
diff --git a/gdb/stack.h b/gdb/stack.h
index 6c6caa913e..32fb196eed 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);
--
2.20.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFAv2 0/3] Implement 'set print frame-info|frame-arguments
@ 2019-05-11 18:56 Philippe Waroquiers
2019-05-11 18:56 ` [RFAv2 3/3] Document 'set print frame-info|frame-arguments presence' Philippe Waroquiers
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Philippe Waroquiers @ 2019-05-11 18:56 UTC (permalink / raw)
To: gdb-patches
When printing big stacktraces having a lot of functions with a lot of
arguments, it can be handy to see a lot less information in the
printed frames.
With the new settings, it is possible to have backtraces such as:
(gdb) bt
#0 break_me ()
#1 call_me (...)
#2 main ()
(gdb)
that are only showing the level, the function name and the presence of
arguments.
Compared to V1, the changes are:
* Handled the comment of Andreas Schwab : do not abbreviate words
in 'set print fram-info' values, and use dash instead of underscore.
* Handled the comment of Tom about updating py-framefilter.c
+ updated py-framefilter.exp to test the new setting with python
frame filter.
* Handled the comments of Eli about the documentation and NEWS.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFAv2 3/3] Document 'set print frame-info|frame-arguments presence'.
2019-05-11 18:56 [RFAv2 0/3] Implement 'set print frame-info|frame-arguments Philippe Waroquiers
@ 2019-05-11 18:56 ` Philippe Waroquiers
2019-05-11 19:18 ` Eli Zaretskii
2019-05-11 18:56 ` [RFAv2 2/3] Test " Philippe Waroquiers
2019-05-11 18:56 ` [RFAv2 1/3] Implement " Philippe Waroquiers
2 siblings, 1 reply; 9+ messages in thread
From: Philippe Waroquiers @ 2019-05-11 18:56 UTC (permalink / raw)
To: gdb-patches; +Cc: Philippe Waroquiers
---
gdb/NEWS | 13 ++++++++++
gdb/doc/ChangeLog | 5 ++++
gdb/doc/gdb.texinfo | 58 ++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 73 insertions(+), 3 deletions(-)
diff --git a/gdb/NEWS b/gdb/NEWS
index 288615b8cd..b766d4394e 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -46,6 +46,19 @@ show print max-depth
The default max-depth is 20, but this can be set to unlimited to get
the old behavior back.
+set print frame-info [short-location|location|location-and-address
+ |source-and-location|source-line|auto]
+show print frame-info
+ This controls what frame information is printed by the commands printing
+ a frame. This setting will e.g. influence the behaviour of 'backtrace',
+ 'frame', stepi. The python frame filtering also respect this setting.
+
+* Changed commands
+
+set print frame-arguments
+ The new value 'presence' indicates to only indicate the presence of
+ arguments using ..., instead of printing argument names and values.
+
*** Changes in GDB 8.3
* GDB and GDBserver now support access to additional registers on
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index fe7f33ba7b..b252f066c0 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -12840,3 +12840,8 @@ fill-column: 74
version-control: never
coding: utf-8
End:
+2019-05-04 Philippe Waroquiers <philippe.waroquiers@skynet.be>
+
+ * gdb.texinfo (Print Settings): Document 'set|show print frame-info'.
+ (Backtraces): Reference 'set print frame-info'.
+
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 1fb4e3df6a..f1f0a98d8c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -7554,6 +7554,8 @@ The value of parameter @code{data} in frame 1 has been replaced by
only if it is a scalar (integer, pointer, enumeration, etc). See command
@kbd{set print frame-arguments} in @ref{Print Settings} for more details
on how to configure the way function parameter values are printed.
+The command @kbd{set print frame-info} (@pxref{Print Settings}) controls
+what frame information is printed.
@cindex optimized out, in backtrace
@cindex function call arguments, optimized out
@@ -10385,7 +10387,7 @@ If the number is 0, then the printing is unlimited.
@cindex printing frame argument values
@cindex print all frame argument values
@cindex print frame argument values for scalars only
-@cindex do not print frame argument values
+@cindex do not print frame arguments
This command allows to control how the values of arguments are printed
when the debugger prints a frame (@pxref{Frames}). The possible
values are:
@@ -10413,6 +10415,17 @@ is replaced by @code{@dots{}}. In this case, the example above now becomes:
#1 0x08048361 in call_me (i=@dots{}, s=@dots{}, ss=@dots{}, u=@dots{}, e=@dots{})
at frame-args.c:23
@end smallexample
+
+@item presence
+Only the presence of arguments is indicated by @code{@dots{}}.
+The @code{@dots{}} are not printed for function without any arguments.
+None of the argument names and values are printed.
+In this case, the example above now becomes:
+
+@smallexample
+#1 0x08048361 in call_me (@dots{}) at frame-args.c:23
+@end smallexample
+
@end table
By default, only scalar arguments are printed. This command can be used
@@ -10423,8 +10436,8 @@ information printed in each frame, making the backtrace more readable.
Also, it improves performance when displaying Ada frames, because
the computation of large arguments can sometimes be CPU-intensive,
especially in large applications. Setting @code{print frame-arguments}
-to @code{scalars} (the default) or @code{none} avoids this computation,
-thus speeding up the display of each Ada frame.
+to @code{scalars} (the default), @code{none} or @code{presence} avoids
+this computation, thus speeding up the display of each Ada frame.
@item show print frame-arguments
Show how the value of arguments should be displayed when printing a frame.
@@ -10556,6 +10569,45 @@ entry resolution see @ref{set debug entry-values}.
Show the method being used for printing of frame argument values at function
entry.
+@item set print frame-info @var{value}
+@kindex set print frame-info
+@cindex printing frame information
+@cindex frame information, printing
+This command allows to control the information printed when
+the debugger prints a frame. See @ref{Frames}, @ref{Backtrace},
+for a general explanation about frames and frame information.
+Note that some other settings (such as @code{set print frame-arguments}
+and @code{set print address}) are also influencing if and how some frame
+information is displayed. In particular, the frame program counter is never
+printed if @code{set print address} is off.
+
+The possible values for @code{set print frame-info} are:
+@table @code
+@item short-location
+Print the frame level, the program counter (if not at the
+beginning of the location source line), the function, the function
+arguments.
+@item location
+Same as @code{short-location} but also print the source file and source line
+number.
+@item location-and-address
+Same as @code{location} but print the program counter even if located at the
+beginning of the location source line.
+@item source-line
+Print the program counter (if not at the beginning of the location
+source line), the line number and the source line.
+@item source-and-location
+Print what @code{location} and @code{source-line} are printing.
+@item auto
+The information printed for a frame is decided automatically
+by the @value{GDBN} command that prints a frame.
+For example, @code{frame} prints the information printed by
+@code{source-and-location} while @code{stepi} will switch between
+@code{source-line} and @code{source-and-location} depending on the program
+counter.
+The default value is @code{auto}.
+@end table
+
@item set print repeats @var{number-of-repeats}
@itemx set print repeats unlimited
@cindex repeated array elements
--
2.20.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFAv2 2/3] Test 'set print frame-info|frame-arguments presence'.
2019-05-11 18:56 [RFAv2 0/3] Implement 'set print frame-info|frame-arguments Philippe Waroquiers
2019-05-11 18:56 ` [RFAv2 3/3] Document 'set print frame-info|frame-arguments presence' Philippe Waroquiers
@ 2019-05-11 18:56 ` Philippe Waroquiers
2019-06-04 17:15 ` Tom Tromey
2019-05-11 18:56 ` [RFAv2 1/3] Implement " Philippe Waroquiers
2 siblings, 1 reply; 9+ messages in thread
From: Philippe Waroquiers @ 2019-05-11 18:56 UTC (permalink / raw)
To: gdb-patches; +Cc: Philippe Waroquiers
---
gdb/testsuite/ChangeLog | 5 ++
gdb/testsuite/gdb.base/frame-args.exp | 56 ++++++++++++++++++++
gdb/testsuite/gdb.python/py-framefilter.exp | 57 +++++++++++++++++++--
3 files changed, 114 insertions(+), 4 deletions(-)
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 252a183d97..94d15d593d 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -15933,3 +15933,8 @@ For older changes see ChangeLog-1993-2013.
Copyright 2014-2019 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted provided the copyright notice and this notice are preserved.
+2019-05-04 Philippe Waroquiers <philippe.waroquiers@skynet.be>
+
+ * gdb.base/frame-args.exp: Test new 'frame-arguments presence'.
+ Test new 'set print frame-info'.
+ * gdb.python/py-framefilter.exp: Likewise.
diff --git a/gdb/testsuite/gdb.base/frame-args.exp b/gdb/testsuite/gdb.base/frame-args.exp
index 77f136c064..9e632c6433 100644
--- a/gdb/testsuite/gdb.base/frame-args.exp
+++ b/gdb/testsuite/gdb.base/frame-args.exp
@@ -50,4 +50,60 @@ gdb_test "frame 1" \
".*in call_me \\(i=\\.\\.\\., f=\\.\\.\\., s=\\.\\.\\., ss=\\.\\.\\., u=\\.\\.\\., e=\\.\\.\\.\\) at .*frame-args\\.c:.*" \
"frame 1 with print frame-arguments set to none"
+# Test with "print frame-arguments" set to "presence"
+
+gdb_test_no_output "set print frame-arguments presence" \
+ "set print frame-arguments presence"
+gdb_test "frame 1" \
+ ".*in call_me \\(\\.\\.\\.\\) at .*frame-args\\.c:.*" \
+ "frame 1 with print frame-arguments set to presence"
+gdb_test "frame 2" \
+ ".*in main \\(\\) at .*frame-args\\.c:.*" \
+ "frame 2 (no args) with print frame-arguments set to presence"
+
+
+# Test with "print frame-info" set to "location-and-address"
+gdb_test_no_output "set print frame-info location-and-address" \
+ "set print frame-info location-and-address"
+gdb_test "frame 1" \
+ ".*0x.* in call_me \\(\\.\\.\\.\\) at .*frame-args\\.c:.*" \
+ "frame 1 with print frame-info set to location-and-address"
+
+# Test with "print address" set to "off" ...
+gdb_test_no_output "set print address off" \
+ "set print address off"
+
+# ... and "location-and-address" (previously set)
+gdb_test "frame 1" \
+ "#1 call_me \\(\\.\\.\\.\\) at .*frame-args\\.c:.*" \
+ "frame 1 with print frame-info set to location-and-address and address off"
+
+# ... and "location"
+gdb_test_no_output "set print frame-info location" \
+ "set print frame-info location"
+gdb_test "frame 1" \
+ "#1 call_me \\(\\.\\.\\.\\) at .*frame-args\\.c:.*" \
+ "frame 1 with print frame-info set to location and address off"
+
+# ... and "short-location"
+gdb_test_no_output "set print frame-info short-location" \
+ "set print frame-info short-location"
+gdb_test "frame 1" \
+ "#1 call_me \\(\\.\\.\\.\\)" \
+ "frame 1 with print frame-info set to short-location and address off"
+
+# ... and "source-and-location"
+gdb_test_no_output "set print frame-info source-and-location" \
+ "set print frame-info source-and-location"
+gdb_test "frame 1" \
+ "#1 call_me \\(\\.\\.\\.\\) at .*frame-args\\.c:.*\r\n\[1-9\]\[0-9\]*\[ \t\]*break_me \\(\\);" \
+ "frame 1 with print frame-info set to source-and-location and address off"
+
+# ... and "source-line".
+gdb_test_no_output "set print frame-info source-line" \
+ "set print frame-info source-line"
+gdb_test "frame 1" \
+ "\[1-9\]\[0-9\]*\[ \t\]*break_me \\(\\);" \
+ "frame 1 with print frame-info set to source-line and address off"
+
diff --git a/gdb/testsuite/gdb.python/py-framefilter.exp b/gdb/testsuite/gdb.python/py-framefilter.exp
index a88e37f8c2..400c9b0941 100644
--- a/gdb/testsuite/gdb.python/py-framefilter.exp
+++ b/gdb/testsuite/gdb.python/py-framefilter.exp
@@ -161,6 +161,10 @@ gdb_test "bt full hide" \
".*#0.*end_func.*str = $hex \"The End\".*st2 = $hex \"Is Near\".*b = 12.*c = 5.*#1.*in funca \\(\\).*#2.*in funcb \\(j=10\\).*bar = \{a = 42, b = 84\}.*#22.*in func1 \\(\\)\[^#\]*#24.*in func3 \\(i=3\\).*" \
"bt full hide with Reverse disabled"
+# Re-enable Reverse
+gdb_test_no_output "enable frame-filter global Reverse" \
+ "re-enable frame-filter global Reverse"
+
# Test set print frame-arguments
# none
gdb_test_no_output "set print frame-arguments none" \
@@ -169,7 +173,7 @@ gdb_test "bt no-filter 1" \
"#0.*end_func \\(foo=\.\.\., bar=\.\.\., fb=\.\.\., bf=\.\.\.\\) at .*py-framefilter.c.*" \
"bt no-filter 1 no args"
gdb_test "bt 1" \
- "#0.*end_func \\(foo=\.\.\., bar=\.\.\., fb=\.\.\., bf=\.\.\.\\) at .*py-framefilter.c.*" \
+ "#0.*cnuf_dneThe End \\(foo=\.\.\., bar=\.\.\., fb=\.\.\., bf=\.\.\.\\) at .*py-framefilter.c.*" \
"bt 1 no args"
# scalars
@@ -179,9 +183,54 @@ gdb_test "bt no-filter 1" \
"#0.*end_func \\(foo=21, bar=$hex \"Param\", fb=$hex, bf=\.\.\.\\) at .*py-framefilter.c.*" \
"bt no-filter 1 scalars"
gdb_test "bt 1" \
- "#0.*end_func \\(foo=21, bar=$hex \"Param\", fb=$hex, bf=\.\.\.\\) at .*py-framefilter.c.*" \
+ "#0.*cnuf_dneThe End \\(foo=21, bar=$hex \"Param\", fb=$hex, bf=\.\.\.\\) at .*py-framefilter.c.*" \
"bt 1 scalars"
+# presence
+gdb_test_no_output "set print frame-arguments presence" \
+ "turn frame arguments to presence only"
+gdb_test "bt no-filter 1" \
+ "#0.*end_func \\(\.\.\.\\) at .*py-framefilter.c.*" \
+ "bt no-filter 1 presence"
+gdb_test "bt 1" \
+ "#0.*cnuf_dneThe End \\(\.\.\.\\) at .*py-framefilter.c.*" \
+ "bt 1 presence"
+
+# Test set print frame-info, with only presence for args.
+# short-location
+gdb_test_no_output "set print frame-info short-location" \
+ "frame-info short-location"
+gdb_test "bt no-filter 1" \
+ "#0.*end_func \\(\.\.\.\\)\r\n.*" \
+ "bt no-filter 1 short-location"
+gdb_test "bt 1" \
+ "#0.*cnuf_dneThe End \\(\.\.\.\\)\r\n.*" \
+ "bt 1 short-location"
+
+# source-and-location
+gdb_test_no_output "set print frame-info source-and-location" \
+ "frame-info source-and-location"
+gdb_test "bt no-filter 1" \
+ "#0.*end_func \\(\.\.\.\\) at .*py-framefilter.c.*\r\n.*\[1-9\]\[0-9\]*.*" \
+ "bt no-filter 1 source-and-location"
+gdb_test "bt 1" \
+ "#0.*cnuf_dneThe End \\(\.\.\.\\) at .*py-framefilter.c.*\r\n.*\[1-9\]\[0-9\]*.*" \
+ "bt 1 source-and-location"
+
+# source-line
+gdb_test_no_output "set print frame-info source-line" \
+ "frame-info source-line"
+gdb_test "bt no-filter 1" \
+ "\[1-9\]\[0-9\]*\[ \t\]*return; /\\* Backtrace end breakpoint \\*/.*" \
+ "bt no-filter 1 source-line"
+gdb_test "bt 1" \
+ "\[1-9\]\[0-9\]*\[ \t\]*return; /\\* Backtrace end breakpoint \\*/.*" \
+ "bt 1 source-line"
+
+# set print frame-info back to auto.
+gdb_test_no_output "set print frame-info auto" \
+ "frame-info auto"
+
# all
gdb_test_no_output "set print frame-arguments all" \
"turn on frame arguments"
@@ -189,7 +238,7 @@ gdb_test "bt no-filter 1" \
"#0.*end_func \\(foo=21, bar=$hex \"Param\", fb=$hex, bf=\{nothing = $hex \"Foo Bar\", f = 42, s = 19\}\\) at .*py-framefilter.c.*" \
"bt no-filter 1 all args"
gdb_test "bt 1" \
- "#0.*end_func \\(foo=21, bar=$hex \"Param\", fb=$hex, bf=\{nothing = $hex \"Foo Bar\", f = 42, s = 19\}\\) at .*py-framefilter.c.*" \
+ "#0.*cnuf_dneThe End \\(foo=21, bar=$hex \"Param\", fb=$hex, bf=\{nothing = $hex \"Foo Bar\", f = 42, s = 19\}\\) at .*py-framefilter.c.*" \
"bt 1 all args"
# set print address off
@@ -199,7 +248,7 @@ gdb_test "bt no-filter 1" \
"#0 end_func \\(foo=21, bar=\"Param\", fb=, bf=\{nothing = \"Foo Bar\", f = 42, s = 19\}\\) at .*py-framefilter.c.*" \
"bt no-filter 1 no address"
gdb_test "bt 1" \
- "#0 end_func \\(foo=21, bar=\"Param\", fb=, bf=\{nothing = \"Foo Bar\", f = 42, s = 19\}\\) at .*py-framefilter.c.*" \
+ "#0 cnuf_dneThe End \\(foo=21, bar=\"Param\", fb=, bf=\{nothing = \"Foo Bar\", f = 42, s = 19\}\\) at .*py-framefilter.c.*" \
"bt 1 no addresss"
gdb_test_no_output "set python print-stack message" \
--
2.20.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFAv2 3/3] Document 'set print frame-info|frame-arguments presence'.
2019-05-11 18:56 ` [RFAv2 3/3] Document 'set print frame-info|frame-arguments presence' Philippe Waroquiers
@ 2019-05-11 19:18 ` Eli Zaretskii
0 siblings, 0 replies; 9+ messages in thread
From: Eli Zaretskii @ 2019-05-11 19:18 UTC (permalink / raw)
To: Philippe Waroquiers; +Cc: gdb-patches
> From: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Cc: Philippe Waroquiers <philippe.waroquiers@skynet.be>
> Date: Sat, 11 May 2019 20:56:03 +0200
>
> ---
> gdb/NEWS | 13 ++++++++++
> gdb/doc/ChangeLog | 5 ++++
> gdb/doc/gdb.texinfo | 58 ++++++++++++++++++++++++++++++++++++++++++---
> 3 files changed, 73 insertions(+), 3 deletions(-)
OK.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFAv2 2/3] Test 'set print frame-info|frame-arguments presence'.
2019-05-11 18:56 ` [RFAv2 2/3] Test " Philippe Waroquiers
@ 2019-06-04 17:15 ` Tom Tromey
0 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2019-06-04 17:15 UTC (permalink / raw)
To: Philippe Waroquiers; +Cc: gdb-patches
>>>>> "Philippe" == Philippe Waroquiers <philippe.waroquiers@skynet.be> writes:
Philippe> ---
I think it's good to have some commit message.
Otherwise this looks fine. Thank you.
Tom
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFAv2 1/3] Implement 'set print frame-info|frame-arguments presence'.
2019-05-11 18:56 ` [RFAv2 1/3] Implement " Philippe Waroquiers
@ 2019-06-04 17:15 ` Tom Tromey
2019-06-10 12:48 ` Philippe Waroquiers
0 siblings, 1 reply; 9+ messages in thread
From: Tom Tromey @ 2019-06-04 17:15 UTC (permalink / raw)
To: Philippe Waroquiers; +Cc: gdb-patches
>>>>> "Philippe" == Philippe Waroquiers <philippe.waroquiers@skynet.be> writes:
Philippe> New settings allow to better control what frame information is printed.
Philippe> 'set print frame-info' allows to override the default frame information
Philippe> printed when a GDB command prints a frame.
Thanks for the patch.
I wanted to mention - in the last series, I noticed that the ChangeLog
entries didn't wind up in the commit messages. I think it is a gdb
standard to do that, so please make sure it happens for future pushes.
I realize this is a bit of a pain, but various people have scripts for
automating it, I believe, and so you can pretty much pick one approach
that appeals to you.
Philippe> + if (args_type == CLI_PRESENCE)
Philippe> + {
Philippe> + if (args_iter != Py_None)
Philippe> + {
Philippe> + if (PyIter_Next (args_iter.get ()) != NULL)
This causes a memory leak, because PyIter_Next returns a new reference.
You can wrap it in a gdbpy_ref<> to avoid this problem.
Sometimes I think we just use wrapper functions for the Python API that
let us spell out this stuff in the type system.
Philippe> + /* Note that this print_what default implies that 'bt' and 'bt no-filters'
Philippe> + shows different information, as the default for 'bt no-filters
Philippe> + is LOCATION. */
Philippe> + enum print_what print_what = LOC_AND_ADDRESS;
Is this a pre-existing bug? It seems like something we should change,
since my believe is that "no filters" should produce the same output as
the situation where there are actually no filters installed.
Tom
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFAv2 1/3] Implement 'set print frame-info|frame-arguments presence'.
2019-06-04 17:15 ` Tom Tromey
@ 2019-06-10 12:48 ` Philippe Waroquiers
2019-06-10 20:10 ` Tom Tromey
0 siblings, 1 reply; 9+ messages in thread
From: Philippe Waroquiers @ 2019-06-10 12:48 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
On Tue, 2019-06-04 at 11:11 -0600, Tom Tromey wrote:
> > > > > > "Philippe" == Philippe Waroquiers <philippe.waroquiers@skynet.be> writes:
>
> Philippe> New settings allow to better control what frame information is printed.
> Philippe> 'set print frame-info' allows to override the default frame information
> Philippe> printed when a GDB command prints a frame.
>
> Thanks for the patch.
>
> I wanted to mention - in the last series, I noticed that the ChangeLog
> entries didn't wind up in the commit messages. I think it is a gdb
> standard to do that, so please make sure it happens for future pushes.
Sorry, I thought that having the ChangeLog file was sufficient.
I will ensure that it is done in the future.
>
> I realize this is a bit of a pain, but various people have scripts for
> automating it, I believe, and so you can pretty much pick one approach
> that appeals to you.
>
> Philippe> + if (args_type == CLI_PRESENCE)
> Philippe> + {
> Philippe> + if (args_iter != Py_None)
> Philippe> + {
> Philippe> + if (PyIter_Next (args_iter.get ()) != NULL)
>
> This causes a memory leak, because PyIter_Next returns a new reference.
> You can wrap it in a gdbpy_ref<> to avoid this problem.
Fixed.
(Note that also for this patch series, I will wait for Pedro to push cli-option
to avoid pushing merge conflicts to him).
>
> Sometimes I think we just use wrapper functions for the Python API that
> let us spell out this stuff in the type system.
>
> Philippe> + /* Note that this print_what default implies that 'bt' and 'bt no-filters'
> Philippe> + shows different information, as the default for 'bt no-filters
> Philippe> + is LOCATION. */
> Philippe> + enum print_what print_what = LOC_AND_ADDRESS;
>
> Is this a pre-existing bug? It seems like something we should change,
> since my believe is that "no filters" should produce the same output as
> the situation where there are actually no filters installed.
Yes, it is a pre-existing "bug", but the difference of behaviour is
between 'bt' and 'bt no-filters' *when there are some filters*.
here is a log with the HEAD:
(gdb) bt
#0Â Â 0x000055555555548e in niam (argc=1, argv=0x7fffffffe0d8) at sleepers.c:194
(gdb) bt no-filters
#0Â Â main (argc=1, argv=0x7fffffffe0d8) at sleepers.c:194
(gdb) p $pc
$1 = (void (*)()) 0x55555555548e <main+823>
(gdb) frame
#0Â Â main (argc=1, argv=0x7fffffffe0d8) at sleepers.c:194
194 Â Â sleeper_or_burner(&m);
(gdb) info line
Line 194 of "sleepers.c" starts at address 0x55555555548e <main+823> and ends at
0x55555555549d <main+838>.
(gdb)Â
As you can see, the first 'bt' is applying a filter (the 'Reverse' filter
of gdb/testsuite/gdb.python/py-framefilter.py), and shows the address,
while the 'bt no-filters' does not show the address.
This difference of behaviour will be visible as long as there is
one filter active, even if the filter is a 'no effect' filter.
This is because backtrace_command_1 calls apply_ext_lang_frame_filter.
If this finds at least one active filter, it will print the frame itself
by calling py_print_frame.
If there are no active filter or with 'bt no-filters', backtrace_command_1
calls 'print_frame_info (..., LOCATION, ...).
So, the GDB HEAD has a different default way to print a frame
when it is printed by py_print_frame or by stack.c print_frame_info.
The 'set print frame-info auto' setting aims at keeping a backward
compatible behaviour : in GDB HEAD, different commands have different
behaviours, and 'auto' means to let each command decide by itself
what to do.
If the user chooses a specific value (e.g. 'set print frame-info location'),
then with this patch, the python frame filtering will do what the user wants.
So, the question is: do we want to change the default output behaviour
of python frame filters to be LOCATION ?
That is of course a user visible change.
Philippe
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFAv2 1/3] Implement 'set print frame-info|frame-arguments presence'.
2019-06-10 12:48 ` Philippe Waroquiers
@ 2019-06-10 20:10 ` Tom Tromey
0 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2019-06-10 20:10 UTC (permalink / raw)
To: Philippe Waroquiers; +Cc: Tom Tromey, gdb-patches
>>>>> "Philippe" == Philippe Waroquiers <philippe.waroquiers@skynet.be> writes:
>> Is this a pre-existing bug? It seems like something we should change,
>> since my believe is that "no filters" should produce the same output as
>> the situation where there are actually no filters installed.
Philippe> Yes, it is a pre-existing "bug", but the difference of behaviour is
Philippe> between 'bt' and 'bt no-filters' *when there are some filters*.
[...]
Philippe> This difference of behaviour will be visible as long as there is
Philippe> one filter active, even if the filter is a 'no effect' filter.
Philippe> So, the question is: do we want to change the default output behaviour
Philippe> of python frame filters to be LOCATION ?
Philippe> That is of course a user visible change.
Yes, I think this ought to change. Installing a "no effect" filter
should not have any effect on the output.
Tom
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2019-06-10 20:10 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-11 18:56 [RFAv2 0/3] Implement 'set print frame-info|frame-arguments Philippe Waroquiers
2019-05-11 18:56 ` [RFAv2 3/3] Document 'set print frame-info|frame-arguments presence' Philippe Waroquiers
2019-05-11 19:18 ` Eli Zaretskii
2019-05-11 18:56 ` [RFAv2 2/3] Test " Philippe Waroquiers
2019-06-04 17:15 ` Tom Tromey
2019-05-11 18:56 ` [RFAv2 1/3] Implement " Philippe Waroquiers
2019-06-04 17:15 ` Tom Tromey
2019-06-10 12:48 ` Philippe Waroquiers
2019-06-10 20:10 ` Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).