* NEWS: Document inlined function support.
	* Makefile.in (SFILES): Add inline-frame.c.
	(COMMON_OBS): Add inline-frame.o.
	* block.c (contained_in): Rewrite to use lexical nesting.
	(block_linkage_function): Skip inlined function blocks.
	(block_inlined_p): New.
	* block.h (struct block): Update comment.
	(block_inlined_p): New prototype.
	* blockframe.c (get_frame_block): Handle inlined functions.
	(get_frame_function): Do not use block_linkage_function.
	(block_innermost_frame): Use get_frame_block and contained_in.
	* breakpoint.c (watchpoint_check): Remove extra reinit_frame_cache.
	Skip over inlined functions.  Simplify epilogue check.
	(bpstat_check_breakpoint_conditions): Use get_stack_frame_id.
	Update comments.
	(set_momentary_breakpoint): Only accept non-inlined frames.
	(watch_command_1): Use frame_unwind_caller_pc and
	frame_unwind_caller_id instead of get_prev_frame.
	(until_break_command): Likewise.  Use get_stack_frame_id.
	* buildsym.c (end_symtab): Set SYMBOL_SYMTAB for block functions.
	* dwarf2loc.c (dwarf_expr_frame_base): Use block_linkage_function.
	* dwarf2read.c (process_die): Handle DW_TAG_inlined_subroutine.
	(read_func_scope, new_symbol): Likewise.  Handle arguments specially
	for inlined functions without call site information.
	(inherit_abstract_dies): Allow tag mismatch for inlined subroutines.
	(die_specification): Treat DW_AT_abstract_origin as a specification.
	(read_type_die): Handle DW_TAG_inlined_subroutine.
	* frame-unwind.c (frame_unwind_init): Add inline_frame_unwind.
	* frame.c (fprint_frame_id): Print inline depth.
	(fprint_frame_type): Handle INLINE_FRAME and SENTINEL_FRAME.
	(skip_inlined_frames, get_stack_frame_id): New.
	(frame_unwind_caller_id): Use skip_inlined_frames.
	(frame_id_inlined_p): New.
	(frame_id_eq): Make the logic match the comments.  Add inline_depth
	check.
	(frame_id_inner): Handle inlined functions.
	(frame_unwind_pc): New function, copied from frame_unwind_caller_pc.
	(frame_unwind_caller_pc): Use skip_inlined_frames and frame_unwind_pc.
	(get_prev_frame_1): Check for inline frames.  Split out frame
	allocation to get_prev_frame_raw.
	(get_prev_frame_raw): New function.
	(get_prev_frame): Handle inline frames.
	(get_frame_pc): Use frame_unwind_pc.
	(get_frame_address_in_block): Skip inlined frames on both sides.
	(pc_notcurrent): Delete.
	(find_frame_sal): Rewrite to handle inline call sites.  Use
	get_frame_address_in_block.
	(deprecated_update_frame_pc_hack): Make static.
	* frame.h: Update comments.
	(struct frame_id): Add inline_depth.
	(enum frame_type): Add INLINE_FRAME.
	(frame_id_inlined_p, get_stack_frame_id): New prototypes.
	* gdbthread.h (struct thread_info): Add step_stack_frame_id field.
	* infcmd.c (set_step_frame): New function.
	(step_once): Use set_step_frame.  Handle inlined functions.
	(until_next_command): Use set_step_frame.
	(finish_backward), finish_forward): Use get_stack_frame_id.
	(finish_command): Support inlined functions.
	* inferior.h (set_step_info): New prototype.
	* infrun.c (RESUME_ALL): Use minus_one_ptid.
	(clear_proceed_status): Clear step_stack_frame_id.
	(init_wait_for_inferior): Call clear_inline_frame_state.
	(init_execution_control_state): Make static.
	(set_step_info): New function.
	(init_thread_stepping_state): Do not set the symtab or line here.
	(stepped_in_from): New function.
	(handle_inferior_event): Handle inlined functions.  Use set_step_info.
	(insert_step_resume_breakpoint_at_frame): Use get_stack_frame_id.
	(struct inferior_status): Add step_stack_frame_id.
	(save_inferior_status, restore_inferior_status): Save and restore
	step_stack_frame_id.
	* inline-frame.c, inline-frame.h: New files.
	* minsyms.c (prim_record_minimal_symbol_and_info): Use XCALLOC.
	* regcache.c (regcache_write_pc): Call reinit_frame_cache.
	* s390-tdep.c (s390_prologue_frame_unwind_cache): Handle INLINE_FRAME.
	* stack.c (frame_show_address): New.
	(print_frame_info, print_frame): Use it.
	(find_frame_funname): Use get_frame_function.  Handle inlined blocks.
	(frame_info): Mark inlined functions.
	(backtrace_command_1): Use get_current_user_frame.
	(print_frame_local_vars, print_frame_label_vars): Update comments.
	(return_command): Refuse inlined functions.
	* symtab.c (lookup_symbol_aux_local): Stop at inlined function
	boundaries.
	(find_function_start_sal): Avoid inlined functions.
	(completion_list_add_fields): New function.
	(default_make_symbol_completion_list): Use it.  Use block_static_block
	and block_global_block.  Check for inlined functions.
	(skip_prologue_using_sal): Avoid line number comparison across
	inlining.
	* symtab.h (struct symbol): Add is_inlined.
	(SYMBOL_INLINED): New.
	* target.c (target_resume): Call clear_inline_frame_state.
	* valops.c (value_of_variable): Check block_inlined_p.

	gdb/doc/
	* gdb.texinfo (Debugging Optimized Code): New chapter.
	(Compiling for Debugging): Reference it.  Move some
	text to the new section.

	gdb/testsuite/
	* gdb.base/break.exp: Add an XFAIL for gcc/36748.
	* gdb.cp/annota2.exp: Accept frames-invalid in more places.
	* gdb.opt/Makefile.in (EXECUTABLES): Update.
	* gdb.opt/clobbered-registers-O2.exp: Update to GPL v3.
	* gdb.opt/inline-bt.c, gdb.opt/inline-bt.exp,
	gdb.opt/inline-cmds.c, gdb.opt/inline-cmds.exp,
	gdb.opt/inline-locals.c, gdb.opt/inline-locals.exp,
	gdb.opt/inline-markers.c: New files.
	* lib/gdb.exp (skip_inline_frame_tests): New function.
	(skip_inline_var_tests): New function.
This commit is contained in:
Daniel Jacobowitz
2009-06-28 00:20:24 +00:00
parent c7ce8faacb
commit edb3359dff
42 changed files with 2195 additions and 216 deletions

View File

@@ -46,6 +46,7 @@
#include "gdbthread.h"
#include "cp-support.h"
#include "disasm.h"
#include "inline-frame.h"
#include "gdb_assert.h"
#include <ctype.h>
@@ -99,6 +100,30 @@ print_stack_frame_stub (void *args)
return 0;
}
/* Return 1 if we should display the address in addition to the location,
because we are in the middle of a statement. */
static int
frame_show_address (struct frame_info *frame,
struct symtab_and_line sal)
{
/* If there is a line number, but no PC, then there is no location
information associated with this sal. The only way that should
happen is for the call sites of inlined functions (SAL comes from
find_frame_sal). Otherwise, we would have some PC range if the
SAL came from a line table. */
if (sal.line != 0 && sal.pc == 0 && sal.end == 0)
{
if (get_next_frame (frame) == NULL)
gdb_assert (inline_skipped_frames (inferior_ptid) > 0);
else
gdb_assert (get_frame_type (get_next_frame (frame)) == INLINE_FRAME);
return 0;
}
return get_frame_pc (frame) != sal.pc;
}
/* Show or print a stack frame FRAME briefly. The output is format
according to PRINT_LEVEL and PRINT_WHAT printing the frame's
relative level, function name, argument list, and file name and
@@ -565,7 +590,7 @@ print_frame_info (struct frame_info *frame, int print_level,
{
int done = 0;
int mid_statement = ((print_what == SRC_LINE)
&& (get_frame_pc (frame) != sal.pc));
&& frame_show_address (frame, sal));
if (annotation_level)
done = identify_source_line (sal.symtab, sal.line, mid_statement,
@@ -623,7 +648,7 @@ find_frame_funname (struct frame_info *frame, char **funname,
*funname = NULL;
*funlang = language_unknown;
func = find_pc_function (get_frame_address_in_block (frame));
func = get_frame_function (frame);
if (func)
{
/* In certain pathological cases, the symtabs give the wrong
@@ -644,8 +669,13 @@ find_frame_funname (struct frame_info *frame, char **funname,
changed (and we'll create a find_pc_minimal_function or some
such). */
struct minimal_symbol *msymbol =
lookup_minimal_symbol_by_pc (get_frame_address_in_block (frame));
struct minimal_symbol *msymbol = NULL;
/* 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));
if (msymbol != NULL
&& (SYMBOL_VALUE_ADDRESS (msymbol)
@@ -719,7 +749,7 @@ print_frame (struct frame_info *frame, int print_level,
}
get_user_print_options (&opts);
if (opts.addressprint)
if (get_frame_pc (frame) != sal.pc || !sal.symtab
if (frame_show_address (frame, sal) || !sal.symtab
|| print_what == LOC_AND_ADDRESS)
{
annotate_frame_address ();
@@ -1042,8 +1072,10 @@ frame_info (char *addr_exp, int from_tty)
printf_filtered (_(" Outermost frame: %s\n"),
frame_stop_reason_string (reason));
}
if (calling_frame_info)
else if (get_frame_type (fi) == INLINE_FRAME)
printf_filtered (" inlined into frame %d",
frame_relative_level (get_prev_frame (fi)));
else
{
printf_filtered (" called by frame at ");
fputs_filtered (paddress (get_frame_base (calling_frame_info)),
@@ -1503,7 +1535,9 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
if (print_block_frame_locals (block, frame, num_tabs, stream))
values_printed = 1;
/* After handling the function's top-level block, stop. Don't
continue to its superblock, the block of per-file symbols. */
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);
@@ -1574,7 +1608,9 @@ print_frame_label_vars (struct frame_info *frame, int 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. */
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);
@@ -1840,6 +1876,9 @@ return_command (char *retval_exp, int from_tty)
thisfun = get_frame_function (thisframe);
gdbarch = get_frame_arch (thisframe);
if (get_frame_type (get_current_frame ()) == INLINE_FRAME)
error (_("Can not force return from an inlined function."));
/* Compute the return value. If the computation triggers an error,
let it bail. If the return type can't be handled, set
RETURN_VALUE to NULL, and QUERY_PREFIX to an informational