X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fstack.c;h=dfe3900e7c090332ce9d79d06f5d4bf6c15b73aa;hb=2bd7c093f663139ad9e57ddc748ade12f6bfbe01;hp=51dd1bc752ed7ec7d1f0f624e9b3be2d99082f65;hpb=aad95b57c5c4f5f11bd45e848a3ff3bafff1bfc5;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/stack.c b/gdb/stack.c index 51dd1bc752..dfe3900e7c 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1,8 +1,8 @@ /* Print and select stack frames for GDB, the GNU debugger. Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 - Free Software Foundation, Inc. + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, + 2009 Free Software Foundation, Inc. This file is part of GDB. @@ -45,6 +45,7 @@ #include "valprint.h" #include "gdbthread.h" #include "cp-support.h" +#include "disasm.h" #include "gdb_assert.h" #include @@ -57,7 +58,7 @@ void (*deprecated_selected_frame_level_changed_hook) (int); static const char *print_frame_arguments_choices[] = {"all", "scalars", "none", NULL}; -static const char *print_frame_arguments = "all"; +static const char *print_frame_arguments = "scalars"; /* Prototypes for local functions. */ @@ -180,9 +181,9 @@ print_this_frame_argument_p (struct symbol *sym) /* The user asked to print only the scalar arguments, so do not print the non-scalar ones. */ - type = CHECK_TYPEDEF (SYMBOL_TYPE (sym)); + type = check_typedef (SYMBOL_TYPE (sym)); while (TYPE_CODE (type) == TYPE_CODE_REF) - type = CHECK_TYPEDEF (TYPE_TARGET_TYPE (type)); + type = check_typedef (TYPE_TARGET_TYPE (type)); switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: @@ -456,6 +457,58 @@ set_current_sal_from_frame (struct frame_info *frame, int center) } } +/* If ON, GDB will display disassembly of the next source line when + execution of the program being debugged stops. + If AUTO (which is the default), or there's no line info to determine + the source line of the next instruction, display disassembly of next + instruction instead. */ + +static enum auto_boolean disassemble_next_line; + +static void +show_disassemble_next_line (struct ui_file *file, int from_tty, + struct cmd_list_element *c, + const char *value) +{ + fprintf_filtered (file, _("\ +Debugger's willingness to use disassemble-next-line is %s.\n"), + value); +} + +/* Show assembly codes; stub for catch_errors. */ + +struct gdb_disassembly_stub_args +{ + int how_many; + CORE_ADDR low; + CORE_ADDR high; +}; + +static void +gdb_disassembly_stub (void *args) +{ + struct gdb_disassembly_stub_args *p = args; + gdb_disassembly (uiout, 0, 0, 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) +{ + volatile struct gdb_exception exception; + struct gdb_disassembly_stub_args args; + + args.how_many = how_many; + args.low = low; + args.high = high; + TRY_CATCH (exception, RETURN_MASK_ALL) + { + gdb_disassembly_stub (&args); + } +} + /* Print information about frame FRAME. The output is format according to PRINT_LEVEL and PRINT_WHAT and PRINT ARGS. The meaning of PRINT_WHAT is: @@ -533,6 +586,13 @@ print_frame_info (struct frame_info *frame, int print_level, source_print = (print_what == SRC_LINE || print_what == SRC_AND_LOC); + /* If disassemble-next-line is set to auto or on and doesn't have + the line debug messages for $pc, output the next instruction. */ + 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); + if (source_print && sal.symtab) { int done = 0; @@ -569,6 +629,11 @@ print_frame_info (struct frame_info *frame, int print_level, print_source_lines (sal.symtab, sal.line, sal.line + 1, 0); } } + + /* 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); } if (print_what != LOCATION) @@ -579,20 +644,16 @@ print_frame_info (struct frame_info *frame, int print_level, gdb_flush (gdb_stdout); } -static void -print_frame (struct frame_info *frame, int print_level, - enum print_what print_what, int print_args, - struct symtab_and_line sal) +/* Attempt to obtain the FUNNAME and FUNLANG of the function corresponding + to FRAME. */ +void +find_frame_funname (struct frame_info *frame, char **funname, + enum language *funlang) { struct symbol *func; - char *funname = NULL; - enum language funlang = language_unknown; - struct ui_stream *stb; - struct cleanup *old_chain, *list_chain; - struct value_print_options opts; - stb = ui_out_stream_new (uiout); - old_chain = make_cleanup_ui_out_stream_delete (stb); + *funname = NULL; + *funlang = language_unknown; func = find_pc_function (get_frame_address_in_block (frame)); if (func) @@ -625,24 +686,24 @@ print_frame (struct frame_info *frame, int print_level, /* 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 = SYMBOL_PRINT_NAME (msymbol); + *funlang = SYMBOL_LANGUAGE (msymbol); } else { - funname = SYMBOL_PRINT_NAME (func); - funlang = SYMBOL_LANGUAGE (func); - if (funlang == language_cplus) + *funname = SYMBOL_PRINT_NAME (func); + *funlang = SYMBOL_LANGUAGE (func); + if (*funlang == language_cplus) { /* It seems appropriate to use SYMBOL_PRINT_NAME() here, to display the demangled name that we already have stored in the symbol table, but we stored a version 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); + char *func_only = cp_remove_params (*funname); if (func_only) { - funname = func_only; + *funname = func_only; make_cleanup (xfree, func_only); } } @@ -655,10 +716,27 @@ print_frame (struct frame_info *frame, int print_level, if (msymbol != NULL) { - funname = SYMBOL_PRINT_NAME (msymbol); - funlang = SYMBOL_LANGUAGE (msymbol); + *funname = SYMBOL_PRINT_NAME (msymbol); + *funlang = SYMBOL_LANGUAGE (msymbol); } } +} + +static void +print_frame (struct frame_info *frame, int print_level, + enum print_what print_what, int print_args, + struct symtab_and_line sal) +{ + char *funname = NULL; + enum language funlang = language_unknown; + struct ui_stream *stb; + struct cleanup *old_chain, *list_chain; + struct value_print_options opts; + + stb = ui_out_stream_new (uiout); + old_chain = make_cleanup_ui_out_stream_delete (stb); + + find_frame_funname (frame, &funname, &funlang); annotate_frame_begin (print_level ? frame_relative_level (frame) : 0, get_frame_pc (frame)); @@ -694,7 +772,7 @@ print_frame (struct frame_info *frame, int print_level, struct print_args_args args; struct cleanup *args_list_chain; args.frame = frame; - args.func = func; + args.func = find_pc_function (get_frame_address_in_block (frame)); args.stream = gdb_stdout; args_list_chain = make_cleanup_ui_out_list_begin_end (uiout, "args"); catch_errors (print_args_stub, &args, "", RETURN_MASK_ERROR); @@ -730,7 +808,7 @@ print_frame (struct frame_info *frame, int print_level, #ifdef PC_SOLIB char *lib = PC_SOLIB (get_frame_pc (frame)); #else - char *lib = solib_address (get_frame_pc (frame)); + char *lib = solib_name_from_address (get_frame_pc (frame)); #endif if (lib) { @@ -832,7 +910,7 @@ parse_frame_specification_1 (const char *frame_exp, const char *message, { int i; for (i = 0; i < numargs; i++) - addrs[i] = value_as_address (args[0]); + addrs[i] = value_as_address (args[i]); } /* Assume that the single arg[0] is an address, use that to identify @@ -1629,13 +1707,7 @@ select_and_print_frame (struct frame_info *frame) struct block * get_selected_block (CORE_ADDR *addr_in_block) { - if (!target_has_stack) - return 0; - - if (is_exited (inferior_ptid)) - return 0; - - if (is_executing (inferior_ptid)) + if (!has_stack_frames ()) return 0; return get_frame_block (get_selected_frame (NULL), addr_in_block); @@ -1796,18 +1868,27 @@ return_command (char *retval_exp, int from_tty) message. */ if (retval_exp) { + struct expression *retval_expr = parse_expression (retval_exp); + struct cleanup *old_chain = make_cleanup (xfree, retval_expr); struct type *return_type = NULL; /* Compute the return value. Should the computation fail, this call throws an error. */ - return_value = parse_and_eval (retval_exp); + return_value = evaluate_expression (retval_expr); /* Cast return value to the return type of the function. Should the cast fail, this call throws an error. */ if (thisfun != NULL) return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); if (return_type == NULL) - return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; + { + if (retval_expr->elts[0].opcode != UNOP_CAST) + error (_("Return value type not available for selected " + "stack frame.\n" + "Please use an explicit cast of the value to return.")); + return_type = value_type (return_value); + } + do_cleanups (old_chain); CHECK_TYPEDEF (return_type); return_value = value_cast (return_type, return_value); @@ -1823,7 +1904,8 @@ return_command (char *retval_exp, int from_tty) is discarded, side effects such as "return i++" still occur. */ return_value = NULL; - else if (using_struct_return (SYMBOL_TYPE (thisfun), return_type)) + else if (thisfun != NULL + && using_struct_return (SYMBOL_TYPE (thisfun), return_type)) { query_prefix = "\ The location at which to store the function's return value is unknown.\n\ @@ -1856,10 +1938,12 @@ If you continue, the return value that you specified will be ignored.\n"; { struct type *return_type = value_type (return_value); struct gdbarch *gdbarch = get_regcache_arch (get_current_regcache ()); - gdb_assert (gdbarch_return_value (gdbarch, SYMBOL_TYPE (thisfun), - return_type, NULL, NULL, NULL) + struct type *func_type = thisfun == NULL ? NULL : SYMBOL_TYPE (thisfun); + + gdb_assert (gdbarch_return_value (gdbarch, func_type, return_type, NULL, + NULL, NULL) == RETURN_VALUE_REGISTER_CONVENTION); - gdbarch_return_value (gdbarch, SYMBOL_TYPE (thisfun), return_type, + gdbarch_return_value (gdbarch, func_type, return_type, get_current_regcache (), NULL /*read*/, value_contents (return_value) /*write*/); } @@ -2059,6 +2143,20 @@ Usage: func \n")); _("Show printing of non-scalar frame arguments"), NULL, NULL, NULL, &setprintlist, &showprintlist); + add_setshow_auto_boolean_cmd ("disassemble-next-line", class_stack, + &disassemble_next_line, _("\ +Set whether to disassemble next source line when execution stops."), _("\ +Show whether to disassemble next source line when execution stops."), _("\ +If ON, GDB will display disassembly of the next source line when\n\ +execution of the program being debugged stops.\n\ +If AUTO (which is the default), or there's no line info to determine\n\ +the source line of the next instruction, display disassembly of next\n\ +instruction instead."), + NULL, + show_disassemble_next_line, + &setlist, &showlist); + disassemble_next_line = AUTO_BOOLEAN_AUTO; + #if 0 add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command, _(\ "Specify maximum number of frames for \"backtrace\" to print by default."),