aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2006-06-16 01:12:58 +0000
committerDaniel Jacobowitz <drow@false.org>2006-06-16 01:12:58 +0000
commit14e60db5bc5d53c7f7986e23c9a5bb4a140b341b (patch)
tree59425df05b3c86b5bfb36092bedf02c2188aca6c
parent0981e92139581414a8d601725a2642dfa09bc4dc (diff)
downloadgdb-14e60db5bc5d53c7f7986e23c9a5bb4a140b341b.zip
gdb-14e60db5bc5d53c7f7986e23c9a5bb4a140b341b.tar.gz
gdb-14e60db5bc5d53c7f7986e23c9a5bb4a140b341b.tar.bz2
* infrun.c (insert_step_resume_breakpoint_at_caller): New function,
based on insert_step_resume_breakpoint_at_frame. (handle_inferior_event): Update comments. Use insert_step_resume_breakpoint_at_caller. (insert_step_resume_breakpoint_at_frame): Revise comments.
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/infrun.c69
2 files changed, 59 insertions, 18 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6feb429..d5404f8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2006-06-15 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * infrun.c (insert_step_resume_breakpoint_at_caller): New function,
+ based on insert_step_resume_breakpoint_at_frame.
+ (handle_inferior_event): Update comments. Use
+ insert_step_resume_breakpoint_at_caller.
+ (insert_step_resume_breakpoint_at_frame): Revise comments.
+
2006-06-14 Daniel Jacobowitz <dan@codesourcery.com>
* dwarf2read.c (read_unspecified_type): New function.
diff --git a/gdb/infrun.c b/gdb/infrun.c
index bccca0d..953983f 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -943,6 +943,7 @@ void handle_inferior_event (struct execution_control_state *ecs);
static void step_into_function (struct execution_control_state *ecs);
static void insert_step_resume_breakpoint_at_frame (struct frame_info *step_frame);
+static void insert_step_resume_breakpoint_at_caller (struct frame_info *);
static void insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
struct frame_id sr_id);
static void stop_stepping (struct execution_control_state *ecs);
@@ -2367,9 +2368,13 @@ process_event_stop_test:
return;
}
+ /* Check for subroutine calls.
+
+ NOTE: frame_id_eq will never report two invalid frame IDs as
+ being equal, so to get into this block, both the current and
+ previous frame must have valid frame IDs. */
if (frame_id_eq (frame_unwind_id (get_current_frame ()), step_frame_id))
{
- /* It's a subroutine call. */
CORE_ADDR real_stop_pc;
if (debug_infrun)
@@ -2396,7 +2401,7 @@ process_event_stop_test:
/* We're doing a "next", set a breakpoint at callee's return
address (the address at which the caller will
resume). */
- insert_step_resume_breakpoint_at_frame (get_prev_frame (get_current_frame ()));
+ insert_step_resume_breakpoint_at_caller (get_current_frame ());
keep_going (ecs);
return;
}
@@ -2459,7 +2464,7 @@ process_event_stop_test:
/* Set a breakpoint at callee's return address (the address at
which the caller will resume). */
- insert_step_resume_breakpoint_at_frame (get_prev_frame (get_current_frame ()));
+ insert_step_resume_breakpoint_at_caller (get_current_frame ());
keep_going (ecs);
return;
}
@@ -2513,8 +2518,11 @@ process_event_stop_test:
and no line number corresponding to the address where the
inferior stopped). Since we want to skip this kind of code,
we keep going until the inferior returns from this
- function. */
- if (step_stop_if_no_debug)
+ function - unless the user has asked us not to (via
+ set step-mode) or we no longer know how to get back
+ to the call site. */
+ if (step_stop_if_no_debug
+ || !frame_id_p (frame_unwind_id (get_current_frame ())))
{
/* If we have no line number and the step-stop-if-no-debug
is set, we stop the step so that the user has a chance to
@@ -2528,7 +2536,7 @@ process_event_stop_test:
{
/* Set a breakpoint at callee's return address (the address
at which the caller will resume). */
- insert_step_resume_breakpoint_at_frame (get_prev_frame (get_current_frame ()));
+ insert_step_resume_breakpoint_at_caller (get_current_frame ());
keep_going (ecs);
return;
}
@@ -2735,20 +2743,13 @@ insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
if (breakpoints_inserted)
insert_breakpoints ();
}
-
-/* Insert a "step resume breakpoint" at RETURN_FRAME.pc. This is used
- to skip a function (next, skip-no-debug) or signal. It's assumed
- that the function/signal handler being skipped eventually returns
- to the breakpoint inserted at RETURN_FRAME.pc.
- For the skip-function case, the function may have been reached by
- either single stepping a call / return / signal-return instruction,
- or by hitting a breakpoint. In all cases, the RETURN_FRAME belongs
- to the skip-function's caller.
+/* Insert a "step resume breakpoint" at RETURN_FRAME.pc. This is used
+ to skip a potential signal handler.
- For the signals case, this is called with the interrupted
- function's frame. The signal handler, when it returns, will resume
- the interrupted function at RETURN_FRAME.pc. */
+ This is called with the interrupted function's frame. The signal
+ handler, when it returns, will resume the interrupted function at
+ RETURN_FRAME.pc. */
static void
insert_step_resume_breakpoint_at_frame (struct frame_info *return_frame)
@@ -2763,6 +2764,38 @@ insert_step_resume_breakpoint_at_frame (struct frame_info *return_frame)
insert_step_resume_breakpoint_at_sal (sr_sal, get_frame_id (return_frame));
}
+/* Similar to insert_step_resume_breakpoint_at_frame, except
+ but a breakpoint at the previous frame's PC. This is used to
+ skip a function after stepping into it (for "next" or if the called
+ function has no debugging information).
+
+ The current function has almost always been reached by single
+ stepping a call or return instruction. NEXT_FRAME belongs to the
+ current function, and the breakpoint will be set at the caller's
+ resume address.
+
+ This is a separate function rather than reusing
+ insert_step_resume_breakpoint_at_frame in order to avoid
+ get_prev_frame, which may stop prematurely (see the implementation
+ of frame_unwind_id for an example). */
+
+static void
+insert_step_resume_breakpoint_at_caller (struct frame_info *next_frame)
+{
+ struct symtab_and_line sr_sal;
+
+ /* We shouldn't have gotten here if we don't know where the call site
+ is. */
+ gdb_assert (frame_id_p (frame_unwind_id (next_frame)));
+
+ init_sal (&sr_sal); /* initialize to zeros */
+
+ sr_sal.pc = ADDR_BITS_REMOVE (frame_pc_unwind (next_frame));
+ sr_sal.section = find_pc_overlay (sr_sal.pc);
+
+ insert_step_resume_breakpoint_at_sal (sr_sal, frame_unwind_id (next_frame));
+}
+
static void
stop_stepping (struct execution_control_state *ecs)
{