From 93d86cefdf1902d003f0d54f27777b8ea4f75b13 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Sun, 9 Oct 2011 19:30:25 +0000 Subject: gdb/ Code reshuffle. * frame.h (struct frame_arg): New definition. (read_frame_arg): New declaration. * mi/mi-cmd-stack.c (list_arg_or_local): New functiom from ... (list_args_or_locals): ... the code here. New variable arg, call read_frame_arg and list_arg_or_local with it. Unify the PRINT_SIMPLE_VALUES and PRINT_ALL_VALUES cases. Call xfree for arg.error. * stack.c (print_frame_arg): New functiom from the code of print_frame_args. (read_frame_arg): New function. (print_frame_args): Remove variable val. New variable arg, call read_frame_arg and print_frame_arg with it. Call xfree for arg.error. --- gdb/ChangeLog | 16 +++++ gdb/frame.h | 20 ++++++ gdb/mi/mi-cmd-stack.c | 130 +++++++++++++++++++++---------------- gdb/stack.c | 176 +++++++++++++++++++++++++++++++++----------------- 4 files changed, 229 insertions(+), 113 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3c11113..959c4c7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,21 @@ 2011-10-09 Jan Kratochvil + Code reshuffle. + * frame.h (struct frame_arg): New definition. + (read_frame_arg): New declaration. + * mi/mi-cmd-stack.c (list_arg_or_local): New functiom from ... + (list_args_or_locals): ... the code here. New variable arg, call + read_frame_arg and list_arg_or_local with it. Unify the + PRINT_SIMPLE_VALUES and PRINT_ALL_VALUES cases. Call xfree for + arg.error. + * stack.c (print_frame_arg): New functiom from the code of + print_frame_args. + (read_frame_arg): New function. + (print_frame_args): Remove variable val. New variable arg, call + read_frame_arg and print_frame_arg with it. Call xfree for arg.error. + +2011-10-09 Jan Kratochvil + Protect entry values against self tail calls. * dwarf2loc.c (VEC (CORE_ADDR), func_verify_no_selftailcall): New. (dwarf_expr_dwarf_reg_entry_value): Call func_verify_no_selftailcall. diff --git a/gdb/frame.h b/gdb/frame.h index 6a1e711..3850e11 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -711,6 +711,26 @@ extern int frame_register_read (struct frame_info *frame, int regnum, gdb_byte *buf); /* From stack.c. */ + +/* Inferior function parameter value read in from a frame. */ + +struct frame_arg +{ + /* Symbol for this parameter used for example for its name. */ + struct symbol *sym; + + /* Value of the parameter. It is NULL if ERROR is not NULL; if both VAL and + ERROR are NULL this parameter's value should not be printed. */ + struct value *val; + + /* String containing the error message, it is more usually NULL indicating no + error occured reading this parameter. */ + char *error; +}; + +extern void read_frame_arg (struct symbol *sym, struct frame_info *frame, + struct frame_arg *argp); + extern void args_info (char *, int); extern void locals_info (char *, int); diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c index 3654727..2e32eff 100644 --- a/gdb/mi/mi-cmd-stack.c +++ b/gdb/mi/mi-cmd-stack.c @@ -236,6 +236,72 @@ mi_cmd_stack_list_variables (char *command, char **argv, int argc) list_args_or_locals (all, parse_print_values (argv[0]), frame); } +/* Print single local or argument. ARG must be already read in. For WHAT and + VALUES see list_args_or_locals. + + Errors are printed as if they would be the parameter value. Use zeroed ARG + iff it should not be printed accoring to VALUES. */ + +static void +list_arg_or_local (const struct frame_arg *arg, enum what_to_list what, + enum print_values values) +{ + struct cleanup *cleanup_tuple = NULL; + struct ui_out *uiout = current_uiout; + struct ui_stream *stb = ui_out_stream_new (uiout); + + gdb_assert (!arg->val || !arg->error); + gdb_assert ((values == PRINT_NO_VALUES && arg->val == NULL + && arg->error == NULL) + || values == PRINT_SIMPLE_VALUES + || (values == PRINT_ALL_VALUES + && (arg->val != NULL || arg->error != NULL))); + + if (values != PRINT_NO_VALUES || what == all) + cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + + ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (arg->sym)); + + if (what == all && SYMBOL_IS_ARGUMENT (arg->sym)) + ui_out_field_int (uiout, "arg", 1); + + if (values == PRINT_SIMPLE_VALUES) + { + check_typedef (arg->sym->type); + type_print (arg->sym->type, "", stb->stream, -1); + ui_out_field_stream (uiout, "type", stb); + } + + if (arg->val || arg->error) + { + volatile struct gdb_exception except; + + if (arg->error) + except.message = arg->error; + else + { + /* TRY_CATCH has two statements, wrap it in a block. */ + + TRY_CATCH (except, RETURN_MASK_ERROR) + { + struct value_print_options opts; + + get_raw_print_options (&opts); + opts.deref_ref = 1; + common_val_print (arg->val, stb->stream, 0, &opts, + language_def (SYMBOL_LANGUAGE (arg->sym))); + } + } + if (except.message) + fprintf_filtered (stb->stream, _(""), + except.message); + ui_out_field_stream (uiout, "value", stb); + } + + ui_out_stream_delete (stb); + if (values != PRINT_NO_VALUES || what == all) + do_cleanups (cleanup_tuple); +} /* Print a list of the locals or the arguments for the currently selected frame. If the argument passed is 0, printonly the names @@ -313,16 +379,8 @@ list_args_or_locals (enum what_to_list what, enum print_values values, } if (print_me) { - struct cleanup *cleanup_tuple = NULL; struct symbol *sym2; - struct value *val; - - if (values != PRINT_NO_VALUES || what == all) - cleanup_tuple = - make_cleanup_ui_out_tuple_begin_end (uiout, NULL); - ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (sym)); - if (what == all && SYMBOL_IS_ARGUMENT (sym)) - ui_out_field_int (uiout, "arg", 1); + struct frame_arg arg; if (SYMBOL_IS_ARGUMENT (sym)) sym2 = lookup_symbol (SYMBOL_NATURAL_NAME (sym), @@ -330,64 +388,26 @@ list_args_or_locals (enum what_to_list what, enum print_values values, (int *) NULL); else sym2 = sym; + + memset (&arg, 0, sizeof (arg)); + arg.sym = sym2; + switch (values) { case PRINT_SIMPLE_VALUES: type = check_typedef (sym2->type); - type_print (sym2->type, "", stb->stream, -1); - ui_out_field_stream (uiout, "type", stb); if (TYPE_CODE (type) != TYPE_CODE_ARRAY && TYPE_CODE (type) != TYPE_CODE_STRUCT && TYPE_CODE (type) != TYPE_CODE_UNION) { - volatile struct gdb_exception except; - - TRY_CATCH (except, RETURN_MASK_ERROR) - { - struct value_print_options opts; - - val = read_var_value (sym2, fi); - get_raw_print_options (&opts); - opts.deref_ref = 1; - common_val_print - (val, stb->stream, 0, &opts, - language_def (SYMBOL_LANGUAGE (sym2))); - } - if (except.reason < 0) - fprintf_filtered (stb->stream, - _(""), - except.message); - - ui_out_field_stream (uiout, "value", stb); - } - break; case PRINT_ALL_VALUES: - { - volatile struct gdb_exception except; - - TRY_CATCH (except, RETURN_MASK_ERROR) - { - struct value_print_options opts; - - val = read_var_value (sym2, fi); - get_raw_print_options (&opts); - opts.deref_ref = 1; - common_val_print - (val, stb->stream, 0, &opts, - language_def (SYMBOL_LANGUAGE (sym2))); - } - if (except.reason < 0) - fprintf_filtered (stb->stream, - _(""), - except.message); - - ui_out_field_stream (uiout, "value", stb); - } + read_frame_arg (sym2, fi, &arg); + } break; } - if (values != PRINT_NO_VALUES || what == all) - do_cleanups (cleanup_tuple); + list_arg_or_local (&arg, what, values); + xfree (arg.error); } } if (BLOCK_FUNCTION (block)) diff --git a/gdb/stack.c b/gdb/stack.c index cf15512..bdc3b01 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -162,6 +162,113 @@ print_frame_nameless_args (struct frame_info *frame, long start, int num, } } +/* Print single argument of inferior function. ARG must be already + read in. + + Errors are printed as if they would be the parameter value. Use zeroed ARG + iff it should not be printed accoring to user settings. */ + +static void +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; + + stb = ui_out_stream_new (uiout); + old_chain = make_cleanup_ui_out_stream_delete (stb); + + gdb_assert (!arg->val || !arg->error); + + annotate_arg_begin (); + + make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + fprintf_symbol_filtered (stb->stream, SYMBOL_PRINT_NAME (arg->sym), + SYMBOL_LANGUAGE (arg->sym), DMGL_PARAMS | DMGL_ANSI); + ui_out_field_stream (uiout, "name", stb); + annotate_arg_name_end (); + ui_out_text (uiout, "="); + + if (!arg->val && !arg->error) + ui_out_text (uiout, "..."); + else + { + if (arg->error) + except.message = arg->error; + else + { + /* TRY_CATCH has two statements, wrap it in a block. */ + + TRY_CATCH (except, RETURN_MASK_ERROR) + { + const struct language_defn *language; + struct value_print_options opts; + + /* Avoid value_print because it will deref ref parameters. We + just want to print their addresses. Print ??? for args whose + address we do not know. We pass 2 as "recurse" to val_print + because our standard indentation here is 4 spaces, and + val_print indents 2 for each recurse. */ + + annotate_arg_value (value_type (arg->val)); + + /* Use the appropriate language to display our symbol, unless the + user forced the language to a specific language. */ + if (language_mode == language_mode_auto) + language = language_def (SYMBOL_LANGUAGE (arg->sym)); + else + language = current_language; + + get_raw_print_options (&opts); + opts.deref_ref = 0; + + /* True in "summary" mode, false otherwise. */ + opts.summary = !strcmp (print_frame_arguments, "scalars"); + + common_val_print (arg->val, stb->stream, 2, &opts, language); + } + } + if (except.message) + fprintf_filtered (stb->stream, _(""), + except.message); + } + + ui_out_field_stream (uiout, "value", stb); + + /* Aleo invoke ui_out_tuple_end. */ + do_cleanups (old_chain); + + annotate_arg_end (); +} + +/* Read in inferior function parameter SYM at FRAME into ARGP. Caller is + responsible for xfree of ARGP->ERROR. This function never throws an + exception. */ + +void +read_frame_arg (struct symbol *sym, struct frame_info *frame, + struct frame_arg *argp) +{ + struct value *val = NULL; + char *val_error = NULL; + volatile struct gdb_exception except; + + TRY_CATCH (except, RETURN_MASK_ERROR) + { + val = read_var_value (sym, frame); + } + if (!val) + { + val_error = alloca (strlen (except.message) + 1); + strcpy (val_error, except.message); + } + + argp->sym = sym; + argp->val = val; + argp->error = val_error ? xstrdup (val_error) : NULL; +} + /* Print the arguments of frame FRAME on STREAM, given the function FUNC running in that frame (as a symbol), where NUM is the number of arguments according to the stack frame (or -1 if the number of @@ -198,10 +305,11 @@ print_frame_args (struct symbol *func, struct frame_info *frame, struct block *b = SYMBOL_BLOCK_VALUE (func); struct dict_iterator iter; struct symbol *sym; - struct value *val; ALL_BLOCK_SYMBOLS (b, iter, sym) { + struct frame_arg arg; + QUIT; /* Keep track of the highest stack argument offset seen, and @@ -314,65 +422,17 @@ print_frame_args (struct symbol *func, struct frame_info *frame, ui_out_text (uiout, ", "); ui_out_wrap_hint (uiout, " "); - annotate_arg_begin (); - - list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); - fprintf_symbol_filtered (stb->stream, SYMBOL_PRINT_NAME (sym), - SYMBOL_LANGUAGE (sym), - DMGL_PARAMS | DMGL_ANSI); - ui_out_field_stream (uiout, "name", stb); - annotate_arg_name_end (); - ui_out_text (uiout, "="); - - if (print_args) - { - volatile struct gdb_exception except; - - TRY_CATCH (except, RETURN_MASK_ERROR) - { - const struct language_defn *language; - struct value_print_options opts; - - /* Avoid value_print because it will deref ref parameters. - We just want to print their addresses. Print ??? for - args whose address we do not know. We pass 2 as - "recurse" to val_print because our standard indentation - here is 4 spaces, and val_print indents 2 for each - recurse. */ - val = read_var_value (sym, frame); - - annotate_arg_value (value_type (val)); - - /* Use the appropriate language to display our symbol, - unless the user forced the language to a specific - language. */ - if (language_mode == language_mode_auto) - language = language_def (SYMBOL_LANGUAGE (sym)); - else - language = current_language; - - get_raw_print_options (&opts); - opts.deref_ref = 0; - opts.summary = summary; - common_val_print (val, stb->stream, 2, &opts, language); - ui_out_field_stream (uiout, "value", stb); - } - if (except.reason < 0) - { - fprintf_filtered (stb->stream, - _(""), - except.message); - ui_out_field_stream (uiout, "value", stb); - } - } - else - ui_out_text (uiout, "..."); - + if (!print_args) + { + memset (&arg, 0, sizeof (arg)); + arg.sym = sym; + } + else + read_frame_arg (sym, frame, &arg); - /* Invoke ui_out_tuple_end. */ - do_cleanups (list_chain); + print_frame_arg (&arg); - annotate_arg_end (); + xfree (arg.error); first = 0; } -- cgit v1.1