Index: gdb/stack.c |
diff --git a/gdb/stack.c b/gdb/stack.c |
index b15b5fcfa1f139d038d238cd9b6c9581a8a7a8bc..35d379d55ec24e9561b7992ce8e0e2aea37790ff 100644 |
--- a/gdb/stack.c |
+++ b/gdb/stack.c |
@@ -59,7 +59,7 @@ void (*deprecated_selected_frame_level_changed_hook) (int); |
/* The possible choices of "set print frame-arguments", and the value |
of this setting. */ |
-static const char *print_frame_arguments_choices[] = |
+static const char *const print_frame_arguments_choices[] = |
{"all", "scalars", "none", NULL}; |
static const char *print_frame_arguments = "scalars"; |
@@ -73,7 +73,7 @@ const char print_entry_values_if_needed[] = "if-needed"; |
const char print_entry_values_both[] = "both"; |
const char print_entry_values_compact[] = "compact"; |
const char print_entry_values_default[] = "default"; |
-static const char *print_entry_values_choices[] = |
+static const char *const print_entry_values_choices[] = |
{ |
print_entry_values_no, |
print_entry_values_only, |
@@ -210,10 +210,10 @@ print_frame_arg (const struct frame_arg *arg) |
struct ui_out *uiout = current_uiout; |
volatile struct gdb_exception except; |
struct cleanup *old_chain; |
- struct ui_stream *stb; |
+ struct ui_file *stb; |
- stb = ui_out_stream_new (uiout); |
- old_chain = make_cleanup_ui_out_stream_delete (stb); |
+ stb = mem_fileopen (); |
+ old_chain = make_cleanup_ui_file_delete (stb); |
gdb_assert (!arg->val || !arg->error); |
gdb_assert (arg->entry_kind == print_entry_values_no |
@@ -224,21 +224,21 @@ print_frame_arg (const struct frame_arg *arg) |
annotate_arg_begin (); |
make_cleanup_ui_out_tuple_begin_end (uiout, NULL); |
- fprintf_symbol_filtered (stb->stream, SYMBOL_PRINT_NAME (arg->sym), |
+ fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (arg->sym), |
SYMBOL_LANGUAGE (arg->sym), 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. */ |
- fputs_filtered ("=", stb->stream); |
+ fputs_filtered ("=", stb); |
- fprintf_symbol_filtered (stb->stream, SYMBOL_PRINT_NAME (arg->sym), |
+ fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (arg->sym), |
SYMBOL_LANGUAGE (arg->sym), |
DMGL_PARAMS | DMGL_ANSI); |
} |
if (arg->entry_kind == print_entry_values_only |
|| arg->entry_kind == print_entry_values_compact) |
- fputs_filtered ("@entry", stb->stream); |
+ fputs_filtered ("@entry", stb); |
ui_out_field_stream (uiout, "name", stb); |
annotate_arg_name_end (); |
ui_out_text (uiout, "="); |
@@ -279,17 +279,17 @@ print_frame_arg (const struct frame_arg *arg) |
/* True in "summary" mode, false otherwise. */ |
opts.summary = !strcmp (print_frame_arguments, "scalars"); |
- common_val_print (arg->val, stb->stream, 2, &opts, language); |
+ common_val_print (arg->val, stb, 2, &opts, language); |
} |
} |
if (except.message) |
- fprintf_filtered (stb->stream, _("<error reading variable: %s>"), |
+ fprintf_filtered (stb, _("<error reading variable: %s>"), |
except.message); |
} |
ui_out_field_stream (uiout, "value", stb); |
- /* Aleo invoke ui_out_tuple_end. */ |
+ /* Also invoke ui_out_tuple_end. */ |
do_cleanups (old_chain); |
annotate_arg_end (); |
@@ -499,20 +499,20 @@ print_frame_args (struct symbol *func, struct frame_info *frame, |
long highest_offset = -1; |
/* Number of ints of arguments that we have printed so far. */ |
int args_printed = 0; |
- struct cleanup *old_chain, *list_chain; |
- struct ui_stream *stb; |
+ struct cleanup *old_chain; |
+ 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 = ui_out_stream_new (uiout); |
- old_chain = make_cleanup_ui_out_stream_delete (stb); |
+ stb = mem_fileopen (); |
+ old_chain = make_cleanup_ui_file_delete (stb); |
if (func) |
{ |
struct block *b = SYMBOL_BLOCK_VALUE (func); |
- struct dict_iterator iter; |
+ struct block_iterator iter; |
struct symbol *sym; |
ALL_BLOCK_SYMBOLS (b, iter, sym) |
@@ -909,6 +909,12 @@ set_last_displayed_sal (int valid, struct program_space *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. */ |
@@ -999,7 +1005,7 @@ get_last_displayed_sal (struct symtab_and_line *sal) |
corresponding to FRAME. */ |
void |
-find_frame_funname (struct frame_info *frame, char **funname, |
+find_frame_funname (struct frame_info *frame, const char **funname, |
enum language *funlang, struct symbol **funcp) |
{ |
struct symbol *func; |
@@ -1095,9 +1101,9 @@ print_frame (struct frame_info *frame, int print_level, |
{ |
struct gdbarch *gdbarch = get_frame_arch (frame); |
struct ui_out *uiout = current_uiout; |
- char *funname = NULL; |
+ const char *funname = NULL; |
enum language funlang = language_unknown; |
- struct ui_stream *stb; |
+ struct ui_file *stb; |
struct cleanup *old_chain, *list_chain; |
struct value_print_options opts; |
struct symbol *func; |
@@ -1106,8 +1112,8 @@ print_frame (struct frame_info *frame, int print_level, |
pc_p = get_frame_pc_if_available (frame, &pc); |
- stb = ui_out_stream_new (uiout); |
- old_chain = make_cleanup_ui_out_stream_delete (stb); |
+ stb = mem_fileopen (); |
+ old_chain = make_cleanup_ui_file_delete (stb); |
find_frame_funname (frame, &funname, &funlang, &func); |
@@ -1137,7 +1143,7 @@ print_frame (struct frame_info *frame, int print_level, |
ui_out_text (uiout, " in "); |
} |
annotate_frame_function_name (); |
- fprintf_symbol_filtered (stb->stream, funname ? funname : "??", |
+ fprintf_symbol_filtered (stb, funname ? funname : "??", |
funlang, DMGL_ANSI); |
ui_out_field_stream (uiout, "func", stb); |
ui_out_wrap_hint (uiout, " "); |
@@ -1363,7 +1369,7 @@ frame_info (char *addr_exp, int from_tty) |
struct symtab *s; |
struct frame_info *calling_frame_info; |
int numregs; |
- char *funname = 0; |
+ const char *funname = 0; |
enum language funlang = language_unknown; |
const char *pc_regname; |
int selected_frame_p; |
@@ -1721,7 +1727,20 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty) |
the frame->prev field gets set to NULL in that case). */ |
print_frame_info (fi, 1, LOCATION, 1); |
if (show_locals) |
- print_frame_local_vars (fi, 1, gdb_stdout); |
+ { |
+ 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; |
@@ -1815,7 +1834,7 @@ iterate_over_block_locals (struct block *b, |
iterate_over_block_arg_local_vars_cb cb, |
void *cb_data) |
{ |
- struct dict_iterator iter; |
+ struct block_iterator iter; |
struct symbol *sym; |
ALL_BLOCK_SYMBOLS (b, iter, sym) |
@@ -1852,7 +1871,7 @@ static int |
print_block_frame_labels (struct gdbarch *gdbarch, struct block *b, |
int *have_default, struct ui_file *stream) |
{ |
- struct dict_iterator iter; |
+ struct block_iterator iter; |
struct symbol *sym; |
int values_printed = 0; |
@@ -1913,7 +1932,7 @@ iterate_over_block_local_vars (struct block *block, |
struct print_variable_and_value_data |
{ |
- struct frame_info *frame; |
+ struct frame_id frame_id; |
int num_tabs; |
struct ui_file *stream; |
int values_printed; |
@@ -1927,12 +1946,28 @@ do_print_variable_and_value (const char *print_name, |
void *cb_data) |
{ |
struct print_variable_and_value_data *p = cb_data; |
+ struct frame_info *frame; |
+ |
+ frame = frame_find_by_id (p->frame_id); |
+ if (frame == NULL) |
+ { |
+ warning (_("Unable to restore previously selected frame.")); |
+ return; |
+ } |
+ |
+ print_variable_and_value (print_name, sym, frame, p->stream, p->num_tabs); |
+ |
+ /* print_variable_and_value invalidates FRAME. */ |
+ frame = NULL; |
- print_variable_and_value (print_name, sym, |
- p->frame, p->stream, p->num_tabs); |
p->values_printed = 1; |
} |
+/* Print all variables from the innermost up to the function block of FRAME. |
+ Print them with values to STREAM indented by NUM_TABS. |
+ |
+ This function will invalidate FRAME. */ |
+ |
static void |
print_frame_local_vars (struct frame_info *frame, int num_tabs, |
struct ui_file *stream) |
@@ -1955,7 +1990,7 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs, |
return; |
} |
- cb_data.frame = frame; |
+ cb_data.frame_id = get_frame_id (frame); |
cb_data.num_tabs = 4 * num_tabs; |
cb_data.stream = stream; |
cb_data.values_printed = 0; |
@@ -1964,86 +1999,13 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs, |
do_print_variable_and_value, |
&cb_data); |
+ /* do_print_variable_and_value invalidates FRAME. */ |
+ frame = NULL; |
+ |
if (!cb_data.values_printed) |
fprintf_filtered (stream, _("No locals.\n")); |
} |
-/* Same, but print labels. */ |
- |
-static void |
-print_frame_label_vars (struct frame_info *frame, int this_level_only, |
- struct ui_file *stream) |
-{ |
-#if 1 |
- fprintf_filtered (stream, "print_frame_label_vars disabled.\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; |
- CORE_ADDR pc = get_frame_pc (frame); |
- |
- if (block == 0) |
- { |
- fprintf_filtered (stream, "No symbol table info available.\n"); |
- return; |
- } |
- |
- bl = blockvector_for_pc (BLOCK_END (block) - 4, &index); |
- blocks_printed = alloca (BLOCKVECTOR_NBLOCKS (bl) * sizeof (char)); |
- memset (blocks_printed, 0, BLOCKVECTOR_NBLOCKS (bl) * sizeof (char)); |
- |
- while (block != 0) |
- { |
- CORE_ADDR end = BLOCK_END (block) - 4; |
- int last_index; |
- |
- if (bl != blockvector_for_pc (end, &index)) |
- error (_("blockvector blotch")); |
- if (BLOCKVECTOR_BLOCK (bl, index) != block) |
- error (_("blockvector botch")); |
- last_index = BLOCKVECTOR_NBLOCKS (bl); |
- index += 1; |
- |
- /* Don't print out blocks that have gone by. */ |
- while (index < last_index |
- && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < pc) |
- index++; |
- |
- while (index < last_index |
- && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < end) |
- { |
- if (blocks_printed[index] == 0) |
- { |
- if (print_block_frame_labels (gdbarch, |
- BLOCKVECTOR_BLOCK (bl, index), |
- &have_default, stream)) |
- values_printed = 1; |
- blocks_printed[index] = 1; |
- } |
- index++; |
- } |
- if (have_default) |
- return; |
- if (values_printed && this_level_only) |
- return; |
- |
- /* 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); |
- } |
- |
- if (!values_printed && !this_level_only) |
- fprintf_filtered (stream, _("No catches.\n")); |
-#endif |
-} |
- |
void |
locals_info (char *args, int from_tty) |
{ |
@@ -2051,14 +2013,6 @@ locals_info (char *args, int from_tty) |
0, gdb_stdout); |
} |
-static void |
-catch_info (char *ignore, int from_tty) |
-{ |
- /* Assume g++ compiled code; old GDB 4.16 behaviour. */ |
- print_frame_label_vars (get_selected_frame (_("No frame selected.")), |
- 0, gdb_stdout); |
-} |
- |
/* Iterate over all the argument variables in block B. |
Returns 1 if any argument was walked; 0 otherwise. */ |
@@ -2068,7 +2022,7 @@ iterate_over_block_arg_vars (struct block *b, |
iterate_over_block_arg_local_vars_cb cb, |
void *cb_data) |
{ |
- struct dict_iterator iter; |
+ struct block_iterator iter; |
struct symbol *sym, *sym2; |
ALL_BLOCK_SYMBOLS (b, iter, sym) |
@@ -2094,6 +2048,11 @@ iterate_over_block_arg_vars (struct block *b, |
} |
} |
+/* Print all argument variables of the function of FRAME. |
+ Print them with values to STREAM. |
+ |
+ This function will invalidate FRAME. */ |
+ |
static void |
print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream) |
{ |
@@ -2114,7 +2073,7 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream) |
return; |
} |
- cb_data.frame = frame; |
+ cb_data.frame_id = get_frame_id (frame); |
cb_data.num_tabs = 0; |
cb_data.stream = gdb_stdout; |
cb_data.values_printed = 0; |
@@ -2122,6 +2081,9 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream) |
iterate_over_block_arg_vars (SYMBOL_BLOCK_VALUE (func), |
do_print_variable_and_value, &cb_data); |
+ /* do_print_variable_and_value invalidates FRAME. */ |
+ frame = NULL; |
+ |
if (!cb_data.values_printed) |
fprintf_filtered (stream, _("No arguments.\n")); |
} |
@@ -2316,6 +2278,7 @@ return_command (char *retval_exp, int from_tty) |
struct gdbarch *gdbarch; |
struct symbol *thisfun; |
struct value *return_value = NULL; |
+ struct value *function = NULL; |
const char *query_prefix = ""; |
thisframe = get_selected_frame ("No selected frame."); |
@@ -2360,6 +2323,9 @@ return_command (char *retval_exp, int from_tty) |
if (value_lazy (return_value)) |
value_fetch_lazy (return_value); |
+ if (thisfun != NULL) |
+ function = read_var_value (thisfun, thisframe); |
+ |
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 |
@@ -2368,8 +2334,7 @@ return_command (char *retval_exp, int from_tty) |
occur. */ |
return_value = NULL; |
else if (thisfun != NULL |
- && using_struct_return (gdbarch, |
- SYMBOL_TYPE (thisfun), return_type)) |
+ && using_struct_return (gdbarch, function, return_type)) |
{ |
query_prefix = "The location at which to store the " |
"function's return value is unknown.\n" |
@@ -2404,12 +2369,11 @@ 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 ()); |
- struct type *func_type = thisfun == NULL ? NULL : SYMBOL_TYPE (thisfun); |
- gdb_assert (gdbarch_return_value (gdbarch, func_type, return_type, NULL, |
+ gdb_assert (gdbarch_return_value (gdbarch, function, return_type, NULL, |
NULL, NULL) |
== RETURN_VALUE_REGISTER_CONVENTION); |
- gdbarch_return_value (gdbarch, func_type, return_type, |
+ gdbarch_return_value (gdbarch, function, return_type, |
get_current_regcache (), NULL /*read*/, |
value_contents (return_value) /*write*/); |
} |
@@ -2449,7 +2413,7 @@ func_command (char *arg, int from_tty) |
return; |
frame = parse_frame_specification ("0"); |
- sals = decode_line_spec (arg, DECODE_LINE_FUNFIRSTLINE); |
+ 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); |
@@ -2615,9 +2579,6 @@ Usage: T <count>\n")); |
Select the stack frame that contains <func>.\n\ |
Usage: func <name>\n")); |
- add_info ("catch", catch_info, |
- _("Exceptions that can be caught in the current stack frame.")); |
- |
add_setshow_enum_cmd ("frame-arguments", class_stack, |
print_frame_arguments_choices, &print_frame_arguments, |
_("Set printing of non-scalar frame arguments"), |