mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-12-19 01:19:41 +08:00
Fix raw-frame-arguments in combination with frame-filters
Currently, if frame-filters are active, raw-values is used instead of
raw-frame-arguments to decide if a pretty-printer should be invoked for
frame arguments in a backtrace.
In this example, "super struct" is the output of the pretty-printer:
(gdb) disable frame-filter global BasicFrameFilter
(gdb) bt
#0 foo (x=42, ss=super struct = {...}) at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:47
#1 0x004016aa in main () at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:57
If no frame-filter is active, then the raw-values print option does not
affect the backtrace output:
(gdb) set print raw-values on
(gdb) bt
#0 foo (x=42, ss=super struct = {...}) at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:47
#1 0x004016aa in main () at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:57
(gdb) set print raw-values off
Instead, the raw-frame-arguments option disables the pretty-printer in the
backtrace:
(gdb) bt -raw-frame-arguments on
#0 foo (x=42, ss=...) at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:47
#1 0x004016aa in main () at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:57
But if a frame-filter is active, the same rules don't apply.
The option raw-frame-arguments is ignored, but raw-values decides if the
pretty-printer is used:
(gdb) enable frame-filter global BasicFrameFilter
(gdb) bt
#0 foo (x=42, ss=super struct = {...}) at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:47
#1 0x004016aa in main () at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:57
(gdb) set print raw-values on
(gdb) bt
#0 foo (x=42, ss=...) at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:47
#1 0x004016aa in main () at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:57
(gdb) set print raw-values off
(gdb) bt -raw-frame-arguments on
#0 foo (x=42, ss=super struct = {...}) at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:47
#1 0x004016aa in main () at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:57
So this adds the PRINT_RAW_FRAME_ARGUMENTS flag to frame_filter_flag, which
is then used in the frame-filter to override the raw flag in enumerate_args.
Then the output is the same if a frame-filter is active, the pretty-printer
for backtraces is only disabled with the raw-frame-arguments option:
(gdb) enable frame-filter global BasicFrameFilter
(gdb) bt
#0 foo (x=42, ss=super struct = {...}) at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:47
#1 0x004016aa in main () at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:57
(gdb) set print raw-values on
(gdb) bt
#0 foo (x=42, ss=super struct = {...}) at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:47
#1 0x004016aa in main () at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:57
(gdb) set print raw-values off
(gdb) bt -raw-frame-arguments on
#0 foo (x=42, ss=...) at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:47
#1 0x004016aa in main () at C:/src/repos/gdb-testsuite/gdb/testsuite/gdb.python/py-frame-args.c:57
Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
Approved-By: Tom Tromey <tom@tromey.com>
This commit is contained in:
@@ -103,6 +103,10 @@ enum frame_filter_flag
|
||||
|
||||
/* Set this flag if elided frames should not be printed. */
|
||||
PRINT_HIDE = 1 << 5,
|
||||
|
||||
/* Set this flag if pretty printers for frame arguments should not
|
||||
be invoked. */
|
||||
PRINT_RAW_FRAME_ARGUMENTS = 1 << 6,
|
||||
};
|
||||
|
||||
DEF_ENUM_FLAGS_TYPE (enum frame_filter_flag, frame_filter_flags);
|
||||
|
||||
@@ -372,6 +372,8 @@ mi_cmd_stack_list_args (const char *command, const char *const *argv, int argc)
|
||||
if (! raw_arg && frame_filters)
|
||||
{
|
||||
frame_filter_flags flags = PRINT_LEVEL | PRINT_ARGS;
|
||||
if (user_frame_print_options.print_raw_frame_arguments)
|
||||
flags |= PRINT_RAW_FRAME_ARGUMENTS;
|
||||
int py_frame_low = frame_low;
|
||||
|
||||
/* We cannot pass -1 to frame_low, as that would signify a
|
||||
@@ -466,6 +468,8 @@ mi_cmd_stack_list_variables (const char *command, const char *const *argv,
|
||||
if (! raw_arg && frame_filters)
|
||||
{
|
||||
frame_filter_flags flags = PRINT_LEVEL | PRINT_ARGS | PRINT_LOCALS;
|
||||
if (user_frame_print_options.print_raw_frame_arguments)
|
||||
flags |= PRINT_RAW_FRAME_ARGUMENTS;
|
||||
|
||||
result = mi_apply_ext_lang_frame_filter (frame, flags,
|
||||
print_value,
|
||||
@@ -491,7 +495,8 @@ mi_cmd_stack_list_variables (const char *command, const char *const *argv,
|
||||
|
||||
static void
|
||||
list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
|
||||
enum print_values values, int skip_unavailable)
|
||||
enum print_values values, int skip_unavailable,
|
||||
const frame_print_options &fp_opts)
|
||||
{
|
||||
struct ui_out *uiout = current_uiout;
|
||||
|
||||
@@ -548,6 +553,8 @@ list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
|
||||
|
||||
get_no_prettyformat_print_options (&opts);
|
||||
opts.deref_ref = true;
|
||||
if (arg->sym->is_argument ())
|
||||
opts.raw = fp_opts.print_raw_frame_arguments;
|
||||
common_val_print (arg->val, &stb, 0, &opts,
|
||||
language_def (arg->sym->language ()));
|
||||
}
|
||||
@@ -664,9 +671,11 @@ list_args_or_locals (const frame_print_options &fp_opts,
|
||||
}
|
||||
|
||||
if (arg.entry_kind != print_entry_values_only)
|
||||
list_arg_or_local (&arg, what, values, skip_unavailable);
|
||||
list_arg_or_local (&arg, what, values, skip_unavailable,
|
||||
fp_opts);
|
||||
if (entryarg.entry_kind != print_entry_values_no)
|
||||
list_arg_or_local (&entryarg, what, values, skip_unavailable);
|
||||
list_arg_or_local (&entryarg, what, values, skip_unavailable,
|
||||
fp_opts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -414,12 +414,14 @@ static enum ext_lang_bt_status
|
||||
enumerate_args (PyObject *iter,
|
||||
struct ui_out *out,
|
||||
enum ext_lang_frame_args args_type,
|
||||
bool raw_frame_args,
|
||||
int print_args_field,
|
||||
frame_info_ptr frame)
|
||||
{
|
||||
struct value_print_options opts;
|
||||
|
||||
get_user_print_options (&opts);
|
||||
opts.raw = raw_frame_args;
|
||||
|
||||
if (args_type == CLI_SCALAR_VALUES)
|
||||
{
|
||||
@@ -634,7 +636,8 @@ static enum ext_lang_bt_status
|
||||
py_mi_print_variables (PyObject *filter, struct ui_out *out,
|
||||
struct value_print_options *opts,
|
||||
enum ext_lang_frame_args args_type,
|
||||
frame_info_ptr frame)
|
||||
frame_info_ptr frame,
|
||||
bool raw_frame_args_p)
|
||||
{
|
||||
gdbpy_ref<> args_iter (get_py_iter_from_func (filter, "frame_args"));
|
||||
if (args_iter == NULL)
|
||||
@@ -647,8 +650,8 @@ py_mi_print_variables (PyObject *filter, struct ui_out *out,
|
||||
ui_out_emit_list list_emitter (out, "variables");
|
||||
|
||||
if (args_iter != Py_None
|
||||
&& (enumerate_args (args_iter.get (), out, args_type, 1, frame)
|
||||
== EXT_LANG_BT_ERROR))
|
||||
&& (enumerate_args (args_iter.get (), out, args_type, raw_frame_args_p,
|
||||
1, frame) == EXT_LANG_BT_ERROR))
|
||||
return EXT_LANG_BT_ERROR;
|
||||
|
||||
if (locals_iter != Py_None
|
||||
@@ -693,6 +696,7 @@ static enum ext_lang_bt_status
|
||||
py_print_args (PyObject *filter,
|
||||
struct ui_out *out,
|
||||
enum ext_lang_frame_args args_type,
|
||||
bool raw_frame_args,
|
||||
frame_info_ptr frame)
|
||||
{
|
||||
gdbpy_ref<> args_iter (get_py_iter_from_func (filter, "frame_args"));
|
||||
@@ -718,7 +722,8 @@ py_print_args (PyObject *filter,
|
||||
}
|
||||
}
|
||||
else if (args_iter != Py_None
|
||||
&& (enumerate_args (args_iter.get (), out, args_type, 0, frame)
|
||||
&& (enumerate_args (args_iter.get (), out, args_type,
|
||||
raw_frame_args, 0, frame)
|
||||
== EXT_LANG_BT_ERROR))
|
||||
return EXT_LANG_BT_ERROR;
|
||||
|
||||
@@ -802,8 +807,9 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
|
||||
/* stack-list-variables. */
|
||||
if (print_locals && print_args && ! print_frame_info)
|
||||
{
|
||||
if (py_mi_print_variables (filter, out, &opts,
|
||||
args_type, frame) == EXT_LANG_BT_ERROR)
|
||||
bool raw_frame_args = (flags & PRINT_RAW_FRAME_ARGUMENTS) != 0;
|
||||
if (py_mi_print_variables (filter, out, &opts, args_type, frame,
|
||||
raw_frame_args) == EXT_LANG_BT_ERROR)
|
||||
return EXT_LANG_BT_ERROR;
|
||||
return EXT_LANG_BT_OK;
|
||||
}
|
||||
@@ -949,7 +955,9 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
|
||||
wrong. */
|
||||
if (print_args && (location_print || out->is_mi_like_p ()))
|
||||
{
|
||||
if (py_print_args (filter, out, args_type, frame) == EXT_LANG_BT_ERROR)
|
||||
bool raw_frame_args = (flags & PRINT_RAW_FRAME_ARGUMENTS) != 0;
|
||||
if (py_print_args (filter, out, args_type, raw_frame_args, frame)
|
||||
== EXT_LANG_BT_ERROR)
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -2016,6 +2016,8 @@ backtrace_command_1 (const frame_print_options &fp_opts,
|
||||
flags |= PRINT_LOCALS;
|
||||
if (bt_opts.hide)
|
||||
flags |= PRINT_HIDE;
|
||||
if (fp_opts.print_raw_frame_arguments)
|
||||
flags |= PRINT_RAW_FRAME_ARGUMENTS;
|
||||
|
||||
if (!bt_opts.no_filters)
|
||||
{
|
||||
|
||||
@@ -33,6 +33,42 @@ gdb_test_no_output "source ${remote_python_file}" "load python file"
|
||||
gdb_breakpoint [gdb_get_line_number "break-here"]
|
||||
gdb_continue_to_breakpoint "break-here" ".* break-here .*"
|
||||
|
||||
# Test raw-frame-arguments on backtrace with and without frame-filter
|
||||
gdb_test "interpreter-exec mi \"-enable-frame-filters\"" \
|
||||
"done"
|
||||
foreach_with_prefix filtered {enable disable} {
|
||||
gdb_test_no_output "$filtered frame-filter global BasicFrameFilter"
|
||||
|
||||
gdb_test "bt 1" \
|
||||
".*foo \\(x=42, ss=super struct = {\[.\]{3}}\\).*" \
|
||||
"bt pretty"
|
||||
|
||||
gdb_test "bt -raw-frame-arguments on 1" \
|
||||
".*foo \\(x=42, ss=\[.\]{3}\\).*" \
|
||||
"bt raw"
|
||||
|
||||
gdb_test "interpreter-exec mi \"-stack-list-arguments 1\"" \
|
||||
".*name=\"ss\",value=\"super struct =.*" \
|
||||
"mi bt pretty"
|
||||
|
||||
gdb_test_no_output "set print raw-frame-arguments on"
|
||||
gdb_test "interpreter-exec mi \"-stack-list-arguments 1\"" \
|
||||
".*name=\"ss\",value=\".a =.*" \
|
||||
"mi bt raw"
|
||||
gdb_test_no_output "set print raw-frame-arguments off"
|
||||
|
||||
# "set print raw-values" should not affect frame arguments
|
||||
gdb_test_no_output "set print raw-values on"
|
||||
gdb_test "bt 1" \
|
||||
".*foo \\(x=42, ss=super struct = {\[.\]{3}}\\).*" \
|
||||
"bt pretty,raw-values"
|
||||
|
||||
gdb_test "interpreter-exec mi \"-stack-list-arguments 1\"" \
|
||||
".*name=\"ss\",value=\"super struct =.*" \
|
||||
"mi bt pretty,raw-values"
|
||||
gdb_test_no_output "set print raw-values off"
|
||||
}
|
||||
|
||||
# Test all combinations with raw off.
|
||||
|
||||
gdb_test_no_output "set print raw-frame-arguments off"
|
||||
|
||||
@@ -76,3 +76,17 @@ pretty_printers_dict = {}
|
||||
|
||||
register_pretty_printers()
|
||||
gdb.pretty_printers.append(lookup_function)
|
||||
|
||||
|
||||
class BasicFrameFilter(object):
|
||||
def __init__(self):
|
||||
self.name = "BasicFrameFilter"
|
||||
self.priority = 100
|
||||
self.enabled = True
|
||||
gdb.frame_filters[self.name] = self
|
||||
|
||||
def filter(self, frame_iter):
|
||||
return frame_iter
|
||||
|
||||
|
||||
BasicFrameFilter()
|
||||
|
||||
Reference in New Issue
Block a user