This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[patch/rfc] Inline handle_step_into_function part # 1of2
- From: Andrew Cagney <cagney at gnu dot org>
- To: gdb-patches at sources dot redhat dot com
- Date: Thu, 13 May 2004 17:48:58 -0400
- Subject: [patch/rfc] Inline handle_step_into_function part # 1of2
Hello,
(fallout from that internal-error)
This is the first of a two-part change to eliminate the function
handle_step_into_function - the goal being to simplify the code to the
point where we can understand it.
This first part just does a mechanical inline.
If you look carefully at the latter half of the diff (I used diff -u13)
you'll see that there is much redundancy. For instance:
if (step_over_calls == STEP_OVER_UNDEBUGGABLE
&& ecs->stop_func_name == NULL)
being a predicate to tests such as:
+ if ((step_over_calls == STEP_OVER_NONE)
+ || ((step_range_end == 1)
+ && in_prologue (prev_pc, ecs->stop_func_start)))
(If the code is undebuggable we're not going to find a prologue) and:
+ if (step_over_calls == STEP_OVER_ALL || IGNORE_HELPER_CALL (stop_pc))
(IGNORE_HELPER_CALL relies on there being a symbol so is always false)
The second part (probably in several parts) will involving eliminating
all that guff.
Andrew
2004-05-13 Andrew Cagney <cagney@redhat.com>
* infrun.c (handle_step_into_function): Delete function.
(handle_inferior_event): Inline calls to
handle_step_into_function.
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.161
diff -p -u -1 -3 -r1.161 infrun.c
--- infrun.c 13 May 2004 19:34:00 -0000 1.161
+++ infrun.c 13 May 2004 21:33:54 -0000
@@ -953,27 +953,26 @@ struct execution_control_state
int stepping_through_solib_after_catch;
bpstat stepping_through_solib_catchpoints;
int enable_hw_watchpoints_after_wait;
int stepping_through_sigtramp;
int new_thread_event;
struct target_waitstatus tmpstatus;
enum infwait_states infwait_state;
ptid_t waiton_ptid;
int wait_some_more;
};
void init_execution_control_state (struct execution_control_state *ecs);
-static void handle_step_into_function (struct execution_control_state *ecs);
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 (struct frame_info *step_frame,
struct execution_control_state *ecs);
static void stop_stepping (struct execution_control_state *ecs);
static void prepare_to_wait (struct execution_control_state *ecs);
static void keep_going (struct execution_control_state *ecs);
static void print_stop_reason (enum inferior_stop_reason stop_reason,
int stop_info);
/* Wait for control to return from inferior to debugger.
If inferior gets a signal, we may decide to start it up again
@@ -1165,106 +1164,26 @@ context_switch (struct execution_control
load_infrun_state (ecs->ptid, &prev_pc,
&trap_expected, &step_resume_breakpoint,
&step_range_start,
&step_range_end, &step_frame_id,
&ecs->handling_longjmp, &ecs->another_trap,
&ecs->stepping_through_solib_after_catch,
&ecs->stepping_through_solib_catchpoints,
&ecs->stepping_through_sigtramp,
&ecs->current_line, &ecs->current_symtab);
}
inferior_ptid = ecs->ptid;
}
-/* Handle the inferior event in the cases when we just stepped
- into a function. */
-
-static void
-handle_step_into_function (struct execution_control_state *ecs)
-{
- CORE_ADDR real_stop_pc;
-
- if ((step_over_calls == STEP_OVER_NONE)
- || ((step_range_end == 1)
- && in_prologue (prev_pc, ecs->stop_func_start)))
- {
- /* I presume that step_over_calls is only 0 when we're
- supposed to be stepping at the assembly language level
- ("stepi"). Just stop. */
- /* Also, maybe we just did a "nexti" inside a prolog,
- so we thought it was a subroutine call but it was not.
- Stop as well. FENN */
- stop_step = 1;
- print_stop_reason (END_STEPPING_RANGE, 0);
- stop_stepping (ecs);
- return;
- }
-
- if (step_over_calls == STEP_OVER_ALL || IGNORE_HELPER_CALL (stop_pc))
- {
- /* 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 (get_prev_frame (get_current_frame ()),
- ecs);
- keep_going (ecs);
- return;
- }
-
- /* If we are in a function call trampoline (a stub between
- the calling routine and the real function), locate the real
- function. That's what tells us (a) whether we want to step
- into it at all, and (b) what prologue we want to run to
- the end of, if we do step into it. */
- real_stop_pc = skip_language_trampoline (stop_pc);
- if (real_stop_pc == 0)
- real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc);
- if (real_stop_pc != 0)
- ecs->stop_func_start = real_stop_pc;
-
- /* If we have line number information for the function we
- are thinking of stepping into, step into it.
-
- If there are several symtabs at that PC (e.g. with include
- files), just want to know whether *any* of them have line
- numbers. find_pc_line handles this. */
- {
- struct symtab_and_line tmp_sal;
-
- tmp_sal = find_pc_line (ecs->stop_func_start, 0);
- if (tmp_sal.line != 0)
- {
- step_into_function (ecs);
- return;
- }
- }
-
- /* 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
- switch in assembly mode. */
- if (step_over_calls == STEP_OVER_UNDEBUGGABLE && step_stop_if_no_debug)
- {
- stop_step = 1;
- print_stop_reason (END_STEPPING_RANGE, 0);
- stop_stepping (ecs);
- return;
- }
-
- /* Set a breakpoint at callee's return address (the address at which
- the caller will resume). */
- insert_step_resume_breakpoint (get_prev_frame (get_current_frame ()), ecs);
- keep_going (ecs);
- return;
-}
-
static void
adjust_pc_after_break (struct execution_control_state *ecs)
{
CORE_ADDR breakpoint_pc;
/* If this target does not decrement the PC after breakpoints, then
we have nothing to do. */
if (DECR_PC_AFTER_BREAK == 0)
return;
/* If we've hit a breakpoint, we'll normally be stopped with SIGTRAP. If
we aren't, just return.
@@ -2427,35 +2346,177 @@ process_event_stop_test:
if (step_over_calls == STEP_OVER_UNDEBUGGABLE
&& ecs->stop_func_name == NULL)
{
/* The inferior just stepped into, or returned to, an
undebuggable function (where there is no symbol, not even a
minimal symbol, 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. */
/* NOTE: cagney/2004-05-12: This test is performed after the
sigtramp test as often sigtramps, while recognized by GDB,
have no symbol information. */
- handle_step_into_function (ecs);
+ CORE_ADDR real_stop_pc;
+
+ if ((step_over_calls == STEP_OVER_NONE)
+ || ((step_range_end == 1)
+ && in_prologue (prev_pc, ecs->stop_func_start)))
+ {
+ /* I presume that step_over_calls is only 0 when we're
+ supposed to be stepping at the assembly language level
+ ("stepi"). Just stop. */
+ /* Also, maybe we just did a "nexti" inside a prolog, so we
+ thought it was a subroutine call but it was not. Stop as
+ well. FENN */
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
+ }
+
+ if (step_over_calls == STEP_OVER_ALL || IGNORE_HELPER_CALL (stop_pc))
+ {
+ /* 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 (get_prev_frame (get_current_frame ()),
+ ecs);
+ keep_going (ecs);
+ return;
+ }
+
+ /* If we are in a function call trampoline (a stub between the
+ calling routine and the real function), locate the real
+ function. That's what tells us (a) whether we want to step
+ into it at all, and (b) what prologue we want to run to the
+ end of, if we do step into it. */
+ real_stop_pc = skip_language_trampoline (stop_pc);
+ if (real_stop_pc == 0)
+ real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc);
+ if (real_stop_pc != 0)
+ ecs->stop_func_start = real_stop_pc;
+
+ /* If we have line number information for the function we are
+ thinking of stepping into, step into it.
+
+ If there are several symtabs at that PC (e.g. with include
+ files), just want to know whether *any* of them have line
+ numbers. find_pc_line handles this. */
+ {
+ struct symtab_and_line tmp_sal;
+
+ tmp_sal = find_pc_line (ecs->stop_func_start, 0);
+ if (tmp_sal.line != 0)
+ {
+ step_into_function (ecs);
+ return;
+ }
+ }
+
+ /* 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 switch
+ in assembly mode. */
+ if (step_over_calls == STEP_OVER_UNDEBUGGABLE && step_stop_if_no_debug)
+ {
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
+ }
+
+ /* Set a breakpoint at callee's return address (the address at
+ which the caller will resume). */
+ insert_step_resume_breakpoint (get_prev_frame (get_current_frame ()), ecs);
+ keep_going (ecs);
return;
}
if (frame_id_eq (frame_unwind_id (get_current_frame ()),
step_frame_id))
{
/* It's a subroutine call. */
- handle_step_into_function (ecs);
+ CORE_ADDR real_stop_pc;
+
+ if ((step_over_calls == STEP_OVER_NONE)
+ || ((step_range_end == 1)
+ && in_prologue (prev_pc, ecs->stop_func_start)))
+ {
+ /* I presume that step_over_calls is only 0 when we're
+ supposed to be stepping at the assembly language level
+ ("stepi"). Just stop. */
+ /* Also, maybe we just did a "nexti" inside a prolog, so we
+ thought it was a subroutine call but it was not. Stop as
+ well. FENN */
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
+ }
+
+ if (step_over_calls == STEP_OVER_ALL || IGNORE_HELPER_CALL (stop_pc))
+ {
+ /* 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 (get_prev_frame (get_current_frame ()),
+ ecs);
+ keep_going (ecs);
+ return;
+ }
+
+ /* If we are in a function call trampoline (a stub between the
+ calling routine and the real function), locate the real
+ function. That's what tells us (a) whether we want to step
+ into it at all, and (b) what prologue we want to run to the
+ end of, if we do step into it. */
+ real_stop_pc = skip_language_trampoline (stop_pc);
+ if (real_stop_pc == 0)
+ real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc);
+ if (real_stop_pc != 0)
+ ecs->stop_func_start = real_stop_pc;
+
+ /* If we have line number information for the function we are
+ thinking of stepping into, step into it.
+
+ If there are several symtabs at that PC (e.g. with include
+ files), just want to know whether *any* of them have line
+ numbers. find_pc_line handles this. */
+ {
+ struct symtab_and_line tmp_sal;
+
+ tmp_sal = find_pc_line (ecs->stop_func_start, 0);
+ if (tmp_sal.line != 0)
+ {
+ step_into_function (ecs);
+ return;
+ }
+ }
+
+ /* 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 switch
+ in assembly mode. */
+ if (step_over_calls == STEP_OVER_UNDEBUGGABLE && step_stop_if_no_debug)
+ {
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
+ }
+
+ /* Set a breakpoint at callee's return address (the address at
+ which the caller will resume). */
+ insert_step_resume_breakpoint (get_prev_frame (get_current_frame ()), ecs);
+ keep_going (ecs);
return;
}
/* We've wandered out of the step range. */
ecs->sal = find_pc_line (stop_pc, 0);
if (step_range_end == 1)
{
/* It is stepi or nexti. We always want to stop stepping after
one instruction. */
stop_step = 1;
print_stop_reason (END_STEPPING_RANGE, 0);