Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
- 2009 Free Software Foundation, Inc.
+ 2009, 2010 Free Software Foundation, Inc.
This file is part of GDB.
#include <ctype.h>
#include "gdb_string.h"
+#include "psymtab.h"
+#include "symfile.h"
+
void (*deprecated_selected_frame_level_changed_hook) (int);
/* The possible choices of "set print frame-arguments, and the value
print_frame_nameless_args (struct frame_info *frame, long start, int num,
int first, struct ui_file *stream)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int i;
CORE_ADDR argsaddr;
long arg_value;
argsaddr = get_frame_args_address (frame);
if (!argsaddr)
return;
- arg_value = read_memory_integer (argsaddr + start, sizeof (int));
+ arg_value = read_memory_integer (argsaddr + start,
+ sizeof (int), byte_order);
if (!first)
fprintf_filtered (stream, ", ");
fprintf_filtered (stream, "%ld", arg_value);
if (*SYMBOL_LINKAGE_NAME (sym))
{
struct symbol *nsym;
+
nsym = lookup_symbol (SYMBOL_LINKAGE_NAME (sym),
b, VAR_DOMAIN, NULL);
gdb_assert (nsym != NULL);
struct gdb_disassembly_stub_args
{
+ struct gdbarch *gdbarch;
int how_many;
CORE_ADDR low;
CORE_ADDR high;
gdb_disassembly_stub (void *args)
{
struct gdb_disassembly_stub_args *p = args;
- gdb_disassembly (uiout, 0, 0, p->how_many, p->low, p->high);
+
+ gdb_disassembly (p->gdbarch, uiout, 0,
+ DISASSEMBLY_RAW_INSN, p->how_many,
+ p->low, p->high);
}
/* Use TRY_CATCH to catch the exception from the gdb_disassembly
because it will be broken by filter sometime. */
static void
-do_gdb_disassembly (int how_many, CORE_ADDR low, CORE_ADDR high)
+do_gdb_disassembly (struct gdbarch *gdbarch,
+ int how_many, CORE_ADDR low, CORE_ADDR high)
{
volatile struct gdb_exception exception;
struct gdb_disassembly_stub_args args;
+ args.gdbarch = gdbarch;
args.how_many = how_many;
args.low = low;
args.high = high;
print_frame_info (struct frame_info *frame, int print_level,
enum print_what print_what, int print_args)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
struct symtab_and_line sal;
int source_print;
int location_print;
= make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
- get_frame_pc (frame));
+ gdbarch, get_frame_pc (frame));
/* Do this regardless of SOURCE because we don't have any source
to list for this frame. */
if (ui_out_is_mi_like_p (uiout))
{
annotate_frame_address ();
- ui_out_field_core_addr (uiout, "addr", get_frame_pc (frame));
+ ui_out_field_core_addr (uiout, "addr",
+ gdbarch, get_frame_pc (frame));
annotate_frame_address_end ();
}
if ((disassemble_next_line == AUTO_BOOLEAN_AUTO
|| disassemble_next_line == AUTO_BOOLEAN_TRUE)
&& source_print && !sal.symtab)
- do_gdb_disassembly (1, get_frame_pc (frame), get_frame_pc (frame) + 1);
+ do_gdb_disassembly (get_frame_arch (frame), 1,
+ get_frame_pc (frame), get_frame_pc (frame) + 1);
if (source_print && sal.symtab)
{
else
{
struct value_print_options opts;
+
get_user_print_options (&opts);
/* We used to do this earlier, but that is clearly
wrong. This function is used by many different
ability to decide for themselves if it is desired. */
if (opts.addressprint && mid_statement)
{
- ui_out_field_core_addr (uiout, "addr", get_frame_pc (frame));
+ ui_out_field_core_addr (uiout, "addr",
+ gdbarch, get_frame_pc (frame));
ui_out_text (uiout, "\t");
}
/* 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 (-1, get_frame_pc (frame), sal.end);
+ do_gdb_disassembly (get_frame_arch (frame), -1, sal.pc, sal.end);
}
if (print_what != LOCATION)
- set_default_breakpoint (1, get_frame_pc (frame), sal.symtab, sal.line);
+ set_default_breakpoint (1, sal.pspace,
+ get_frame_pc (frame), sal.symtab, sal.line);
annotate_frame_end ();
with DMGL_PARAMS turned on, and here we don't want to
display parameters. So remove the parameters. */
char *func_only = cp_remove_params (*funname);
+
if (func_only)
{
*funname = func_only;
enum print_what print_what, int print_args,
struct symtab_and_line sal)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
char *funname = NULL;
enum language funlang = language_unknown;
struct ui_stream *stb;
find_frame_funname (frame, &funname, &funlang);
annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
- get_frame_pc (frame));
+ gdbarch, get_frame_pc (frame));
list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
|| print_what == LOC_AND_ADDRESS)
{
annotate_frame_address ();
- ui_out_field_core_addr (uiout, "addr", get_frame_pc (frame));
+ ui_out_field_core_addr (uiout, "addr", gdbarch, get_frame_pc (frame));
annotate_frame_address_end ();
ui_out_text (uiout, " in ");
}
{
struct print_args_args args;
struct cleanup *args_list_chain;
+
args.frame = frame;
args.func = find_pc_function (get_frame_address_in_block (frame));
args.stream = gdb_stdout;
if (ui_out_is_mi_like_p (uiout))
{
const char *fullname = symtab_to_fullname (sal.symtab);
+
if (fullname != NULL)
ui_out_field_string (uiout, "fullname", fullname);
}
#ifdef PC_SOLIB
char *lib = PC_SOLIB (get_frame_pc (frame));
#else
- char *lib = solib_name_from_address (get_frame_pc (frame));
+ char *lib = solib_name_from_address (get_frame_program_space (frame),
+ get_frame_pc (frame));
#endif
if (lib)
{
numargs = 0;
else
{
- char *addr_string;
- struct cleanup *tmp_cleanup;
-
numargs = 0;
while (1)
{
{
struct frame_info *fid;
int level = value_as_long (args[0]);
+
fid = find_relative_frame (get_current_frame (), &level);
if (level == 0)
/* find_relative_frame was successful */
/* Convert each value into a corresponding address. */
{
int i;
+
for (i = 0; i < numargs; i++)
addrs[i] = value_as_address (args[i]);
}
struct symbol *func;
struct symtab *s;
struct frame_info *calling_frame_info;
- int i, count, numregs;
+ int numregs;
char *funname = 0;
enum language funlang = language_unknown;
const char *pc_regname;
with DMGL_PARAMS turned on, and here we don't want to
display parameters. So remove the parameters. */
char *func_only = cp_remove_params (funname);
+
if (func_only)
{
funname = func_only;
{
printf_filtered (_("Stack frame at "));
}
- fputs_filtered (paddress (get_frame_base (fi)), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, get_frame_base (fi)), gdb_stdout);
printf_filtered (":\n");
printf_filtered (" %s = ", pc_regname);
- fputs_filtered (paddress (get_frame_pc (fi)), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, get_frame_pc (fi)), gdb_stdout);
wrap_here (" ");
if (funname)
puts_filtered ("; ");
wrap_here (" ");
printf_filtered ("saved %s ", pc_regname);
- fputs_filtered (paddress (frame_unwind_caller_pc (fi)), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, frame_unwind_caller_pc (fi)), gdb_stdout);
printf_filtered ("\n");
if (calling_frame_info == NULL)
else
{
printf_filtered (" called by frame at ");
- fputs_filtered (paddress (get_frame_base (calling_frame_info)),
+ fputs_filtered (paddress (gdbarch, get_frame_base (calling_frame_info)),
gdb_stdout);
}
if (get_next_frame (fi) && calling_frame_info)
if (get_next_frame (fi))
{
printf_filtered (" caller of frame at ");
- fputs_filtered (paddress (get_frame_base (get_next_frame (fi))),
+ fputs_filtered (paddress (gdbarch, get_frame_base (get_next_frame (fi))),
gdb_stdout);
}
if (get_next_frame (fi) || calling_frame_info)
else
{
printf_filtered (" Arglist at ");
- fputs_filtered (paddress (arg_list), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, arg_list), gdb_stdout);
printf_filtered (",");
if (!gdbarch_frame_num_args_p (gdbarch))
else
{
printf_filtered (" Locals at ");
- fputs_filtered (paddress (arg_list), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, arg_list), gdb_stdout);
printf_filtered (",");
}
}
&realnum, NULL);
if (!optimized && lval == not_lval)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
gdb_byte value[MAX_REGISTER_SIZE];
CORE_ADDR sp;
+
frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
&optimized, &lval, &addr,
&realnum, value);
/* NOTE: cagney/2003-05-22: This is assuming that the
stack pointer was packed as an unsigned integer. That
may or may not be valid. */
- sp = extract_unsigned_integer (value,
- register_size (gdbarch,
- gdbarch_sp_regnum (gdbarch)));
+ sp = extract_unsigned_integer (value, sp_size, byte_order);
printf_filtered (" Previous frame's sp is ");
- fputs_filtered (paddress (sp), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, sp), gdb_stdout);
printf_filtered ("\n");
need_nl = 0;
}
else if (!optimized && lval == lval_memory)
{
printf_filtered (" Previous frame's sp at ");
- fputs_filtered (paddress (addr), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, addr), gdb_stdout);
printf_filtered ("\n");
need_nl = 0;
}
wrap_here (" ");
printf_filtered (" %s at ",
gdbarch_register_name (gdbarch, i));
- fputs_filtered (paddress (addr), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, addr), gdb_stdout);
count++;
}
}
of frames which we should print, or -1 if all of them. */
trailing = get_current_frame ();
- /* The target can be in a state where there is no valid frames
- (e.g., just connected). */
- if (trailing == NULL)
- error (_("No stack."));
-
trailing_level = 0;
if (count_exp)
{
if (info_verbose)
{
- struct partial_symtab *ps;
-
/* 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
i = count;
for (fi = trailing; fi != NULL && i--; fi = get_prev_frame (fi))
{
+ CORE_ADDR pc;
+
QUIT;
- ps = find_pc_psymtab (get_frame_address_in_block (fi));
- if (ps)
- PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in. */
+ pc = get_frame_address_in_block (fi);
+ find_pc_sect_symtab_via_partial (pc, find_pc_mapped_section (pc));
}
}
backtrace_command_stub (void *data)
{
struct backtrace_command_args *args = data;
+
backtrace_command_1 (args->count_exp, args->show_locals, args->from_tty);
return 0;
}
backtrace_full_command (char *arg, int from_tty)
{
struct backtrace_command_args btargs;
+
btargs.count_exp = arg;
btargs.show_locals = 1;
btargs.from_tty = from_tty;
}
\f
-/* Print the local variables of a block B active in FRAME on STREAM.
- Return 1 if any variables were printed; 0 otherwise. */
+/* Iterate over the local variables of a block B, calling CB with
+ CB_DATA. */
-static int
-print_block_frame_locals (struct block *b, struct frame_info *frame,
- int num_tabs, struct ui_file *stream)
+static void
+iterate_over_block_locals (struct block *b,
+ iterate_over_block_arg_local_vars_cb cb,
+ void *cb_data)
{
struct dict_iterator iter;
struct symbol *sym;
- int values_printed = 0;
- int j;
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
case LOC_COMPUTED:
if (SYMBOL_IS_ARGUMENT (sym))
break;
- values_printed = 1;
- print_variable_and_value (NULL, sym, frame, stream, 4 * num_tabs);
+ (*cb) (SYMBOL_PRINT_NAME (sym), sym, cb_data);
break;
default:
break;
}
}
-
- return values_printed;
}
+
/* 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 block *b, int *have_default,
- struct ui_file *stream)
+print_block_frame_labels (struct gdbarch *gdbarch, struct block *b,
+ int *have_default, struct ui_file *stream)
{
struct dict_iterator iter;
struct symbol *sym;
{
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);
if (opts.addressprint)
{
fprintf_filtered (stream, " ");
- fputs_filtered (paddress (SYMBOL_VALUE_ADDRESS (sym)), 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
-/* Print on STREAM all the local variables in frame FRAME, including
- all the blocks active in that frame at its current PC.
+/* Iterate over all the local variables in block B, including all its
+ superblocks, stopping when the top-level block is reached. */
- Returns 1 if the job was done, or 0 if nothing was printed because
- we have no info on the function running in FRAME. */
+void
+iterate_over_block_local_vars (struct block *block,
+ iterate_over_block_arg_local_vars_cb cb,
+ void *cb_data)
+{
+ while (block)
+ {
+ iterate_over_block_locals (block, cb, cb_data);
+ /* After handling the function's top-level block, stop. Don't
+ continue to its superblock, the block of per-file
+ symbols. */
+ if (BLOCK_FUNCTION (block))
+ break;
+ block = BLOCK_SUPERBLOCK (block);
+ }
+}
+
+/* Data to be passed around in the calls to the locals and args
+ iterators. */
+
+struct print_variable_and_value_data
+{
+ struct frame_info *frame;
+ int num_tabs;
+ struct ui_file *stream;
+ int values_printed;
+};
+
+/* The callback for the locals and args iterators */
+
+static void
+do_print_variable_and_value (const char *print_name,
+ struct symbol *sym,
+ void *cb_data)
+{
+ struct print_variable_and_value_data *p = cb_data;
+
+ print_variable_and_value (print_name, sym,
+ p->frame, p->stream, p->num_tabs);
+ p->values_printed = 1;
+}
static void
print_frame_local_vars (struct frame_info *frame, int num_tabs,
struct ui_file *stream)
{
- struct block *block = get_frame_block (frame, 0);
- int values_printed = 0;
+ struct print_variable_and_value_data cb_data;
+ struct block *block;
+ block = get_frame_block (frame, 0);
if (block == 0)
{
fprintf_filtered (stream, "No symbol table info available.\n");
return;
}
- while (block)
- {
- if (print_block_frame_locals (block, frame, num_tabs, stream))
- values_printed = 1;
- /* After handling the function's top-level block, stop. Don't
- continue to its superblock, the block of per-file symbols.
- Also do not continue to the containing function of an inlined
- function. */
- if (BLOCK_FUNCTION (block))
- break;
- block = BLOCK_SUPERBLOCK (block);
- }
+ cb_data.frame = frame;
+ cb_data.num_tabs = 4 * num_tabs;
+ cb_data.stream = stream;
+ cb_data.values_printed = 0;
+
+ iterate_over_block_local_vars (block,
+ do_print_variable_and_value,
+ &cb_data);
- if (!values_printed)
+ if (!cb_data.values_printed)
fprintf_filtered (stream, _("No locals.\n"));
}
#else
struct blockvector *bl;
struct block *block = get_frame_block (frame, 0);
+ struct gdbarch *gdbarch = get_frame_arch (frame);
int values_printed = 0;
int index, have_default = 0;
char *blocks_printed;
{
if (blocks_printed[index] == 0)
{
- if (print_block_frame_labels (BLOCKVECTOR_BLOCK (bl, index),
+ if (print_block_frame_labels (gdbarch,
+ BLOCKVECTOR_BLOCK (bl, index),
&have_default, stream))
values_printed = 1;
blocks_printed[index] = 1;
static void
catch_info (char *ignore, int from_tty)
{
- struct symtab_and_line *sal;
-
/* Assume g++ compiled code; old GDB 4.16 behaviour. */
print_frame_label_vars (get_selected_frame (_("No frame selected.")),
0, gdb_stdout);
}
-static void
-print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
+/* Iterate over all the argument variables in block B.
+
+ Returns 1 if any argument was walked; 0 otherwise. */
+
+void
+iterate_over_block_arg_vars (struct block *b,
+ iterate_over_block_arg_local_vars_cb cb,
+ void *cb_data)
{
- struct symbol *func = get_frame_function (frame);
- struct block *b;
struct dict_iterator iter;
struct symbol *sym, *sym2;
- int values_printed = 0;
- if (func == 0)
- {
- fprintf_filtered (stream, _("No symbol table info available.\n"));
- return;
- }
-
- b = SYMBOL_BLOCK_VALUE (func);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
/* Don't worry about things which aren't arguments. */
if (SYMBOL_IS_ARGUMENT (sym))
{
- values_printed = 1;
-
/* We have to look up the symbol because arguments can have
two entries (one a parameter, one a local) and the one we
want is the local, which lookup_symbol will find for us.
sym2 = lookup_symbol (SYMBOL_LINKAGE_NAME (sym),
b, VAR_DOMAIN, NULL);
- print_variable_and_value (SYMBOL_PRINT_NAME (sym), sym2,
- frame, stream, 0);
+ (*cb) (SYMBOL_PRINT_NAME (sym), sym2, cb_data);
}
}
+}
+
+static void
+print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
+{
+ struct print_variable_and_value_data cb_data;
+ struct symbol *func;
+
+ func = get_frame_function (frame);
+ if (func == NULL)
+ {
+ fprintf_filtered (stream, _("No symbol table info available.\n"));
+ return;
+ }
- if (!values_printed)
+ cb_data.frame = frame;
+ cb_data.num_tabs = 0;
+ cb_data.stream = gdb_stdout;
+ cb_data.values_printed = 0;
+
+ iterate_over_block_arg_vars (SYMBOL_BLOCK_VALUE (func),
+ do_print_variable_and_value, &cb_data);
+
+ if (!cb_data.values_printed)
fprintf_filtered (stream, _("No arguments.\n"));
}
while (*level_offset_ptr > 0)
{
struct frame_info *prev = get_prev_frame (frame);
+
if (!prev)
break;
(*level_offset_ptr)--;
while (*level_offset_ptr < 0)
{
struct frame_info *next = get_next_frame (frame);
+
if (!next)
break;
(*level_offset_ptr)++;
{
struct frame_info *frame;
int count = -1;
+
if (count_exp)
count = -parse_and_eval_long (count_exp);
if (from_tty)
{
int confirmed;
+
if (thisfun == NULL)
confirmed = query (_("%sMake selected stack frame return now? "),
query_prefix);
void
_initialize_stack (void)
{
-#if 0
- backtrace_limit = 30;
-#endif
-
add_com ("return", class_stack, return_command, _("\
Make selected stack frame return to its caller.\n\
Control remains in the debugger, but when you continue\n\
{
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\
+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"));
show_disassemble_next_line,
&setlist, &showlist);
disassemble_next_line = AUTO_BOOLEAN_FALSE;
-
-#if 0
- add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command, _(\
-"Specify maximum number of frames for \"backtrace\" to print by default."),
- &setlist);
- add_info ("backtrace-limit", backtrace_limit_info, _("\
-The maximum number of frames for \"backtrace\" to print by default."));
-#endif
}