/* Print and select stack frames for GDB, the GNU debugger.
- Copyright (C) 1986-2019 Free Software Foundation, Inc.
+ Copyright (C) 1986-2020 Free Software Foundation, Inc.
This file is part of GDB.
#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. */
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
enum print_what print_what, int print_args,
struct symtab_and_line sal);
-static void set_last_displayed_sal (int valid,
- struct program_space *pspace,
- CORE_ADDR addr,
- struct symtab *symtab,
- int line);
-
static struct frame_info *find_frame_for_function (const char *);
static struct frame_info *find_frame_for_address (CORE_ADDR);
int annotation_level = 0;
-/* These variables hold the last symtab and line we displayed to the user.
- * This is where we insert a breakpoint or a skiplist entry by default. */
-static int last_displayed_sal_valid = 0;
-static struct program_space *last_displayed_pspace = 0;
-static CORE_ADDR last_displayed_addr = 0;
-static struct symtab *last_displayed_symtab = 0;
-static int last_displayed_line = 0;
+/* Class used to manage tracking the last symtab we displayed. */
+
+class last_displayed_symtab_info_type
+{
+public:
+ /* True if the cached information is valid. */
+ bool is_valid () const
+ { return m_valid; }
+
+ /* Return the cached program_space. If the cache is invalid nullptr is
+ returned. */
+ struct program_space *pspace () const
+ { return m_pspace; }
+
+ /* Return the cached CORE_ADDR address. If the cache is invalid 0 is
+ returned. */
+ CORE_ADDR address () const
+ { return m_address; }
+
+ /* Return the cached symtab. If the cache is invalid nullptr is
+ returned. */
+ struct symtab *symtab () const
+ { return m_symtab; }
+
+ /* Return the cached line number. If the cache is invalid 0 is
+ returned. */
+ int line () const
+ { return m_line; }
+
+ /* Invalidate the cache, reset all the members to their default value. */
+ void invalidate ()
+ {
+ m_valid = false;
+ m_pspace = nullptr;
+ m_address = 0;
+ m_symtab = nullptr;
+ m_line = 0;
+ }
+
+ /* Store a new set of values in the cache. */
+ void set (struct program_space *pspace, CORE_ADDR address,
+ struct symtab *symtab, int line)
+ {
+ gdb_assert (pspace != nullptr);
+
+ m_valid = true;
+ m_pspace = pspace;
+ m_address = address;
+ m_symtab = symtab;
+ m_line = line;
+ }
+
+private:
+ /* True when the cache is valid. */
+ bool m_valid = false;
+
+ /* The last program space displayed. */
+ struct program_space *m_pspace = nullptr;
+
+ /* The last address displayed. */
+ CORE_ADDR m_address = 0;
+
+ /* The last symtab displayed. */
+ struct symtab *m_symtab = nullptr;
+
+ /* The last line number displayed. */
+ int m_line = 0;
+};
+
+/* An actual instance of the cache, holds information about the last symtab
+ displayed. */
+static last_displayed_symtab_info_type last_displayed_symtab_info;
+
\f
/* See stack.h. */
-int
+bool
frame_show_address (struct frame_info *frame,
struct symtab_and_line sal)
{
gdb_assert (inline_skipped_frames (inferior_thread ()) > 0);
else
gdb_assert (get_frame_type (get_next_frame (frame)) == INLINE_FRAME);
- return 0;
+ return false;
}
- return get_frame_pc (frame) != sal.pc;
+ return get_frame_pc (frame) != sal.pc || !sal.is_stmt;
}
/* See frame.h. */
int set_current_sal)
{
- /* For mi, alway print location and address. */
+ /* For mi, always print location and address. */
if (current_uiout->is_mi_like_p ())
print_what = LOC_AND_ADDRESS;
read in.
Errors are printed as if they would be the parameter value. Use zeroed ARG
- iff it should not be printed accoring to user settings. */
+ iff it should not be printed according to user settings. */
static void
print_frame_arg (const frame_print_options &fp_opts,
annotate_arg_emitter arg_emitter;
ui_out_emit_tuple tuple_emitter (uiout, NULL);
- fprintf_symbol_filtered (&stb, SYMBOL_PRINT_NAME (arg->sym),
- SYMBOL_LANGUAGE (arg->sym), DMGL_PARAMS | DMGL_ANSI);
+ fprintf_symbol_filtered (&stb, arg->sym->print_name (),
+ arg->sym->language (), DMGL_PARAMS | DMGL_ANSI);
if (arg->entry_kind == print_entry_values_compact)
{
/* It is OK to provide invalid MI-like stream as with
PRINT_ENTRY_VALUE_COMPACT we never use MI. */
stb.puts ("=");
- fprintf_symbol_filtered (&stb, SYMBOL_PRINT_NAME (arg->sym),
- SYMBOL_LANGUAGE (arg->sym),
+ fprintf_symbol_filtered (&stb, arg->sym->print_name (),
+ arg->sym->language (),
DMGL_PARAMS | DMGL_ANSI);
}
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
/* Use the appropriate language to display our symbol, unless the
user forced the language to a specific language. */
if (language_mode == language_mode_auto)
- language = language_def (SYMBOL_LANGUAGE (arg->sym));
+ language = language_def (arg->sym->language ());
else
language = current_language;
vp_opts.summary
= fp_opts.print_frame_arguments == print_frame_arguments_scalars;
- common_val_print (arg->val, &stb, 2, &vp_opts, language);
+ common_val_print_checked (arg->val, &stb, 2, &vp_opts, language);
}
catch (const gdb_exception_error &except)
{
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,
symbol *sym, frame_info *frame,
- struct frame_arg *argp, struct frame_arg *entryargp)
+ struct frame_arg *argp, struct frame_arg *entryargp)
{
struct value *val = NULL, *entryval = NULL;
char *val_error = NULL, *entryval_error = NULL;
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
= (print_names
&& fp_opts.print_frame_arguments != print_frame_arguments_none);
+ /* Temporarily change the selected frame to the given FRAME.
+ This allows routines that rely on the selected frame instead
+ of being given a frame as parameter to use the correct frame. */
+ scoped_restore_selected_frame restore_selected_frame;
+ select_frame (frame);
+
if (func)
{
const struct block *b = SYMBOL_BLOCK_VALUE (func);
struct symbol *sym;
ALL_BLOCK_SYMBOLS (b, iter, sym)
- {
+ {
struct frame_arg arg, entryarg;
QUIT;
parameter names occur on the RS/6000, for traceback
tables. FIXME, should we even print them? */
- if (*SYMBOL_LINKAGE_NAME (sym))
+ if (*sym->linkage_name ())
{
struct symbol *nsym;
- nsym = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
+ nsym = lookup_symbol_search_name (sym->search_name (),
b, VAR_DOMAIN).symbol;
gdb_assert (nsym != NULL);
if (SYMBOL_CLASS (nsym) == LOC_REGISTER
Reasons for using the LOC_ARG:
(1) Because find_saved_registers may be slow for
- remote debugging.
+ remote debugging.
(2) Because registers are often re-used and stack
- slots rarely (never?) are. Therefore using
- the stack slot is much less likely to print
- garbage.
+ slots rarely (never?) are. Therefore using
+ the stack slot is much less likely to print
+ garbage.
Reasons why we might want to use the LOC_REGISTER:
(1) So that the backtrace prints the same value
- as "print foo". I see no compelling reason
- why this needs to be the case; having the
- backtrace print the value which was passed
- in, and "print foo" print the value as
- modified within the called function, makes
- perfect sense to me.
+ as "print foo". I see no compelling reason
+ why this needs to be the case; having the
+ backtrace print the value which was passed
+ in, and "print foo" print the value as
+ modified within the called function, makes
+ perfect sense to me.
Additional note: It might be nice if "info args"
displayed both values.
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;
}
}
fprintf_filtered (file,
_("Debugger's willingness to use "
"disassemble-next-line is %s.\n"),
- value);
+ value);
}
/* Use TRY_CATCH to catch the exception from the gdb_disassembly
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
{
*what
= print_frame_info_to_print_what
- (user_frame_print_options.print_frame_info);
+ (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. 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
+ Note that PRINT_WHAT is overridden if FP_OPTS.print_frame_info
!= print_frame_info_auto.
Used in "where" output, and to emit breakpoint or step
gdbarch, get_frame_pc (frame));
/* Do this regardless of SOURCE because we don't have any source
- to list for this frame. */
+ to list for this frame. */
if (print_level)
- {
- uiout->text ("#");
- uiout->field_fmt_signed (2, ui_left, "level",
+ {
+ uiout->text ("#");
+ uiout->field_fmt_signed (2, ui_left, "level",
frame_relative_level (frame));
- }
+ }
if (uiout->is_mi_like_p ())
- {
- annotate_frame_address ();
- uiout->field_core_addr ("addr",
- gdbarch, get_frame_pc (frame));
- annotate_frame_address_end ();
- }
+ {
+ annotate_frame_address ();
+ print_pc (uiout, gdbarch, frame, get_frame_pc (frame));
+ annotate_frame_address_end ();
+ }
if (get_frame_type (frame) == DUMMY_FRAME)
- {
- annotate_function_call ();
- uiout->field_string ("func", "<function called from gdb>",
- ui_out_style_kind::FUNCTION);
+ {
+ annotate_function_call ();
+ uiout->field_string ("func", "<function called from gdb>",
+ 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);
- }
+ uiout->field_string ("func", "<signal handler called>",
+ metadata_style.style ());
+ }
else if (get_frame_type (frame) == ARCH_FRAME)
- {
- uiout->field_string ("func", "<cross-architecture call>",
- ui_out_style_kind::FUNCTION);
+ {
+ uiout->field_string ("func", "<cross-architecture call>",
+ metadata_style.style ());
}
uiout->text ("\n");
annotate_frame_end ();
{
int mid_statement = ((print_what == SRC_LINE)
&& frame_show_address (frame, sal));
- annotate_source_line (sal.symtab, sal.line, mid_statement,
- get_frame_pc (frame));
-
- if (deprecated_print_frame_info_listing_hook)
+ if (annotation_level > 0
+ && annotate_source_line (sal.symtab, sal.line, mid_statement,
+ get_frame_pc (frame)))
+ {
+ /* The call to ANNOTATE_SOURCE_LINE already printed the
+ annotation for this source line, so we avoid the two cases
+ below and do not print the actual source line. The
+ documentation for annotations makes it clear that the source
+ line annotation is printed __instead__ of printing the source
+ line, not as well as.
+
+ However, if we fail to print the source line, which usually
+ means either the source file is missing, or the requested
+ line is out of range of the file, then we don't print the
+ source annotation, and will pass through the "normal" print
+ source line code below, the expectation is that this code
+ will print an appropriate error. */
+ }
+ else if (deprecated_print_frame_info_listing_hook)
deprecated_print_frame_info_listing_hook (sal.symtab, sal.line,
sal.line + 1, 0);
else
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");
}
print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
}
- }
- /* If disassemble-next-line is set to on and there is line debug
- messages, output assembly codes for next line. */
- if (disassemble_next_line == AUTO_BOOLEAN_TRUE)
- do_gdb_disassembly (get_frame_arch (frame), -1, sal.pc, sal.end);
+ /* If disassemble-next-line is set to on and there is line debug
+ messages, output assembly codes for next line. */
+ if (disassemble_next_line == AUTO_BOOLEAN_TRUE)
+ do_gdb_disassembly (get_frame_arch (frame), -1, sal.pc, sal.end);
+ }
if (set_current_sal)
{
CORE_ADDR pc;
if (get_frame_pc_if_available (frame, &pc))
- set_last_displayed_sal (1, sal.pspace, pc, sal.symtab, sal.line);
+ last_displayed_symtab_info.set (sal.pspace, pc, sal.symtab, sal.line);
else
- set_last_displayed_sal (0, 0, 0, 0, 0);
+ last_displayed_symtab_info.invalidate ();
}
annotate_frame_end ();
gdb_flush (gdb_stdout);
}
-/* Remember the last symtab and line we displayed, which we use e.g.
- * as the place to put a breakpoint when the `break' command is
- * invoked with no arguments. */
-
-static void
-set_last_displayed_sal (int valid, struct program_space *pspace,
- CORE_ADDR addr, struct symtab *symtab,
- int line)
-{
- last_displayed_sal_valid = valid;
- last_displayed_pspace = pspace;
- last_displayed_addr = addr;
- last_displayed_symtab = symtab;
- last_displayed_line = line;
- if (valid && pspace == NULL)
- {
- clear_last_displayed_sal ();
- internal_error (__FILE__, __LINE__,
- _("Trying to set NULL pspace."));
- }
-}
-
-/* Forget the last sal we displayed. */
+/* See stack.h. */
void
clear_last_displayed_sal (void)
{
- last_displayed_sal_valid = 0;
- last_displayed_pspace = 0;
- last_displayed_addr = 0;
- last_displayed_symtab = 0;
- last_displayed_line = 0;
+ last_displayed_symtab_info.invalidate ();
}
-/* Is our record of the last sal we displayed valid? If not,
- * the get_last_displayed_* functions will return NULL or 0, as
- * appropriate. */
+/* See stack.h. */
-int
+bool
last_displayed_sal_is_valid (void)
{
- return last_displayed_sal_valid;
+ return last_displayed_symtab_info.is_valid ();
}
-/* Get the pspace of the last sal we displayed, if it's valid. */
+/* See stack.h. */
struct program_space *
get_last_displayed_pspace (void)
{
- if (last_displayed_sal_valid)
- return last_displayed_pspace;
- return 0;
+ return last_displayed_symtab_info.pspace ();
}
-/* Get the address of the last sal we displayed, if it's valid. */
+/* See stack.h. */
CORE_ADDR
get_last_displayed_addr (void)
{
- if (last_displayed_sal_valid)
- return last_displayed_addr;
- return 0;
+ return last_displayed_symtab_info.address ();
}
-/* Get the symtab of the last sal we displayed, if it's valid. */
+/* See stack.h. */
struct symtab*
get_last_displayed_symtab (void)
{
- if (last_displayed_sal_valid)
- return last_displayed_symtab;
- return 0;
+ return last_displayed_symtab_info.symtab ();
}
-/* Get the line of the last sal we displayed, if it's valid. */
+/* See stack.h. */
int
get_last_displayed_line (void)
{
- if (last_displayed_sal_valid)
- return last_displayed_line;
- return 0;
+ return last_displayed_symtab_info.line ();
}
-/* Get the last sal we displayed, if it's valid. */
+/* See stack.h. */
symtab_and_line
get_last_displayed_sal ()
{
symtab_and_line sal;
- if (last_displayed_sal_valid)
+ if (last_displayed_symtab_info.is_valid ())
{
- sal.pspace = last_displayed_pspace;
- sal.pc = last_displayed_addr;
- sal.symtab = last_displayed_symtab;
- sal.line = last_displayed_line;
+ sal.pspace = last_displayed_symtab_info.pspace ();
+ sal.pc = last_displayed_symtab_info.address ();
+ sal.symtab = last_displayed_symtab_info.symtab ();
+ sal.line = last_displayed_symtab_info.line ();
}
return sal;
func = get_frame_function (frame);
if (func)
{
- const char *print_name = SYMBOL_PRINT_NAME (func);
+ const char *print_name = func->print_name ();
- *funlang = SYMBOL_LANGUAGE (func);
+ *funlang = func->language ();
if (funcp)
*funcp = func;
if (*funlang == language_cplus)
{
- /* It seems appropriate to use SYMBOL_PRINT_NAME() here,
+ /* It seems appropriate to use 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
msymbol = lookup_minimal_symbol_by_pc (pc);
if (msymbol.minsym != NULL)
{
- funname.reset (xstrdup (MSYMBOL_PRINT_NAME (msymbol.minsym)));
- *funlang = MSYMBOL_LANGUAGE (msymbol.minsym);
+ funname.reset (xstrdup (msymbol.minsym->print_name ()));
+ *funlang = msymbol.minsym->language ();
}
}
{
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 ();
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_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 ())
/* Completion function for "frame function", "info frame function", and
"select-frame function" commands. */
-void
+static void
frame_selection_by_function_completer (struct cmd_list_element *ignore,
completion_tracker &tracker,
const char *text, const char *word)
gdb::unique_xmalloc_ptr<char> func_only;
if (func)
{
- funname = SYMBOL_PRINT_NAME (func);
- funlang = SYMBOL_LANGUAGE (func);
+ funname = func->print_name ();
+ funlang = func->language ();
if (funlang == language_cplus)
{
- /* It seems appropriate to use SYMBOL_PRINT_NAME() here,
+ /* It seems appropriate to use 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
msymbol = lookup_minimal_symbol_by_pc (frame_pc);
if (msymbol.minsym != NULL)
{
- funname = MSYMBOL_PRINT_NAME (msymbol.minsym);
- funlang = MSYMBOL_LANGUAGE (msymbol.minsym);
+ funname = msymbol.minsym->print_name ();
+ funlang = msymbol.minsym->language ();
}
}
calling_frame_info = get_prev_frame (fi);
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;
}
}
int realnum;
/* Find out the location of the saved register without
- fetching the corresponding value. */
+ fetching the corresponding value. */
frame_register_unwind (fi, i, &optimized, &unavailable,
&lval, &addr, &realnum, NULL);
/* For moment, only display registers that were saved on the
static void
select_frame_command_core (struct frame_info *fi, bool ignored)
{
- struct frame_info *prev_frame = get_selected_frame_if_set ();
+ frame_info *prev_frame = get_selected_frame ();
select_frame (fi);
- if (get_selected_frame_if_set () != prev_frame)
+ if (get_selected_frame () != prev_frame)
gdb::observers::user_selected_context_changed.notify (USER_SELECTED_FRAME);
}
static void
frame_command_core (struct frame_info *fi, bool ignored)
{
- struct frame_info *prev_frame = get_selected_frame_if_set ();
-
+ frame_info *prev_frame = get_selected_frame ();
select_frame (fi);
- if (get_selected_frame_if_set () != prev_frame)
+ if (get_selected_frame () != prev_frame)
gdb::observers::user_selected_context_changed.notify (USER_SELECTED_FRAME);
else
print_selected_thread_frame (current_uiout, USER_SELECTED_FRAME);
int py_start = 0, py_end = 0;
enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
- if (!target_has_stack)
+ if (!target_has_stack ())
error (_("No stack."));
if (count_exp)
{
switch (SYMBOL_CLASS (sym))
{
+ case LOC_CONST:
case LOC_LOCAL:
case LOC_REGISTER:
case LOC_STATIC:
break;
if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN)
break;
- (*cb) (SYMBOL_PRINT_NAME (sym), sym, cb_data);
+ (*cb) (sym->print_name (), sym, cb_data);
break;
default:
}
}
-
-/* Same, but print labels. */
-
-#if 0
-/* Commented out, as the code using this function has also been
- commented out. FIXME:brobecker/2009-01-13: Find out why the code
- was commented out in the first place. The discussion introducing
- this change (2007-12-04: Support lexical blocks and function bodies
- that occupy non-contiguous address ranges) did not explain why
- this change was made. */
-static int
-print_block_frame_labels (struct gdbarch *gdbarch, struct block *b,
- int *have_default, struct ui_file *stream)
-{
- struct block_iterator iter;
- struct symbol *sym;
- int values_printed = 0;
-
- ALL_BLOCK_SYMBOLS (b, iter, sym)
- {
- if (strcmp (SYMBOL_LINKAGE_NAME (sym), "default") == 0)
- {
- if (*have_default)
- continue;
- *have_default = 1;
- }
- if (SYMBOL_CLASS (sym) == LOC_LABEL)
- {
- struct symtab_and_line sal;
- struct value_print_options opts;
-
- sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 0);
- values_printed = 1;
- fputs_filtered (SYMBOL_PRINT_NAME (sym), stream);
- get_user_print_options (&opts);
- if (opts.addressprint)
- {
- fprintf_filtered (stream, " ");
- fputs_filtered (paddress (gdbarch, SYMBOL_VALUE_ADDRESS (sym)),
- stream);
- }
- fprintf_filtered (stream, " in file %s, line %d\n",
- sal.symtab->filename, sal.line);
- }
- }
-
- return values_printed;
-}
-#endif
-
/* Iterate over all the local variables in block B, including all its
superblocks, stopping when the top-level block is reached. */
struct frame_info *frame;
if (p->preg.has_value ()
- && p->preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
- NULL, 0) != 0)
+ && p->preg->exec (sym->natural_name (), 0, NULL, 0) != 0)
return;
if (p->treg.has_value ()
&& !treg_matches_sym_type_name (*p->treg, sym))
}
}
+/* 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,
float). There are also LOC_ARG/LOC_REGISTER pairs which
are not combined in symbol-reading. */
- sym2 = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
+ sym2 = lookup_symbol_search_name (sym->search_name (),
b, VAR_DOMAIN).symbol;
- (*cb) (SYMBOL_PRINT_NAME (sym), sym2, cb_data);
+ (*cb) (sym->print_name (), sym2, cb_data);
}
}
}
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);
if (count != 0 && count_exp == NULL)
{
/* We only do this if COUNT_EXP is not specified. That way
- "down" means to really go down (and let me know if that is
- impossible), but "down 9999" can be used to mean go all the
- way down without getting an error. */
+ "down" means to really go down (and let me know if that is
+ impossible), but "down 9999" can be used to mean go all the
+ way down without getting an error. */
error (_("Bottom (innermost) frame selected; you cannot go down."));
}
struct type *return_type = NULL;
/* Compute the return value. Should the computation fail, this
- call throws an error. */
+ call throws an error. */
return_value = evaluate_expression (retval_expr.get ());
/* Cast return value to the return type of the function. Should
- the cast fail, this call throws an error. */
+ the cast fail, this call throws an error. */
if (thisfun != NULL)
return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun));
if (return_type == NULL)
{
- if (retval_expr->elts[0].opcode != UNOP_CAST
- && retval_expr->elts[0].opcode != UNOP_CAST_TYPE)
+ if (retval_expr->first_opcode () != UNOP_CAST
+ && retval_expr->first_opcode () != UNOP_CAST_TYPE)
error (_("Return value type not available for selected "
"stack frame.\n"
"Please use an explicit cast of the value to return."));
return_value = value_cast (return_type, return_value);
/* Make sure the value is fully evaluated. It may live in the
- stack frame we're about to pop. */
+ stack frame we're about to pop. */
if (value_lazy (return_value))
value_fetch_lazy (return_value);
function = read_var_value (thisfun, NULL, thisframe);
rv_conv = RETURN_VALUE_REGISTER_CONVENTION;
- if (TYPE_CODE (return_type) == TYPE_CODE_VOID)
+ if (return_type->code () == TYPE_CODE_VOID)
/* If the return-type is "void", don't try to find the
- return-value's location. However, do still evaluate the
- return expression so that, even when the expression result
- is discarded, side effects such as "return i++" still
- occur. */
+ return-value's location. However, do still evaluate the
+ return expression so that, even when the expression result
+ is discarded, side effects such as "return i++" still
+ occur. */
return_value = NULL;
else if (thisfun != NULL)
{
if (TYPE_NO_RETURN (thisfun->type))
warning (_("Function does not return normally to caller."));
confirmed = query (_("%sMake %s return now? "), query_prefix,
- SYMBOL_PRINT_NAME (thisfun));
+ thisfun->print_name ());
}
if (!confirmed)
error (_("Not confirmed"));
frame apply -3 info frame Apply 'info frame' to outermost 3 frames.
frame apply all x/i $pc Apply 'x/i $pc' cmd to all frames.
frame apply all -s p local_var_no_idea_in_which_frame
- If a frame has a local variable called
- local_var_no_idea_in_which_frame, print frame
- and value of local_var_no_idea_in_which_frame.
+ If a frame has a local variable called
+ local_var_no_idea_in_which_frame, print frame
+ and value of local_var_no_idea_in_which_frame.
frame apply all -s -q p local_var_no_idea_in_which_frame
- Same as before, but only print the variable value.
+ Same as before, but only print the variable value.
frame apply level 2-5 0 4-7 -s p i = i + 1
- Adds 1 to the variable i in the specified frames.
- Note that i will be incremented twice in
- frames 4 and 5. */
+ Adds 1 to the variable i in the specified frames.
+ Note that i will be incremented twice in
+ frames 4 and 5. */
/* Apply a GDB command to COUNT stack frames, starting at TRAILING.
CMD starts with 0 or more qcs flags followed by the GDB command to apply.
static void
frame_apply_level_command (const char *cmd, int from_tty)
{
- if (!target_has_stack)
+ if (!target_has_stack ())
error (_("No stack."));
bool level_found = false;
static void
frame_apply_all_command (const char *cmd, int from_tty)
{
- if (!target_has_stack)
+ if (!target_has_stack ())
error (_("No stack."));
frame_apply_command_count ("frame apply all", cmd, from_tty,
int count;
struct frame_info *trailing;
- if (!target_has_stack)
+ if (!target_has_stack ())
error (_("No stack."));
if (cmd == NULL)
static void
faas_command (const char *cmd, int from_tty)
{
+ if (cmd == NULL || *cmd == '\0')
+ error (_("Please specify a command to apply on all frames"));
std::string expanded = std::string ("frame apply all -s ") + cmd;
execute_command (expanded.c_str (), from_tty);
}
/* Commands with a prefix of `info frame'. */
static struct cmd_list_element *info_frame_cmd_list = NULL;
+void _initialize_stack ();
void
-_initialize_stack (void)
+_initialize_stack ()
{
struct cmd_list_element *cmd;
This is useful in command scripts."));
add_prefix_cmd ("frame", class_stack,
- &frame_cmd.base_command, _("\
+ &frame_cmd.base_command, _("\
Select and print a stack frame.\n\
With no argument, print the selected stack frame. (See also \"info frame\").\n\
A single numerical argument specifies the frame to select."),
- &frame_cmd_list, "frame ", 1, &cmdlist);
-
+ &frame_cmd_list, "frame ", 1, &cmdlist);
add_com_alias ("f", "frame", class_stack, 1);
#define FRAME_APPLY_OPTION_HELP "\
See \"help frame apply all\" for available options."));
set_cmd_completer_handle_brkchars (cmd, frame_apply_all_cmd_completer);
- add_prefix_cmd ("frame", class_stack,
- &frame_cmd.base_command, _("\
-Select and print a stack frame.\n\
-With no argument, print the selected stack frame. (See also \"info frame\").\n\
-A single numerical argument specifies the frame to select."),
- &frame_cmd_list, "frame ", 1, &cmdlist);
- add_com_alias ("f", "frame", class_stack, 1);
-
add_cmd ("address", class_stack, &frame_cmd.address,
_("\
Select and print a stack frame by stack address.\n\
add_com_alias ("bt", "backtrace", class_stack, 0);
- add_com_alias ("where", "backtrace", class_alias, 0);
+ add_com_alias ("where", "backtrace", class_stack, 0);
add_info ("stack", backtrace_command,
_("Backtrace of the stack, or innermost COUNT frames."));
add_info_alias ("s", "stack", 1);
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)
deprecate_cmd (cmd, "set print raw-frame-arguments");
add_setshow_auto_boolean_cmd ("disassemble-next-line", class_stack,
- &disassemble_next_line, _("\
+ &disassemble_next_line, _("\
Set whether to disassemble next source line or insn when execution stops."),
_("\
Show whether to disassemble next source line or insn when execution stops."),
cannot be displayed.\n\
If OFF (which is the default), never display the disassembly of the next\n\
source line."),
- NULL,
- show_disassemble_next_line,
- &setlist, &showlist);
+ NULL,
+ show_disassemble_next_line,
+ &setlist, &showlist);
disassemble_next_line = AUTO_BOOLEAN_FALSE;
gdb::option::add_setshow_cmds_for_options