| 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"),
|
|
|