Index: gdb/stack.c |
diff --git a/gdb/stack.c b/gdb/stack.c |
index 35d379d55ec24e9561b7992ce8e0e2aea37790ff..f45bb8050a45f5acac1913dfd4dbd58e58951e18 100644 |
--- a/gdb/stack.c |
+++ b/gdb/stack.c |
@@ -1,6 +1,6 @@ |
/* Print and select stack frames for GDB, the GNU debugger. |
- Copyright (C) 1986-2005, 2007-2012 Free Software Foundation, Inc. |
+ Copyright (C) 1986-2013 Free Software Foundation, Inc. |
This file is part of GDB. |
@@ -46,13 +46,14 @@ |
#include "disasm.h" |
#include "inline-frame.h" |
#include "linespec.h" |
+#include "cli/cli-utils.h" |
#include "gdb_assert.h" |
#include <ctype.h> |
-#include "gdb_string.h" |
+#include <string.h> |
-#include "psymtab.h" |
#include "symfile.h" |
+#include "python/python.h" |
void (*deprecated_selected_frame_level_changed_hook) (int); |
@@ -63,6 +64,9 @@ static const char *const print_frame_arguments_choices[] = |
{"all", "scalars", "none", NULL}; |
static const char *print_frame_arguments = "scalars"; |
+/* If non-zero, don't invoke pretty-printers for frame arguments. */ |
+static int print_raw_frame_arguments; |
+ |
/* The possible choices of "set print entry-values", and the value |
of this setting. */ |
@@ -150,7 +154,8 @@ frame_show_address (struct frame_info *frame, |
void |
print_stack_frame (struct frame_info *frame, int print_level, |
- enum print_what print_what) |
+ enum print_what print_what, |
+ int set_current_sal) |
{ |
volatile struct gdb_exception e; |
@@ -162,8 +167,10 @@ print_stack_frame (struct frame_info *frame, int print_level, |
{ |
int center = (print_what == SRC_LINE || print_what == SRC_AND_LOC); |
- print_frame_info (frame, print_level, print_what, 1 /* print_args */); |
- set_current_sal_from_frame (frame, center); |
+ print_frame_info (frame, print_level, print_what, 1 /* print_args */, |
+ set_current_sal); |
+ if (set_current_sal) |
+ set_current_sal_from_frame (frame, center); |
} |
} |
@@ -273,8 +280,9 @@ print_frame_arg (const struct frame_arg *arg) |
else |
language = current_language; |
- get_raw_print_options (&opts); |
+ get_no_prettyformat_print_options (&opts); |
opts.deref_ref = 1; |
+ opts.raw = print_raw_frame_arguments; |
/* True in "summary" mode, false otherwise. */ |
opts.summary = !strcmp (print_frame_arguments, "scalars"); |
@@ -295,6 +303,27 @@ print_frame_arg (const struct frame_arg *arg) |
annotate_arg_end (); |
} |
+/* Read in inferior function local SYM at FRAME into ARGP. Caller is |
+ responsible for xfree of ARGP->ERROR. This function never throws an |
+ exception. */ |
+ |
+void |
+read_frame_local (struct symbol *sym, struct frame_info *frame, |
+ struct frame_arg *argp) |
+{ |
+ volatile struct gdb_exception except; |
+ struct value *val = NULL; |
+ |
+ TRY_CATCH (except, RETURN_MASK_ERROR) |
+ { |
+ val = read_var_value (sym, frame); |
+ } |
+ |
+ argp->error = (val == NULL) ? xstrdup (except.message) : NULL; |
+ argp->sym = sym; |
+ argp->val = val; |
+} |
+ |
/* Read in inferior function parameter SYM at FRAME into ARGP. Caller is |
responsible for xfree of ARGP->ERROR. This function never throws an |
exception. */ |
@@ -322,7 +351,8 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame, |
} |
} |
- if (SYMBOL_CLASS (sym) == LOC_COMPUTED |
+ if (SYMBOL_COMPUTED_OPS (sym) != NULL |
+ && SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry != NULL |
&& print_entry_values != print_entry_values_no |
&& (print_entry_values != print_entry_values_if_needed |
|| !val || value_optimized_out (val))) |
@@ -354,14 +384,11 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame, |
if (val && entryval && !ui_out_is_mi_like_p (current_uiout)) |
{ |
- unsigned len = TYPE_LENGTH (value_type (val)); |
+ struct type *type = value_type (val); |
- if (!value_optimized_out (val) && value_lazy (val)) |
- value_fetch_lazy (val); |
- if (!value_optimized_out (val) && value_lazy (entryval)) |
- value_fetch_lazy (entryval); |
if (!value_optimized_out (val) |
- && value_available_contents_eq (val, 0, entryval, 0, len)) |
+ && value_available_contents_eq (val, 0, entryval, 0, |
+ TYPE_LENGTH (type))) |
{ |
/* Initialize it just to avoid a GCC false warning. */ |
struct value *val_deref = NULL, *entryval_deref; |
@@ -373,12 +400,12 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame, |
TRY_CATCH (except, RETURN_MASK_ERROR) |
{ |
- unsigned len_deref; |
+ struct type *type_deref; |
val_deref = coerce_ref (val); |
if (value_lazy (val_deref)) |
value_fetch_lazy (val_deref); |
- len_deref = TYPE_LENGTH (value_type (val_deref)); |
+ type_deref = value_type (val_deref); |
entryval_deref = coerce_ref (entryval); |
if (value_lazy (entryval_deref)) |
@@ -389,7 +416,7 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame, |
if (val != val_deref |
&& value_available_contents_eq (val_deref, 0, |
entryval_deref, 0, |
- len_deref)) |
+ TYPE_LENGTH (type_deref))) |
val_equal = 1; |
} |
@@ -444,7 +471,10 @@ read_frame_arg (struct symbol *sym, struct frame_info *frame, |
|| print_entry_values == print_entry_values_both |
|| (print_entry_values == print_entry_values_preferred |
&& (!val || value_optimized_out (val)))) |
- entryval = allocate_optimized_out_value (SYMBOL_TYPE (sym)); |
+ { |
+ entryval = allocate_optimized_out_value (SYMBOL_TYPE (sym)); |
+ entryval_error = NULL; |
+ } |
} |
if ((print_entry_values == print_entry_values_compact |
|| print_entry_values == print_entry_values_if_needed |
@@ -503,8 +533,6 @@ print_frame_args (struct symbol *func, struct frame_info *frame, |
struct ui_file *stb; |
/* True if we should print arguments, false otherwise. */ |
int print_args = strcmp (print_frame_arguments, "none"); |
- /* True in "summary" mode, false otherwise. */ |
- int summary = !strcmp (print_frame_arguments, "scalars"); |
stb = mem_fileopen (); |
old_chain = make_cleanup_ui_file_delete (stb); |
@@ -755,7 +783,8 @@ do_gdb_disassembly (struct gdbarch *gdbarch, |
void |
print_frame_info (struct frame_info *frame, int print_level, |
- enum print_what print_what, int print_args) |
+ enum print_what print_what, int print_args, |
+ int set_current_sal) |
{ |
struct gdbarch *gdbarch = get_frame_arch (frame); |
struct symtab_and_line sal; |
@@ -880,7 +909,7 @@ print_frame_info (struct frame_info *frame, int print_level, |
do_gdb_disassembly (get_frame_arch (frame), -1, sal.pc, sal.end); |
} |
- if (print_what != LOCATION) |
+ if (set_current_sal) |
{ |
CORE_ADDR pc; |
@@ -1002,10 +1031,10 @@ get_last_displayed_sal (struct symtab_and_line *sal) |
/* Attempt to obtain the FUNNAME, FUNLANG and optionally FUNCP of the function |
- corresponding to FRAME. */ |
+ corresponding to FRAME. FUNNAME needs to be freed by the caller. */ |
void |
-find_frame_funname (struct frame_info *frame, const char **funname, |
+find_frame_funname (struct frame_info *frame, char **funname, |
enum language *funlang, struct symbol **funcp) |
{ |
struct symbol *func; |
@@ -1036,27 +1065,29 @@ find_frame_funname (struct frame_info *frame, const char **funname, |
changed (and we'll create a find_pc_minimal_function or some |
such). */ |
- struct minimal_symbol *msymbol = NULL; |
+ 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)); |
- if (msymbol != NULL |
- && (SYMBOL_VALUE_ADDRESS (msymbol) |
+ if (msymbol.minsym != NULL |
+ && (SYMBOL_VALUE_ADDRESS (msymbol.minsym) |
> BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) |
{ |
/* We also don't know anything about the function besides |
its address and name. */ |
func = 0; |
- *funname = SYMBOL_PRINT_NAME (msymbol); |
- *funlang = SYMBOL_LANGUAGE (msymbol); |
+ *funname = xstrdup (SYMBOL_PRINT_NAME (msymbol.minsym)); |
+ *funlang = SYMBOL_LANGUAGE (msymbol.minsym); |
} |
else |
{ |
- *funname = SYMBOL_PRINT_NAME (func); |
+ *funname = xstrdup (SYMBOL_PRINT_NAME (func)); |
*funlang = SYMBOL_LANGUAGE (func); |
if (funcp) |
*funcp = func; |
@@ -1071,25 +1102,25 @@ find_frame_funname (struct frame_info *frame, const char **funname, |
if (func_only) |
{ |
+ xfree (*funname); |
*funname = func_only; |
- make_cleanup (xfree, func_only); |
} |
} |
} |
} |
else |
{ |
- struct minimal_symbol *msymbol; |
+ struct bound_minimal_symbol msymbol; |
CORE_ADDR pc; |
if (!get_frame_address_in_block_if_available (frame, &pc)) |
return; |
msymbol = lookup_minimal_symbol_by_pc (pc); |
- if (msymbol != NULL) |
+ if (msymbol.minsym != NULL) |
{ |
- *funname = SYMBOL_PRINT_NAME (msymbol); |
- *funlang = SYMBOL_LANGUAGE (msymbol); |
+ *funname = xstrdup (SYMBOL_PRINT_NAME (msymbol.minsym)); |
+ *funlang = SYMBOL_LANGUAGE (msymbol.minsym); |
} |
} |
} |
@@ -1101,7 +1132,7 @@ print_frame (struct frame_info *frame, int print_level, |
{ |
struct gdbarch *gdbarch = get_frame_arch (frame); |
struct ui_out *uiout = current_uiout; |
- const char *funname = NULL; |
+ char *funname = NULL; |
enum language funlang = language_unknown; |
struct ui_file *stb; |
struct cleanup *old_chain, *list_chain; |
@@ -1116,6 +1147,7 @@ print_frame (struct frame_info *frame, int print_level, |
old_chain = make_cleanup_ui_file_delete (stb); |
find_frame_funname (frame, &funname, &funlang, &func); |
+ make_cleanup (xfree, funname); |
annotate_frame_begin (print_level ? frame_relative_level (frame) : 0, |
gdbarch, pc); |
@@ -1177,19 +1209,21 @@ print_frame (struct frame_info *frame, int print_level, |
QUIT; |
} |
ui_out_text (uiout, ")"); |
- if (sal.symtab && sal.symtab->filename) |
+ if (sal.symtab) |
{ |
+ const char *filename_display; |
+ |
+ filename_display = symtab_to_filename_for_display (sal.symtab); |
annotate_frame_source_begin (); |
ui_out_wrap_hint (uiout, " "); |
ui_out_text (uiout, " at "); |
annotate_frame_source_file (); |
- ui_out_field_string (uiout, "file", sal.symtab->filename); |
+ ui_out_field_string (uiout, "file", filename_display); |
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); |
+ ui_out_field_string (uiout, "fullname", fullname); |
} |
annotate_frame_source_file_end (); |
ui_out_text (uiout, ":"); |
@@ -1198,14 +1232,11 @@ print_frame (struct frame_info *frame, int print_level, |
annotate_frame_source_end (); |
} |
- if (pc_p && (!funname || (!sal.symtab || !sal.symtab->filename))) |
+ if (pc_p && (funname == NULL || sal.symtab == NULL)) |
{ |
-#ifdef PC_SOLIB |
- char *lib = PC_SOLIB (get_frame_pc (frame)); |
-#else |
char *lib = solib_name_from_address (get_frame_program_space (frame), |
get_frame_pc (frame)); |
-#endif |
+ |
if (lib) |
{ |
annotate_frame_where (); |
@@ -1248,8 +1279,7 @@ parse_frame_specification_1 (const char *frame_exp, const char *message, |
const char *p; |
/* Skip leading white space, bail of EOL. */ |
- while (isspace (*frame_exp)) |
- frame_exp++; |
+ frame_exp = skip_spaces_const (frame_exp); |
if (!*frame_exp) |
break; |
@@ -1377,7 +1407,9 @@ frame_info (char *addr_exp, int from_tty) |
struct cleanup *back_to = make_cleanup (null_cleanup, NULL); |
CORE_ADDR frame_pc; |
int frame_pc_p; |
- CORE_ADDR caller_pc; |
+ /* Initialize it to avoid "may be used uninitialized" warning. */ |
+ CORE_ADDR caller_pc = 0; |
+ volatile struct gdb_exception ex; |
fi = parse_frame_specification_1 (addr_exp, "No stack.", &selected_frame_p); |
gdbarch = get_frame_arch (fi); |
@@ -1422,13 +1454,13 @@ frame_info (char *addr_exp, int from_tty) |
} |
else if (frame_pc_p) |
{ |
- struct minimal_symbol *msymbol; |
+ struct bound_minimal_symbol msymbol; |
msymbol = lookup_minimal_symbol_by_pc (frame_pc); |
- if (msymbol != NULL) |
+ if (msymbol.minsym != NULL) |
{ |
- funname = SYMBOL_PRINT_NAME (msymbol); |
- funlang = SYMBOL_LANGUAGE (msymbol); |
+ funname = SYMBOL_PRINT_NAME (msymbol.minsym); |
+ funlang = SYMBOL_LANGUAGE (msymbol.minsym); |
} |
} |
calling_frame_info = get_prev_frame (fi); |
@@ -1459,14 +1491,33 @@ frame_info (char *addr_exp, int from_tty) |
} |
wrap_here (" "); |
if (sal.symtab) |
- printf_filtered (" (%s:%d)", sal.symtab->filename, sal.line); |
+ printf_filtered (" (%s:%d)", symtab_to_filename_for_display (sal.symtab), |
+ sal.line); |
puts_filtered ("; "); |
wrap_here (" "); |
- printf_filtered ("saved %s ", pc_regname); |
- if (frame_unwind_caller_pc_if_available (fi, &caller_pc)) |
- fputs_filtered (paddress (gdbarch, caller_pc), gdb_stdout); |
+ printf_filtered ("saved %s = ", pc_regname); |
+ |
+ TRY_CATCH (ex, RETURN_MASK_ERROR) |
+ { |
+ caller_pc = frame_unwind_caller_pc (fi); |
+ } |
+ if (ex.reason < 0) |
+ { |
+ 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; |
+ } |
+ } |
else |
- fputs_filtered ("<unavailable>", gdb_stdout); |
+ fputs_filtered (paddress (gdbarch, caller_pc), gdb_stdout); |
printf_filtered ("\n"); |
if (calling_frame_info == NULL) |
@@ -1649,13 +1700,15 @@ frame_info (char *addr_exp, int from_tty) |
frames. */ |
static void |
-backtrace_command_1 (char *count_exp, int show_locals, int from_tty) |
+backtrace_command_1 (char *count_exp, int show_locals, int no_filters, |
+ int from_tty) |
{ |
struct frame_info *fi; |
int count; |
int i; |
struct frame_info *trailing; |
- int trailing_level; |
+ int trailing_level, py_start = 0, py_end = 0; |
+ enum py_bt_status result = PY_BT_ERROR; |
if (!target_has_stack) |
error (_("No stack.")); |
@@ -1674,6 +1727,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty) |
{ |
struct frame_info *current; |
+ py_start = count; |
count = -count; |
current = trailing; |
@@ -1695,9 +1749,17 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty) |
count = -1; |
} |
+ else |
+ { |
+ py_start = 0; |
+ py_end = count; |
+ } |
} |
else |
- count = -1; |
+ { |
+ py_end = -1; |
+ count = -1; |
+ } |
if (info_verbose) |
{ |
@@ -1717,49 +1779,74 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty) |
} |
} |
- for (i = 0, fi = trailing; fi && count--; i++, fi = get_prev_frame (fi)) |
+ if (! no_filters) |
{ |
- QUIT; |
+ int flags = PRINT_LEVEL | PRINT_FRAME_INFO | PRINT_ARGS; |
+ enum py_frame_args arg_type; |
- /* Don't use print_stack_frame; if an error() occurs it probably |
- means further attempts to backtrace would fail (on the other |
- hand, perhaps the code does or could be fixed to make sure |
- the frame->prev field gets set to NULL in that case). */ |
- print_frame_info (fi, 1, LOCATION, 1); |
if (show_locals) |
+ flags |= PRINT_LOCALS; |
+ |
+ if (!strcmp (print_frame_arguments, "scalars")) |
+ arg_type = CLI_SCALAR_VALUES; |
+ else if (!strcmp (print_frame_arguments, "all")) |
+ arg_type = CLI_ALL_VALUES; |
+ else |
+ arg_type = NO_VALUES; |
+ |
+ result = apply_frame_filter (get_current_frame (), flags, arg_type, |
+ current_uiout, py_start, py_end); |
+ |
+ } |
+ /* Run the inbuilt backtrace if there are no filters registered, or |
+ "no-filters" has been specified from the command. */ |
+ if (no_filters || result == PY_BT_NO_FILTERS) |
+ { |
+ for (i = 0, fi = trailing; fi && count--; i++, fi = get_prev_frame (fi)) |
{ |
- struct frame_id frame_id = get_frame_id (fi); |
+ QUIT; |
- print_frame_local_vars (fi, 1, gdb_stdout); |
+ /* Don't use print_stack_frame; if an error() occurs it probably |
+ means further attempts to backtrace would fail (on the other |
+ hand, perhaps the code does or could be fixed to make sure |
+ the frame->prev field gets set to NULL in that case). */ |
- /* print_frame_local_vars invalidates FI. */ |
- fi = frame_find_by_id (frame_id); |
- if (fi == NULL) |
+ print_frame_info (fi, 1, LOCATION, 1, 0); |
+ if (show_locals) |
{ |
- trailing = NULL; |
- warning (_("Unable to restore previously selected frame.")); |
- break; |
+ struct frame_id frame_id = get_frame_id (fi); |
+ |
+ print_frame_local_vars (fi, 1, gdb_stdout); |
+ |
+ /* print_frame_local_vars invalidates FI. */ |
+ fi = frame_find_by_id (frame_id); |
+ if (fi == NULL) |
+ { |
+ trailing = NULL; |
+ warning (_("Unable to restore previously selected frame.")); |
+ break; |
+ } |
} |
- } |
- /* Save the last frame to check for error conditions. */ |
- trailing = fi; |
- } |
+ /* Save the last frame to check for error conditions. */ |
+ trailing = fi; |
+ } |
- /* If we've stopped before the end, mention that. */ |
- if (fi && from_tty) |
- printf_filtered (_("(More stack frames follow...)\n")); |
+ /* If we've stopped before the end, mention that. */ |
+ if (fi && from_tty) |
+ printf_filtered (_("(More stack frames follow...)\n")); |
- /* If we've run out of frames, and the reason appears to be an error |
- condition, print it. */ |
- if (fi == NULL && trailing != NULL) |
- { |
- enum unwind_stop_reason reason; |
+ /* If we've run out of frames, and the reason appears to be an error |
+ condition, print it. */ |
+ if (fi == NULL && trailing != NULL) |
+ { |
+ enum unwind_stop_reason reason; |
- reason = get_frame_unwind_stop_reason (trailing); |
- if (reason >= UNWIND_FIRST_ERROR) |
- printf_filtered (_("Backtrace stopped: %s\n"), |
- frame_stop_reason_string (reason)); |
+ reason = get_frame_unwind_stop_reason (trailing); |
+ if (reason >= UNWIND_FIRST_ERROR) |
+ printf_filtered (_("Backtrace stopped: %s\n"), |
+ frame_stop_reason_string (reason)); |
+ } |
} |
} |
@@ -1767,7 +1854,8 @@ static void |
backtrace_command (char *arg, int from_tty) |
{ |
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); |
- int fulltrace_arg = -1, arglen = 0, argc = 0; |
+ int fulltrace_arg = -1, arglen = 0, argc = 0, no_filters = -1; |
+ int user_arg = 0; |
if (arg) |
{ |
@@ -1784,25 +1872,31 @@ backtrace_command (char *arg, int from_tty) |
for (j = 0; j < strlen (argv[i]); j++) |
argv[i][j] = tolower (argv[i][j]); |
- if (fulltrace_arg < 0 && subset_compare (argv[i], "full")) |
- fulltrace_arg = argc; |
+ if (no_filters < 0 && subset_compare (argv[i], "no-filters")) |
+ no_filters = argc; |
else |
{ |
- arglen += strlen (argv[i]); |
- argc++; |
+ if (fulltrace_arg < 0 && subset_compare (argv[i], "full")) |
+ fulltrace_arg = argc; |
+ else |
+ { |
+ user_arg++; |
+ arglen += strlen (argv[i]); |
+ } |
} |
+ argc++; |
} |
- arglen += argc; |
- if (fulltrace_arg >= 0) |
+ arglen += user_arg; |
+ if (fulltrace_arg >= 0 || no_filters >= 0) |
{ |
if (arglen > 0) |
{ |
arg = xmalloc (arglen + 1); |
make_cleanup (xfree, arg); |
arg[0] = 0; |
- for (i = 0; i < (argc + 1); i++) |
+ for (i = 0; i < argc; i++) |
{ |
- if (i != fulltrace_arg) |
+ if (i != fulltrace_arg && i != no_filters) |
{ |
strcat (arg, argv[i]); |
strcat (arg, " "); |
@@ -1814,7 +1908,8 @@ backtrace_command (char *arg, int from_tty) |
} |
} |
- backtrace_command_1 (arg, fulltrace_arg >= 0 /* show_locals */, from_tty); |
+ backtrace_command_1 (arg, fulltrace_arg >= 0 /* show_locals */, |
+ no_filters >= 0 /* no frame-filters */, from_tty); |
do_cleanups (old_chain); |
} |
@@ -1822,7 +1917,7 @@ backtrace_command (char *arg, int from_tty) |
static void |
backtrace_full_command (char *arg, int from_tty) |
{ |
- backtrace_command_1 (arg, 1 /* show_locals */, from_tty); |
+ backtrace_command_1 (arg, 1 /* show_locals */, 0, from_tty); |
} |
@@ -1847,6 +1942,8 @@ iterate_over_block_locals (struct block *b, |
case LOC_COMPUTED: |
if (SYMBOL_IS_ARGUMENT (sym)) |
break; |
+ if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN) |
+ break; |
(*cb) (SYMBOL_PRINT_NAME (sym), sym, cb_data); |
break; |
@@ -2111,7 +2208,7 @@ select_and_print_frame (struct frame_info *frame) |
{ |
select_frame (frame); |
if (frame) |
- print_stack_frame (frame, 1, SRC_AND_LOC); |
+ print_stack_frame (frame, 1, SRC_AND_LOC, 1); |
} |
/* Return the symbol-block in which the selected frame is executing. |
@@ -2189,7 +2286,7 @@ static void |
frame_command (char *level_exp, int from_tty) |
{ |
select_frame_command (level_exp, from_tty); |
- print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); |
+ print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1); |
} |
/* The XDB Compatibility command to print the current frame. */ |
@@ -2197,7 +2294,7 @@ frame_command (char *level_exp, int from_tty) |
static void |
current_frame_command (char *level_exp, int from_tty) |
{ |
- print_stack_frame (get_selected_frame (_("No stack.")), 1, SRC_AND_LOC); |
+ 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 |
@@ -2228,7 +2325,7 @@ static void |
up_command (char *count_exp, int from_tty) |
{ |
up_silently_base (count_exp); |
- print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); |
+ print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1); |
} |
/* Select the frame down one or COUNT_EXP stack levels from the previously |
@@ -2267,13 +2364,15 @@ static void |
down_command (char *count_exp, int from_tty) |
{ |
down_silently_base (count_exp); |
- print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); |
+ print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1); |
} |
void |
return_command (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; |
struct frame_info *thisframe; |
struct gdbarch *gdbarch; |
struct symbol *thisfun; |
@@ -2308,7 +2407,8 @@ return_command (char *retval_exp, int from_tty) |
return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); |
if (return_type == NULL) |
{ |
- if (retval_expr->elts[0].opcode != UNOP_CAST) |
+ if (retval_expr->elts[0].opcode != UNOP_CAST |
+ && retval_expr->elts[0].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.")); |
@@ -2326,6 +2426,7 @@ return_command (char *retval_exp, int from_tty) |
if (thisfun != NULL) |
function = read_var_value (thisfun, thisframe); |
+ rv_conv = RETURN_VALUE_REGISTER_CONVENTION; |
if (TYPE_CODE (return_type) == TYPE_CODE_VOID) |
/* If the return-type is "void", don't try to find the |
return-value's location. However, do still evaluate the |
@@ -2333,14 +2434,18 @@ return_command (char *retval_exp, int from_tty) |
is discarded, side effects such as "return i++" still |
occur. */ |
return_value = NULL; |
- else if (thisfun != NULL |
- && using_struct_return (gdbarch, function, return_type)) |
+ else if (thisfun != NULL) |
{ |
- query_prefix = "The location at which to store the " |
- "function's return value is unknown.\n" |
- "If you continue, the return value " |
- "that you specified will be ignored.\n"; |
- return_value = NULL; |
+ rv_conv = struct_return_convention (gdbarch, function, return_type); |
+ if (rv_conv == RETURN_VALUE_STRUCT_CONVENTION |
+ || rv_conv == RETURN_VALUE_ABI_RETURNS_ADDRESS) |
+ { |
+ query_prefix = "The location at which to store the " |
+ "function's return value is unknown.\n" |
+ "If you continue, the return value " |
+ "that you specified will be ignored.\n"; |
+ return_value = NULL; |
+ } |
} |
} |
@@ -2370,9 +2475,8 @@ return_command (char *retval_exp, int from_tty) |
struct type *return_type = value_type (return_value); |
struct gdbarch *gdbarch = get_regcache_arch (get_current_regcache ()); |
- gdb_assert (gdbarch_return_value (gdbarch, function, return_type, NULL, |
- NULL, NULL) |
- == RETURN_VALUE_REGISTER_CONVENTION); |
+ gdb_assert (rv_conv != RETURN_VALUE_STRUCT_CONVENTION |
+ && rv_conv != RETURN_VALUE_ABI_RETURNS_ADDRESS); |
gdbarch_return_value (gdbarch, function, return_type, |
get_current_regcache (), NULL /*read*/, |
value_contents (return_value) /*write*/); |
@@ -2547,7 +2651,9 @@ It can be a stack frame number or the address of the frame.\n")); |
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")); |
+'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")); |
add_com_alias ("bt", "backtrace", class_stack, 0); |
if (xdb_commands) |
{ |
@@ -2585,6 +2691,15 @@ Usage: func <name>\n")); |
_("Show printing of non-scalar frame arguments"), |
NULL, NULL, NULL, &setprintlist, &showprintlist); |
+ add_setshow_boolean_cmd ("frame-arguments", no_class, |
+ &print_raw_frame_arguments, _("\ |
+Set whether to print frame arguments in raw form."), _("\ |
+Show whether to print frame arguments in raw form."), _("\ |
+If set, frame arguments are printed in raw form, bypassing any\n\ |
+pretty-printers for that value."), |
+ NULL, NULL, |
+ &setprintrawlist, &showprintrawlist); |
+ |
add_setshow_auto_boolean_cmd ("disassemble-next-line", class_stack, |
&disassemble_next_line, _("\ |
Set whether to disassemble next source line or insn when execution stops."), |