#include "observable.h"
#include "gdbsupport/def-vector.h"
#include "cli/cli-option.h"
+#include "cli/cli-style.h"
/* The possible choices of "set print frame-arguments", and the value
of this setting. */
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. */
print_entry_values_choices,
[] (frame_print_options *opt) { return &opt->print_entry_values; },
NULL, /* show_cmd_cb */
- N_("Set printing of function arguments at function entry"),
- N_("Show printing of function arguments at function entry"),
+ N_("Set printing of function arguments at function entry."),
+ N_("Show printing of function arguments at function entry."),
N_("GDB can sometimes determine the values of function arguments at entry,\n\
in addition to their current values. This option tells GDB whether\n\
to print the current value, the value at entry (marked as val@entry),\n\
print_frame_arguments_choices,
[] (frame_print_options *opt) { return &opt->print_frame_arguments; },
NULL, /* show_cmd_cb */
- N_("Set printing of non-scalar frame arguments"),
- N_("Show printing of non-scalar frame arguments"),
+ N_("Set printing of non-scalar frame arguments."),
+ N_("Show printing of non-scalar frame arguments."),
NULL /* help_doc */
},
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. */
struct backtrace_cmd_options
{
- int full = 0;
- int no_filters = 0;
- int hide = 0;
+ bool full = false;
+ bool no_filters = false;
+ bool hide = false;
};
using bt_flag_option_def
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)
{
if (arg->entry_kind == print_entry_values_only
|| arg->entry_kind == print_entry_values_compact)
stb.puts ("@entry");
- uiout->field_stream ("name", stb, ui_out_style_kind::VARIABLE);
+ uiout->field_stream ("name", stb, variable_name_style.style ());
annotate_arg_name_end ();
uiout->text ("=");
+ ui_file_style style;
if (!arg->val && !arg->error)
uiout->text ("...");
else
{
if (arg->error)
- stb.printf (_("<error reading variable: %s>"), arg->error);
+ {
+ stb.printf (_("<error reading variable: %s>"), arg->error.get ());
+ style = metadata_style.style ();
+ }
else
{
try
{
stb.printf (_("<error reading variable: %s>"),
except.what ());
+ style = metadata_style.style ();
}
}
}
- uiout->field_stream ("value", stb);
+ uiout->field_stream ("value", stb, style);
}
/* Read in inferior function local SYM at FRAME into ARGP. Caller is
}
catch (const gdb_exception_error &except)
{
- argp->error = xstrdup (except.what ());
+ argp->error.reset (xstrdup (except.what ()));
}
}
-/* Read in inferior function parameter SYM at FRAME into ARGP. Caller is
- responsible for xfree of ARGP->ERROR. This function never throws an
- exception. */
+/* Read in inferior function parameter SYM at FRAME into ARGP. This
+ function never throws an exception. */
void
read_frame_arg (const frame_print_options &fp_opts,
argp->sym = sym;
argp->val = val;
- argp->error = val_error ? xstrdup (val_error) : NULL;
+ argp->error.reset (val_error ? xstrdup (val_error) : NULL);
if (!val && !val_error)
argp->entry_kind = print_entry_values_only;
else if ((fp_opts.print_entry_values == print_entry_values_compact
entryargp->sym = sym;
entryargp->val = entryval;
- entryargp->error = entryval_error ? xstrdup (entryval_error) : NULL;
+ entryargp->error.reset (entryval_error ? xstrdup (entryval_error) : NULL);
if (!entryval && !entryval_error)
entryargp->entry_kind = print_entry_values_no;
else
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)
{
if (!SYMBOL_IS_ARGUMENT (sym))
continue;
+ if (!print_names)
+ {
+ uiout->text ("...");
+ first = 0;
+ break;
+ }
+
switch (SYMBOL_CLASS (sym))
{
case LOC_ARG:
if (!print_args)
{
- memset (&arg, 0, sizeof (arg));
arg.sym = sym;
arg.entry_kind = print_entry_values_no;
- memset (&entryarg, 0, sizeof (entryarg));
entryarg.sym = sym;
entryarg.entry_kind = print_entry_values_no;
}
print_frame_arg (fp_opts, &entryarg);
}
- xfree (arg.error);
- xfree (entryarg.error);
-
first = 0;
}
}
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);
}
}
}
}
+/* 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);
+}
+
+/* Print the PC from FRAME, plus any flags, to UIOUT. */
+
+static void
+print_pc (struct ui_out *uiout, struct gdbarch *gdbarch, frame_info *frame,
+ CORE_ADDR pc)
+{
+ uiout->field_core_addr ("addr", gdbarch, pc);
+
+ std::string flags = gdbarch_get_pc_address_flags (gdbarch, frame, pc);
+ if (!flags.empty ())
+ {
+ uiout->text (" [");
+ uiout->field_string ("addr_flags", flags);
+ uiout->text ("]");
+ }
+}
+
+/* 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. */
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)
if (uiout->is_mi_like_p ())
{
annotate_frame_address ();
- uiout->field_core_addr ("addr",
- gdbarch, get_frame_pc (frame));
+ print_pc (uiout, gdbarch, frame, get_frame_pc (frame));
annotate_frame_address_end ();
}
{
annotate_function_call ();
uiout->field_string ("func", "<function called from gdb>",
- ui_out_style_kind::FUNCTION);
+ metadata_style.style ());
}
else if (get_frame_type (frame) == SIGTRAMP_FRAME)
{
annotate_signal_handler_caller ();
uiout->field_string ("func", "<signal handler called>",
- ui_out_style_kind::FUNCTION);
+ metadata_style.style ());
}
else if (get_frame_type (frame) == ARCH_FRAME)
{
uiout->field_string ("func", "<cross-architecture call>",
- ui_out_style_kind::FUNCTION);
+ metadata_style.style ());
}
uiout->text ("\n");
annotate_frame_end ();
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);
ability to decide for themselves if it is desired. */
if (opts.addressprint && mid_statement)
{
- uiout->field_core_addr ("addr",
- gdbarch, get_frame_pc (frame));
+ print_pc (uiout, gdbarch, frame, get_frame_pc (frame));
uiout->text ("\t");
}
func = get_frame_function (frame);
if (func)
{
- /* In certain pathological cases, the symtabs give the wrong
- function (when we are in the first function in a file which
- is compiled without debugging symbols, the previous function
- is compiled with debugging symbols, and the "foo.o" symbol
- that is supposed to tell us where the file with debugging
- symbols ends has been truncated by ar because it is longer
- than 15 characters). This also occurs if the user uses asm()
- to create a function but not stabs for it (in a file compiled
- with -g).
-
- So look in the minimal symbol tables as well, and if it comes
- up with a larger address for the function use that instead.
- I don't think this can ever cause any problems; there
- shouldn't be any minimal symbols in the middle of a function;
- if this is ever changed many parts of GDB will need to be
- changed (and we'll create a find_pc_minimal_function or some
- such). */
-
- struct bound_minimal_symbol msymbol;
-
- /* Don't attempt to do this for inlined functions, which do not
- have a corresponding minimal symbol. */
- if (!block_inlined_p (SYMBOL_BLOCK_VALUE (func)))
- msymbol
- = lookup_minimal_symbol_by_pc (get_frame_address_in_block (frame));
- else
- memset (&msymbol, 0, sizeof (msymbol));
+ const char *print_name = SYMBOL_PRINT_NAME (func);
- if (msymbol.minsym != NULL
- && (BMSYMBOL_VALUE_ADDRESS (msymbol)
- > BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (func))))
+ *funlang = SYMBOL_LANGUAGE (func);
+ if (funcp)
+ *funcp = func;
+ if (*funlang == language_cplus)
{
- /* We also don't know anything about the function besides
- its address and name. */
- func = 0;
- funname.reset (xstrdup (MSYMBOL_PRINT_NAME (msymbol.minsym)));
- *funlang = MSYMBOL_LANGUAGE (msymbol.minsym);
+ /* It seems appropriate to use SYMBOL_PRINT_NAME() here,
+ to display the demangled name that we already have
+ stored in the symbol table, but we stored a version
+ with DMGL_PARAMS turned on, and here we don't want to
+ display parameters. So remove the parameters. */
+ funname = cp_remove_params (print_name);
}
- else
- {
- const char *print_name = SYMBOL_PRINT_NAME (func);
- *funlang = SYMBOL_LANGUAGE (func);
- if (funcp)
- *funcp = func;
- if (*funlang == language_cplus)
- {
- /* It seems appropriate to use SYMBOL_PRINT_NAME() here,
- to display the demangled name that we already have
- stored in the symbol table, but we stored a version
- with DMGL_PARAMS turned on, and here we don't want to
- display parameters. So remove the parameters. */
- funname = cp_remove_params (print_name);
- }
-
- /* If we didn't hit the C++ case above, set *funname
- here. */
- if (funname == NULL)
- funname.reset (xstrdup (print_name));
- }
+ /* If we didn't hit the C++ case above, set *funname
+ here. */
+ if (funname == NULL)
+ funname.reset (xstrdup (print_name));
}
else
{
{
annotate_frame_address ();
if (pc_p)
- uiout->field_core_addr ("addr", gdbarch, pc);
+ print_pc (uiout, gdbarch, frame, pc);
else
uiout->field_string ("addr", "<unavailable>",
- ui_out_style_kind::ADDRESS);
+ metadata_style.style ());
annotate_frame_address_end ();
uiout->text (" in ");
}
string_file stb;
fprintf_symbol_filtered (&stb, funname ? funname.get () : "??",
funlang, DMGL_ANSI);
- uiout->field_stream ("func", stb, ui_out_style_kind::FUNCTION);
+ uiout->field_stream ("func", stb, function_name_style.style ());
uiout->wrap_hint (" ");
annotate_frame_args ();
QUIT;
}
uiout->text (")");
- if (sal.symtab)
+ if (print_what != SHORT_LOCATION && sal.symtab)
{
const char *filename_display;
uiout->wrap_hint (" ");
uiout->text (" at ");
annotate_frame_source_file ();
- uiout->field_string ("file", filename_display, ui_out_style_kind::FILE);
+ uiout->field_string ("file", filename_display,
+ file_name_style.style ());
if (uiout->is_mi_like_p ())
{
const char *fullname = symtab_to_fullname (sal.symtab);
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));
annotate_frame_where ();
uiout->wrap_hint (" ");
uiout->text (" from ");
- uiout->field_string ("from", lib);
+ uiout->field_string ("from", lib, file_name_style.style ());
}
}
if (uiout->is_mi_like_p ())
if (frame_pc_p)
fputs_filtered (paddress (gdbarch, get_frame_pc (fi)), gdb_stdout);
else
- fputs_filtered ("<unavailable>", gdb_stdout);
+ fputs_styled ("<unavailable>", metadata_style.style (), gdb_stdout);
wrap_here (" ");
if (funname)
}
wrap_here (" ");
if (sal.symtab)
- printf_filtered (" (%s:%d)", symtab_to_filename_for_display (sal.symtab),
- sal.line);
+ printf_filtered
+ (" (%ps:%d)",
+ styled_string (file_name_style.style (),
+ symtab_to_filename_for_display (sal.symtab)),
+ sal.line);
puts_filtered ("; ");
wrap_here (" ");
printf_filtered ("saved %s = ", pc_regname);
val_print_not_saved (gdb_stdout);
break;
default:
- fprintf_filtered (gdb_stdout, _("<error: %s>"),
- ex.what ());
+ fprintf_styled (gdb_stdout, metadata_style.style (),
+ _("<error: %s>"),
+ ex.what ());
break;
}
}
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,
}
}
+/* Structure to hold the values of the options used by the 'info
+ variables' command and other similar commands. These correspond to the
+ -q and -t options. */
+
+struct info_print_options
+{
+ bool quiet = false;
+ char *type_regexp = nullptr;
+
+ ~info_print_options ()
+ {
+ xfree (type_regexp);
+ }
+};
+
+/* The options used by the 'info locals' and 'info args' commands. */
+
+static const gdb::option::option_def info_print_options_defs[] = {
+ gdb::option::boolean_option_def<info_print_options> {
+ "q",
+ [] (info_print_options *opt) { return &opt->quiet; },
+ nullptr, /* show_cmd_cb */
+ nullptr /* set_doc */
+ },
+
+ gdb::option::string_option_def<info_print_options> {
+ "t",
+ [] (info_print_options *opt) { return &opt->type_regexp; },
+ nullptr, /* show_cmd_cb */
+ nullptr /* set_doc */
+ }
+};
+
+/* Returns the option group used by 'info locals' and 'info args'
+ commands. */
+
+static gdb::option::option_def_group
+make_info_print_options_def_group (info_print_options *opts)
+{
+ return {{info_print_options_defs}, opts};
+}
+
+/* Command completer for 'info locals' and 'info args'. */
+
+static void
+info_print_command_completer (struct cmd_list_element *ignore,
+ completion_tracker &tracker,
+ const char *text, const char * /* word */)
+{
+ const auto group
+ = make_info_print_options_def_group (nullptr);
+ if (gdb::option::complete_options
+ (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
+ return;
+
+ const char *word = advance_to_expression_complete_word_point (tracker, text);
+ symbol_completer (ignore, tracker, text, word);
+}
+
/* Implement the 'info locals' command. */
void
info_locals_command (const char *args, int from_tty)
{
info_print_options opts;
- extract_info_print_options (&opts, &args);
+ auto grp = make_info_print_options_def_group (&opts);
+ gdb::option::process_options
+ (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+ if (args != nullptr && *args == '\0')
+ args = nullptr;
print_frame_local_vars (get_selected_frame (_("No frame selected.")),
opts.quiet, args, opts.type_regexp,
info_args_command (const char *args, int from_tty)
{
info_print_options opts;
- extract_info_print_options (&opts, &args);
+ auto grp = make_info_print_options_def_group (&opts);
+ gdb::option::process_options
+ (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+ if (args != nullptr && *args == '\0')
+ args = nullptr;
print_frame_arg_vars (get_selected_frame (_("No frame selected.")),
opts.quiet, args, opts.type_regexp, gdb_stdout);
const auto frame_apply_opts
= make_frame_apply_options_def_group (nullptr, nullptr);
- static std::string frame_apply_cmd_help = gdb::option::build_help (N_("\
+ static std::string frame_apply_cmd_help = gdb::option::build_help (_("\
Apply a command to a number of frames.\n\
Usage: frame apply COUNT [OPTION]... COMMAND\n\
With a negative COUNT argument, applies the command on outermost -COUNT frames.\n"
&frame_cmd_list);
set_cmd_completer_handle_brkchars (cmd, frame_apply_cmd_completer);
- static std::string frame_apply_all_cmd_help = gdb::option::build_help (N_("\
+ static std::string frame_apply_all_cmd_help = gdb::option::build_help (_("\
Apply a command to all frames.\n\
\n\
Usage: frame apply all [OPTION]... COMMAND\n"
&frame_apply_cmd_list);
set_cmd_completer_handle_brkchars (cmd, frame_apply_all_cmd_completer);
- static std::string frame_apply_level_cmd_help = gdb::option::build_help (N_("\
+ static std::string frame_apply_level_cmd_help = gdb::option::build_help (_("\
Apply a command to a list of frames.\n\
\n\
Usage: frame apply level LEVEL... [OPTION]... COMMAND\n\
add_cmd ("address", class_stack, &frame_cmd.address,
_("\
-Select and print a stack frame by stack address\n\
+Select and print a stack frame by stack address.\n\
\n\
Usage: frame address STACK-ADDRESS"),
&frame_cmd_list);
= make_backtrace_options_def_group (nullptr, nullptr, nullptr);
static std::string backtrace_help
- = gdb::option::build_help (N_("\
+ = gdb::option::build_help (_("\
Print backtrace of all stack frames, or innermost COUNT frames.\n\
Usage: backtrace [OPTION]... [QUALIFIER]... [COUNT | -COUNT]\n\
\n\
Options:\n\
-%OPTIONS%\
+%OPTIONS%\n\
+\n\
For backward compatibility, the following qualifiers are supported:\n\
\n\
full - same as -full option.\n\
All local variables of current stack frame or those matching REGEXPs.\n\
Usage: info locals [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the local variables of the current stack frame.\n"),
- _("local variables")));
+ _("local variables"),
+ false));
set_cmd_completer_handle_brkchars (cmd, info_print_command_completer);
cmd = add_info ("args", info_args_command,
info_print_args_help (_("\
All argument variables of current stack frame or those matching REGEXPs.\n\
Usage: info args [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the argument variables of the current stack frame.\n"),
- _("argument variables")));
+ _("argument variables"),
+ false));
set_cmd_completer_handle_brkchars (cmd, info_print_command_completer);
if (dbx_commands)