/* Print and select stack frames for GDB, the GNU debugger.
- Copyright (C) 1986-2017 Free Software Foundation, Inc.
+ Copyright (C) 1986-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "safe-ctype.h"
#include "symfile.h"
#include "extension.h"
-#include "observer.h"
+#include "observable.h"
#include "common/def-vector.h"
/* The possible choices of "set print frame-arguments", and the value
{
struct symbol *nsym;
- nsym = lookup_symbol (SYMBOL_LINKAGE_NAME (sym),
- b, VAR_DOMAIN, NULL).symbol;
+ nsym = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
+ b, VAR_DOMAIN).symbol;
gdb_assert (nsym != NULL);
if (SYMBOL_CLASS (nsym) == LOC_REGISTER
&& !SYMBOL_IS_ARGUMENT (nsym))
ADDR_EXP. Absolutely all information in the frame is printed. */
static void
-info_frame_command (char *addr_exp, int from_tty)
+info_frame_command (const char *addr_exp, int from_tty)
{
struct frame_info *fi;
struct symbol *func;
}
release_value (value);
- value_free (value);
need_nl = 0;
}
/* else keep quiet. */
frames. */
static void
-backtrace_command_1 (char *count_exp, int show_locals, int no_filters,
- int from_tty)
+backtrace_command_1 (const char *count_exp, frame_filter_flags flags,
+ int no_filters, int from_tty)
{
struct frame_info *fi;
int count;
int i;
- struct frame_info *trailing;
- int trailing_level, py_start = 0, py_end = 0;
+ int py_start = 0, py_end = 0;
enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
if (!target_has_stack)
error (_("No stack."));
- /* The following code must do two things. First, it must set the
- variable TRAILING to the frame from which we should start
- printing. Second, it must set the variable count to the number
- of frames which we should print, or -1 if all of them. */
- trailing = get_current_frame ();
-
- trailing_level = 0;
if (count_exp)
{
count = parse_and_eval_long (count_exp);
if (count < 0)
- {
- struct frame_info *current;
-
- py_start = count;
- count = -count;
-
- current = trailing;
- while (current && count--)
- {
- QUIT;
- current = get_prev_frame (current);
- }
-
- /* Will stop when CURRENT reaches the top of the stack.
- TRAILING will be COUNT below it. */
- while (current)
- {
- QUIT;
- trailing = get_prev_frame (trailing);
- current = get_prev_frame (current);
- trailing_level++;
- }
-
- count = -1;
- }
+ py_start = count;
else
{
py_start = 0;
- py_end = count;
+ /* The argument to apply_ext_lang_frame_filter is the number
+ of the final frame to print, and frames start at 0. */
+ py_end = count - 1;
}
}
else
count = -1;
}
- if (info_verbose)
- {
- /* Read in symbols for all of the frames. Need to do this in a
- separate pass so that "Reading in symbols for xxx" messages
- don't screw up the appearance of the backtrace. Also if
- people have strong opinions against reading symbols for
- backtrace this may have to be an option. */
- i = count;
- for (fi = trailing; fi != NULL && i--; fi = get_prev_frame (fi))
- {
- CORE_ADDR pc;
-
- QUIT;
- pc = get_frame_address_in_block (fi);
- expand_symtab_containing_pc (pc, find_pc_mapped_section (pc));
- }
- }
-
if (! no_filters)
{
- int flags = PRINT_LEVEL | PRINT_FRAME_INFO | PRINT_ARGS;
enum ext_lang_frame_args arg_type;
- if (show_locals)
- flags |= PRINT_LOCALS;
+ flags |= PRINT_LEVEL | PRINT_FRAME_INFO | PRINT_ARGS;
+ if (from_tty)
+ flags |= PRINT_MORE_FRAMES;
if (!strcmp (print_frame_arguments, "scalars"))
arg_type = CLI_SCALAR_VALUES;
"no-filters" has been specified from the command. */
if (no_filters || result == EXT_LANG_BT_NO_FILTERS)
{
+ struct frame_info *trailing;
+
+ /* The following code must do two things. First, it must set the
+ variable TRAILING to the frame from which we should start
+ printing. Second, it must set the variable count to the number
+ of frames which we should print, or -1 if all of them. */
+ trailing = get_current_frame ();
+
+ if (count_exp != NULL && count < 0)
+ {
+ struct frame_info *current;
+
+ count = -count;
+
+ current = trailing;
+ while (current && count--)
+ {
+ QUIT;
+ current = get_prev_frame (current);
+ }
+
+ /* Will stop when CURRENT reaches the top of the stack.
+ TRAILING will be COUNT below it. */
+ while (current)
+ {
+ QUIT;
+ trailing = get_prev_frame (trailing);
+ current = get_prev_frame (current);
+ }
+
+ count = -1;
+ }
+
for (i = 0, fi = trailing; fi && count--; i++, fi = get_prev_frame (fi))
{
QUIT;
the frame->prev field gets set to NULL in that case). */
print_frame_info (fi, 1, LOCATION, 1, 0);
- if (show_locals)
+ if ((flags & PRINT_LOCALS) != 0)
{
struct frame_id frame_id = get_frame_id (fi);
}
static void
-backtrace_command (char *arg, int from_tty)
+backtrace_command (const char *arg, int from_tty)
{
- struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
- int fulltrace_arg = -1, arglen = 0, argc = 0, no_filters = -1;
- int user_arg = 0;
+ bool filters = true;
+ frame_filter_flags flags = 0;
if (arg)
{
- char **argv;
- int i;
+ bool done = false;
- gdb_argv built_argv (arg);
- argv = built_argv.get ();
- argc = 0;
- for (i = 0; argv[i]; i++)
+ while (!done)
{
- unsigned int j;
+ const char *save_arg = arg;
+ std::string this_arg = extract_arg (&arg);
- for (j = 0; j < strlen (argv[i]); j++)
- argv[i][j] = TOLOWER (argv[i][j]);
+ if (this_arg.empty ())
+ break;
- if (no_filters < 0 && subset_compare (argv[i], "no-filters"))
- no_filters = argc;
+ if (subset_compare (this_arg.c_str (), "no-filters"))
+ filters = false;
+ else if (subset_compare (this_arg.c_str (), "full"))
+ flags |= PRINT_LOCALS;
+ else if (subset_compare (this_arg.c_str (), "hide"))
+ flags |= PRINT_HIDE;
else
{
- if (fulltrace_arg < 0 && subset_compare (argv[i], "full"))
- fulltrace_arg = argc;
- else
- {
- user_arg++;
- arglen += strlen (argv[i]);
- }
- }
- argc++;
- }
- arglen += user_arg;
- if (fulltrace_arg >= 0 || no_filters >= 0)
- {
- if (arglen > 0)
- {
- arg = (char *) xmalloc (arglen + 1);
- make_cleanup (xfree, arg);
- arg[0] = 0;
- for (i = 0; i < argc; i++)
- {
- if (i != fulltrace_arg && i != no_filters)
- {
- strcat (arg, argv[i]);
- strcat (arg, " ");
- }
- }
+ /* Not a recognized argument, so stop. */
+ arg = save_arg;
+ done = true;
}
- else
- arg = NULL;
}
- }
- backtrace_command_1 (arg, fulltrace_arg >= 0 /* show_locals */,
- no_filters >= 0 /* no frame-filters */, from_tty);
+ if (*arg == '\0')
+ arg = NULL;
+ }
- do_cleanups (old_chain);
+ backtrace_command_1 (arg, flags, !filters /* no frame-filters */, from_tty);
}
/* Iterate over the local variables of a block B, calling CB with
case LOC_REGISTER:
case LOC_STATIC:
case LOC_COMPUTED:
+ case LOC_OPTIMIZED_OUT:
if (SYMBOL_IS_ARGUMENT (sym))
break;
if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN)
}
void
-info_locals_command (char *args, int from_tty)
+info_locals_command (const char *args, int from_tty)
{
print_frame_local_vars (get_selected_frame (_("No frame selected.")),
0, gdb_stdout);
float). There are also LOC_ARG/LOC_REGISTER pairs which
are not combined in symbol-reading. */
- sym2 = lookup_symbol (SYMBOL_LINKAGE_NAME (sym),
- b, VAR_DOMAIN, NULL).symbol;
+ sym2 = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
+ b, VAR_DOMAIN).symbol;
(*cb) (SYMBOL_PRINT_NAME (sym), sym2, cb_data);
}
}
}
void
-info_args_command (char *ignore, int from_tty)
+info_args_command (const char *ignore, int from_tty)
{
print_frame_arg_vars (get_selected_frame (_("No frame selected.")),
gdb_stdout);
expressions. */
void
-select_frame_command (char *level_exp, int from_tty)
+select_frame_command (const char *level_exp, int from_tty)
{
struct frame_info *prev_frame = get_selected_frame_if_set ();
select_frame (parse_frame_specification (level_exp, NULL));
if (get_selected_frame_if_set () != prev_frame)
- observer_notify_user_selected_context_changed (USER_SELECTED_FRAME);
+ gdb::observers::user_selected_context_changed.notify (USER_SELECTED_FRAME);
}
/* The "frame" command. With no argument, print the selected frame
the selected frame. */
static void
-frame_command (char *level_exp, int from_tty)
+frame_command (const char *level_exp, int from_tty)
{
struct frame_info *prev_frame = get_selected_frame_if_set ();
select_frame (parse_frame_specification (level_exp, NULL));
if (get_selected_frame_if_set () != prev_frame)
- observer_notify_user_selected_context_changed (USER_SELECTED_FRAME);
+ gdb::observers::user_selected_context_changed.notify (USER_SELECTED_FRAME);
else
print_selected_thread_frame (current_uiout, USER_SELECTED_FRAME);
}
}
static void
-up_silently_command (char *count_exp, int from_tty)
+up_silently_command (const char *count_exp, int from_tty)
{
up_silently_base (count_exp);
}
static void
-up_command (char *count_exp, int from_tty)
+up_command (const char *count_exp, int from_tty)
{
up_silently_base (count_exp);
- observer_notify_user_selected_context_changed (USER_SELECTED_FRAME);
+ gdb::observers::user_selected_context_changed.notify (USER_SELECTED_FRAME);
}
/* Select the frame down one or COUNT_EXP stack levels from the previously
}
static void
-down_silently_command (char *count_exp, int from_tty)
+down_silently_command (const char *count_exp, int from_tty)
{
down_silently_base (count_exp);
}
static void
-down_command (char *count_exp, int from_tty)
+down_command (const char *count_exp, int from_tty)
{
down_silently_base (count_exp);
- observer_notify_user_selected_context_changed (USER_SELECTED_FRAME);
+ gdb::observers::user_selected_context_changed.notify (USER_SELECTED_FRAME);
}
void
-return_command (char *retval_exp, int from_tty)
+return_command (const char *retval_exp, int from_tty)
{
/* Initialize it just to avoid a GCC false warning. */
enum return_value_convention rv_conv = RETURN_VALUE_STRUCT_CONVENTION;
if (return_value != NULL)
{
struct type *return_type = value_type (return_value);
- struct gdbarch *gdbarch = get_regcache_arch (get_current_regcache ());
+ struct gdbarch *gdbarch = get_current_regcache ()->arch ();
gdb_assert (rv_conv != RETURN_VALUE_STRUCT_CONVENTION
&& rv_conv != RETURN_VALUE_ABI_RETURNS_ADDRESS);
};
static void
-func_command (char *arg, int from_tty)
+func_command (const char *arg, int from_tty)
{
struct frame_info *frame;
int found = 0;
Select and print a stack frame.\nWith no argument, \
print the selected stack frame. (See also \"info frame\").\n\
An argument specifies the frame to select.\n\
-It can be a stack frame number or the address of the frame.\n"));
+It can be a stack frame number or the address of the frame."));
add_com_alias ("f", "frame", class_stack, 1);
add_com_suppress_notification ("select-frame", class_stack, select_frame_command, _("\
Select a stack frame without printing anything.\n\
An argument specifies the frame to select.\n\
-It can be a stack frame number or the address of the frame.\n"),
+It can be a stack frame number or the address of the frame."),
&cli_suppress_notification.user_selected_context);
add_com ("backtrace", class_stack, backtrace_command, _("\
Print backtrace of all stack frames, or innermost COUNT frames.\n\
-With a negative argument, print outermost -COUNT frames.\nUse of the \
-'full' qualifier also prints the values of the local variables.\n\
+Usage: backtrace [QUALIFIERS]... [COUNT]\n\
+With a negative argument, print outermost -COUNT frames.\n\
+Use of the 'full' qualifier also prints the values of the local variables.\n\
Use of the 'no-filters' qualifier prohibits frame filters from executing\n\
-on this backtrace.\n"));
+on this backtrace."));
add_com_alias ("bt", "backtrace", class_stack, 0);
add_com_alias ("where", "backtrace", class_alias, 0);
if (dbx_commands)
add_com ("func", class_stack, func_command, _("\
Select the stack frame that contains <func>.\n\
-Usage: func <name>\n"));
+Usage: func <name>"));
add_setshow_enum_cmd ("frame-arguments", class_stack,
print_frame_arguments_choices, &print_frame_arguments,