/* Print and select stack frames for GDB, the GNU debugger.
- Copyright (C) 1986-2015 Free Software Foundation, Inc.
+ Copyright (C) 1986-2016 Free Software Foundation, Inc.
This file is part of GDB.
#include "cli/cli-utils.h"
#include "objfiles.h"
-#include <ctype.h>
+#include "safe-ctype.h"
#include "symfile.h"
#include "extension.h"
-void (*deprecated_selected_frame_level_changed_hook) (int);
-
/* The possible choices of "set print frame-arguments", and the value
of this setting. */
return get_frame_pc (frame) != sal.pc;
}
-/* Show or print a stack frame FRAME briefly. The output is format
+/* Show or print a stack frame FRAME briefly. The output is formatted
according to PRINT_LEVEL and PRINT_WHAT printing the frame's
relative level, function name, argument list, and file name and
line number. If the frame's PC is not at the beginning of the
read_frame_local (struct symbol *sym, struct frame_info *frame,
struct frame_arg *argp)
{
- struct value *val = NULL;
-
argp->sym = sym;
argp->val = NULL;
argp->error = NULL;
TRY
{
- argp->val = read_var_value (sym, frame);
+ argp->val = read_var_value (sym, NULL, frame);
}
CATCH (except, RETURN_MASK_ERROR)
{
{
TRY
{
- val = read_var_value (sym, frame);
+ val = read_var_value (sym, NULL, frame);
}
CATCH (except, RETURN_MASK_ERROR)
{
- val_error = alloca (strlen (except.message) + 1);
+ val_error = (char *) alloca (strlen (except.message) + 1);
strcpy (val_error, except.message);
}
END_CATCH
TRY
{
- val = read_var_value (sym, frame);
+ val = read_var_value (sym, NULL, frame);
}
CATCH (except, RETURN_MASK_ERROR)
{
- val_error = alloca (strlen (except.message) + 1);
+ val_error = (char *) alloca (strlen (except.message) + 1);
strcpy (val_error, except.message);
}
END_CATCH
struct symbol *nsym;
nsym = lookup_symbol (SYMBOL_LINKAGE_NAME (sym),
- b, VAR_DOMAIN, NULL);
+ b, VAR_DOMAIN, NULL).symbol;
gdb_assert (nsym != NULL);
if (SYMBOL_CLASS (nsym) == LOC_REGISTER
&& !SYMBOL_IS_ARGUMENT (nsym))
}
\f
-/* Read a frame specification in whatever the appropriate format is
- from FRAME_EXP. Call error(), printing MESSAGE, if the
- specification is in any way invalid (so this function never returns
- NULL). When SEPECTED_P is non-NULL set its target to indicate that
- the default selected frame was used. */
+/* Read a frame specification in whatever the appropriate format is from
+ FRAME_EXP. Call error() if the specification is in any way invalid (so
+ this function never returns NULL). When SEPECTED_P is non-NULL set its
+ target to indicate that the default selected frame was used. */
static struct frame_info *
-parse_frame_specification_1 (const char *frame_exp, const char *message,
- int *selected_frame_p)
+parse_frame_specification (const char *frame_exp, int *selected_frame_p)
{
int numargs;
struct value *args[4];
/* Parse the argument, extract it, save it. */
for (p = frame_exp;
- *p && !isspace (*p);
+ *p && !ISSPACE (*p);
p++);
addr_string = savestring (frame_exp, p - frame_exp);
frame_exp = p;
{
if (selected_frame_p != NULL)
(*selected_frame_p) = 1;
- return get_selected_frame (message);
+ return get_selected_frame (_("No stack."));
}
/* None of the remaining use the selected frame. */
error (_("Too many args in frame specification"));
}
-static struct frame_info *
-parse_frame_specification (char *frame_exp)
-{
- return parse_frame_specification_1 (frame_exp, NULL, NULL);
-}
-
/* Print verbosely the selected frame or the frame at address
ADDR_EXP. Absolutely all information in the frame is printed. */
CORE_ADDR caller_pc = 0;
int caller_pc_p = 0;
- fi = parse_frame_specification_1 (addr_exp, "No stack.", &selected_frame_p);
+ fi = parse_frame_specification (addr_exp, &selected_frame_p);
gdbarch = get_frame_arch (fi);
/* Name of the value returned by get_frame_pc(). Per comments, "pc"
wrap_here (" ");
printf_filtered ("saved %s = ", pc_regname);
- TRY
- {
- caller_pc = frame_unwind_caller_pc (fi);
- caller_pc_p = 1;
- }
- CATCH (ex, RETURN_MASK_ERROR)
+ if (!frame_id_p (frame_unwind_caller_id (fi)))
+ val_print_unavailable (gdb_stdout);
+ else
{
- switch (ex.error)
+ TRY
{
- case NOT_AVAILABLE_ERROR:
- val_print_unavailable (gdb_stdout);
- break;
- case OPTIMIZED_OUT_ERROR:
- val_print_not_saved (gdb_stdout);
- break;
- default:
- fprintf_filtered (gdb_stdout, _("<error: %s>"), ex.message);
- break;
+ caller_pc = frame_unwind_caller_pc (fi);
+ caller_pc_p = 1;
}
+ CATCH (ex, RETURN_MASK_ERROR)
+ {
+ switch (ex.error)
+ {
+ case NOT_AVAILABLE_ERROR:
+ val_print_unavailable (gdb_stdout);
+ break;
+ case OPTIMIZED_OUT_ERROR:
+ val_print_not_saved (gdb_stdout);
+ break;
+ default:
+ fprintf_filtered (gdb_stdout, _("<error: %s>"), ex.message);
+ break;
+ }
+ }
+ END_CATCH
}
- END_CATCH
if (caller_pc_p)
fputs_filtered (paddress (gdbarch, caller_pc), gdb_stdout);
unsigned int j;
for (j = 0; j < strlen (argv[i]); j++)
- argv[i][j] = tolower (argv[i][j]);
+ argv[i][j] = TOLOWER (argv[i][j]);
if (no_filters < 0 && subset_compare (argv[i], "no-filters"))
no_filters = argc;
{
if (arglen > 0)
{
- arg = xmalloc (arglen + 1);
+ arg = (char *) xmalloc (arglen + 1);
make_cleanup (xfree, arg);
arg[0] = 0;
for (i = 0; i < argc; i++)
do_cleanups (old_chain);
}
-static void
-backtrace_full_command (char *arg, int from_tty)
-{
- backtrace_command_1 (arg, 1 /* show_locals */, 0, from_tty);
-}
-\f
-
/* Iterate over the local variables of a block B, calling CB with
CB_DATA. */
struct symbol *sym,
void *cb_data)
{
- struct print_variable_and_value_data *p = cb_data;
+ struct print_variable_and_value_data *p
+ = (struct print_variable_and_value_data *) cb_data;
struct frame_info *frame;
frame = frame_find_by_id (p->frame_id);
struct print_variable_and_value_data cb_data;
const struct block *block;
CORE_ADDR pc;
+ struct gdb_exception except = exception_none;
if (!get_frame_pc_if_available (frame, &pc))
{
cb_data.stream = stream;
cb_data.values_printed = 0;
- iterate_over_block_local_vars (block,
- do_print_variable_and_value,
- &cb_data);
+ /* 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. */
+ select_frame (frame);
+
+ TRY
+ {
+ iterate_over_block_local_vars (block,
+ do_print_variable_and_value,
+ &cb_data);
+ }
+ CATCH (ex, RETURN_MASK_ALL)
+ {
+ except = ex;
+ }
+ END_CATCH
+
+ /* Restore the selected frame, and then rethrow if there was a problem. */
+ select_frame (frame_find_by_id (cb_data.frame_id));
+ if (except.reason < 0)
+ throw_exception (except);
/* do_print_variable_and_value invalidates FRAME. */
frame = NULL;
are not combined in symbol-reading. */
sym2 = lookup_symbol (SYMBOL_LINKAGE_NAME (sym),
- b, VAR_DOMAIN, NULL);
+ b, VAR_DOMAIN, NULL).symbol;
(*cb) (SYMBOL_PRINT_NAME (sym), sym2, cb_data);
}
}
gdb_stdout);
}
-
-static void
-args_plus_locals_info (char *ignore, int from_tty)
-{
- args_info (ignore, from_tty);
- locals_info (ignore, from_tty);
-}
-\f
-
/* Select frame FRAME. Also print the stack frame and show the source
if this is the tui version. */
static void
void
select_frame_command (char *level_exp, int from_tty)
{
- select_frame (parse_frame_specification_1 (level_exp, "No stack.", NULL));
+ select_frame (parse_frame_specification (level_exp, NULL));
}
/* The "frame" command. With no argument, print the selected frame
print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
}
-/* The XDB Compatibility command to print the current frame. */
-
-static void
-current_frame_command (char *level_exp, int from_tty)
-{
- print_stack_frame (get_selected_frame (_("No stack.")), 1, SRC_AND_LOC, 1);
-}
-
/* Select the frame up one or COUNT_EXP stack levels from the
previously selected frame, and print it briefly. */
return_type = value_type (return_value);
}
do_cleanups (old_chain);
- CHECK_TYPEDEF (return_type);
+ return_type = check_typedef (return_type);
return_value = value_cast (return_type, return_value);
/* Make sure the value is fully evaluated. It may live in the
value_fetch_lazy (return_value);
if (thisfun != NULL)
- function = read_var_value (thisfun, thisframe);
+ function = read_var_value (thisfun, NULL, thisframe);
rv_conv = RETURN_VALUE_REGISTER_CONVENTION;
if (TYPE_CODE (return_type) == TYPE_CODE_VOID)
if (get_frame_type (get_current_frame ()) == DUMMY_FRAME)
frame_pop (get_current_frame ());
+ select_frame (get_current_frame ());
/* If interactive, print the frame that is now current. */
if (from_tty)
- frame_command ("0", 1);
- else
- select_frame_command ("0", 0);
+ print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
}
/* Sets the scope to input function name, provided that the function
struct function_bounds *func_bounds = NULL;
struct cleanup *cleanups;
- if (arg != NULL)
+ if (arg == NULL)
return;
- frame = parse_frame_specification ("0");
+ frame = get_current_frame ();
sals = decode_line_with_current_source (arg, DECODE_LINE_FUNFIRSTLINE);
cleanups = make_cleanup (xfree, sals.sals);
- func_bounds = (struct function_bounds *) xmalloc (
- sizeof (struct function_bounds) * sals.nelts);
+ func_bounds = XNEWVEC (struct function_bounds, sals.nelts);
make_cleanup (xfree, func_bounds);
for (i = 0; (i < sals.nelts && !found); i++)
{
else if (frame != get_selected_frame (NULL))
select_and_print_frame (frame);
}
-
-/* Gets the language of the current frame. */
-
-enum language
-get_frame_language (void)
-{
- struct frame_info *frame = deprecated_safe_get_selected_frame ();
-
- if (frame)
- {
- CORE_ADDR pc = 0;
- int pc_p = 0;
-
- /* We determine the current frame language by looking up its
- associated symtab. To retrieve this symtab, we use the frame
- PC. However we cannot use the frame PC as is, because it
- usually points to the instruction following the "call", which
- is sometimes the first instruction of another function. So
- we rely on get_frame_address_in_block(), it provides us with
- a PC that is guaranteed to be inside the frame's code
- block. */
-
- TRY
- {
- pc = get_frame_address_in_block (frame);
- pc_p = 1;
- }
- CATCH (ex, RETURN_MASK_ERROR)
- {
- if (ex.error != NOT_AVAILABLE_ERROR)
- throw_exception (ex);
- }
- END_CATCH
-
- if (pc_p)
- {
- struct compunit_symtab *cust = find_pc_compunit_symtab (pc);
-
- if (cust != NULL)
- return compunit_language (cust);
- }
- }
-
- return language_unknown;
-}
\f
/* Provide a prototype to silence -Wmissing-prototypes. */
add_com_alias ("f", "frame", class_stack, 1);
- if (xdb_commands)
- {
- add_com ("L", class_stack, current_frame_command,
- _("Print the current stack frame.\n"));
- add_com_alias ("V", "frame", class_stack, 1);
- }
add_com ("select-frame", class_stack, select_frame_command, _("\
Select a stack frame without printing anything.\n\
An argument specifies the frame to select.\n\
Use of the 'no-filters' qualifier prohibits frame filters from executing\n\
on this backtrace.\n"));
add_com_alias ("bt", "backtrace", class_stack, 0);
- if (xdb_commands)
- {
- add_com_alias ("t", "backtrace", class_stack, 0);
- add_com ("T", class_stack, backtrace_full_command, _("\
-Print backtrace of all stack frames, or innermost COUNT frames\n\
-and the values of the local variables.\n\
-With a negative argument, print outermost -COUNT frames.\n\
-Usage: T <count>\n"));
- }
add_com_alias ("where", "backtrace", class_alias, 0);
add_info ("stack", backtrace_command,
_("Local variables of current stack frame."));
add_info ("args", args_info,
_("Argument variables of current stack frame."));
- if (xdb_commands)
- add_com ("l", class_info, args_plus_locals_info,
- _("Argument and local variables of current stack frame."));
if (dbx_commands)
add_com ("func", class_stack, func_command, _("\