From fe6750385724b6c284c2dbb5af73f5d6868794e0 Mon Sep 17 00:00:00 2001 From: Jim Kingdon Date: Sun, 11 Jul 1993 04:52:50 +0000 Subject: [PATCH] * infrun.c: Remove step_resume_{duplicate,shadow}. Replace step_resume_break_address with step_resume_breakpoint (now local to wait_for_inferior). ({insert,remove}_step_breakpoint): Remove. (wait_for_inferior): Set step resume break with set_momentary_breakpoint. Test hitting it with bpstat_stop_status and bpstat_what (stop_step_resume_break removed). * breakpoint.{h,c}, infrun.c: Return value from bpstat_what now struct which includes previous return value as main_action, and a step_resume bit. * breakpoint.c (delete_breakpoint): If breakpoint was inserted, and there is another breakpoint there, insert it. * infrun.c (wait_for_inferior): Rearrange the spaghetti a bit. Use a few more gotos. Various: Clean up and add comments. --- gdb/ChangeLog | 16 ++ gdb/breakpoint.c | 87 +++++-- gdb/infcmd.c | 7 +- gdb/infrun.c | 709 ++++++++++++++++++++++++++----------------------------- 4 files changed, 423 insertions(+), 396 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a124234..6fe11ea 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,21 @@ Sat Jul 10 09:54:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com) + * infrun.c: Remove step_resume_{duplicate,shadow}. Replace + step_resume_break_address with step_resume_breakpoint (now local + to wait_for_inferior). + ({insert,remove}_step_breakpoint): Remove. + (wait_for_inferior): Set step resume break with + set_momentary_breakpoint. Test hitting it with bpstat_stop_status + and bpstat_what (stop_step_resume_break removed). + * breakpoint.{h,c}, infrun.c: Return value from bpstat_what now struct + which includes previous return value as main_action, and a step_resume + bit. + * breakpoint.c (delete_breakpoint): If breakpoint was inserted, and + there is another breakpoint there, insert it. + * infrun.c (wait_for_inferior): Rearrange the spaghetti a bit. Use + a few more gotos. + Various: Clean up and add comments. + * infrun.c [TDESC]: Remove remaining tdesc code (see ChangeLog for Wed Nov 13 16:45:13 1991). diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index e495a08..8ef00b7 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -815,7 +815,7 @@ bpstat_alloc (b, cbs) still on the stack, I guess this needs to be machine-specific (e.g. a29k) but I think - read_register (FP_REGNUM) INNER_THAN watchpoint_frame->frame + read_fp () INNER_THAN watchpoint_frame->frame would generally work. @@ -824,7 +824,7 @@ bpstat_alloc (b, cbs) watchpoint is relative to (another machine-specific thing, usually FRAMELESS_FUNCTION_INVOCATION (get_current_frame(), fromleaf) - read_register (FP_REGNUM) == wp_frame->frame + read_fp () == wp_frame->frame && !fromleaf ), *then* it could do a @@ -918,7 +918,7 @@ within_scope (valid_block) /* Check watchpoint condition. */ static int watchpoint_check (p) - PTR p; + char *p; { bpstat bs = (bpstat) p; FRAME fr; @@ -1058,7 +1058,8 @@ bpstat_stop_status (pc, frame_address) "Error evaluating expression for watchpoint %d\n"; char message[sizeof (message1) + 30 /* slop */]; sprintf (message, message1, b->number); - switch (catch_errors (watchpoint_check, (char *) bs, message)) + switch (catch_errors (watchpoint_check, (char *) bs, message, + RETURN_MASK_ALL)) { case WP_DISABLED: /* We've already printed what needs to be printed. */ @@ -1104,7 +1105,8 @@ bpstat_stop_status (pc, frame_address) select_frame (get_current_frame (), 0); value_is_zero = catch_errors (breakpoint_cond_eval, (char *)(b->cond), - "Error in testing breakpoint condition:\n"); + "Error in testing breakpoint condition:\n", + RETURN_MASK_ALL); /* FIXME-someday, should give breakpoint # */ free_all_values (); } @@ -1165,14 +1167,14 @@ bpstat_stop_status (pc, frame_address) } /* Tell what to do about this bpstat. */ -enum bpstat_what +struct bpstat_what bpstat_what (bs) bpstat bs; { /* Classify each bpstat as one of the following. */ enum class { - /* There was a watchpoint, but we're not stopping. */ - wp_nostop = 0, + /* This bpstat element has no effect on the main_action. */ + no_effect = 0, /* There was a watchpoint, stop but don't print. */ wp_silent, @@ -1215,13 +1217,13 @@ bpstat_what (bs) #define err BPSTAT_WHAT_STOP_NOISY /* Given an old action and a class, come up with a new action. */ - static const enum bpstat_what + static const enum bpstat_what_main_action table[(int)class_last][(int)BPSTAT_WHAT_LAST] = { /* old action */ /* keep_c stop_s stop_n single setlr clrlr clrlrs */ -/*wp_nostop*/ {keep_c, stop_s, stop_n, single, setlr , clrlr , clrlrs}, +/*no_effect*/ {keep_c, stop_s, stop_n, single, setlr , clrlr , clrlrs}, /*wp_silent*/ {stop_s, stop_s, stop_n, stop_s, stop_s, stop_s, stop_s}, /*wp_noisy*/ {stop_n, stop_n, stop_n, stop_n, stop_n, stop_n, stop_n}, /*bp_nostop*/ {single, stop_s, stop_n, single, setlr , clrlrs, clrlrs}, @@ -1238,7 +1240,8 @@ bpstat_what (bs) #undef clrlr #undef clrlrs #undef err - enum bpstat_what current_action = BPSTAT_WHAT_KEEP_CHECKING; + enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING; + int found_step_resume = 0; for (; bs != NULL; bs = bs->next) { @@ -1271,7 +1274,9 @@ bpstat_what (bs) bs_class = wp_silent; } else - bs_class = wp_nostop; + /* There was a watchpoint, but we're not stopping. This requires + no further action. */ + bs_class = no_effect; break; case bp_longjmp: bs_class = long_jump; @@ -1279,10 +1284,34 @@ bpstat_what (bs) case bp_longjmp_resume: bs_class = long_resume; break; + case bp_step_resume: +#if 0 + /* Need to temporarily disable this until we can fix the bug + with nexting over a breakpoint with ->stop clear causing + an infinite loop. For now, treat the breakpoint as having + been hit even if the frame is wrong. */ + if (bs->stop) + { +#endif + found_step_resume = 1; + /* We don't handle this via the main_action. */ + bs_class = no_effect; +#if 0 + } + else + /* It is for the wrong frame. */ + bs_class = bp_nostop; +#endif + break; } current_action = table[(int)bs_class][(int)current_action]; } - return current_action; + { + struct bpstat_what retval; + retval.main_action = current_action; + retval.step_resume = found_step_resume; + return retval; + } } /* Nonzero if we should step constantly (e.g. watchpoints on machines @@ -2251,7 +2280,7 @@ catch_command_1 (arg, tempflag, from_tty) else { /* Grab selected catch clauses. */ - error ("catch NAME not implemeneted"); + error ("catch NAME not implemented"); #if 0 /* This isn't used; I don't know what it was for. */ sals = map_catch_names (arg, catch_breakpoint); @@ -2444,7 +2473,7 @@ delete_breakpoint (bpt) register bpstat bs; if (bpt->inserted) - target_remove_breakpoint(bpt->address, bpt->shadow_contents); + target_remove_breakpoint(bpt->address, bpt->shadow_contents); if (breakpoint_chain == bpt) breakpoint_chain = bpt->next; @@ -2457,6 +2486,24 @@ delete_breakpoint (bpt) } check_duplicates (bpt->address); + /* If this breakpoint was inserted, and there is another breakpoint + at the same address, we need to insert the other breakpoint. */ + if (bpt->inserted) + { + ALL_BREAKPOINTS (b) + if (b->address == bpt->address && !b->duplicate) + { + int val; + val = target_insert_breakpoint (b->address, b->shadow_contents); + if (val != 0) + { + fprintf (stderr, "Cannot insert breakpoint %d:\n", b->number); + memory_error (val, b->address); /* which bombs us out */ + } + else + b->inserted = 1; + } + } free_command_lines (&bpt->commands); if (bpt->cond) @@ -2606,17 +2653,11 @@ breakpoint_re_set () static char message1[] = "Error in re-setting breakpoint %d:\n"; char message[sizeof (message1) + 30 /* slop */]; - /* If we have no current source symtab, and we have any breakpoints, - go through the work of making a source context. */ - if (current_source_symtab == NULL && breakpoint_chain != 0) - { - select_source_symtab (NULL); - } - ALL_BREAKPOINTS_SAFE (b, temp) { sprintf (message, message1, b->number); /* Format possible error msg */ - catch_errors (breakpoint_re_set_one, (char *) b, message); + catch_errors (breakpoint_re_set_one, (char *) b, message, + RETURN_MASK_ALL); } create_longjmp_breakpoint("longjmp"); diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 4aaa791..77015a1 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -399,11 +399,12 @@ step_1 (skip_subroutines, single_inst, count_string) } else { - /* Say we are stepping, but stop after one insn whatever it does. - Don't step through subroutine calls even to undebuggable - functions. */ + /* Say we are stepping, but stop after one insn whatever it does. */ step_range_start = step_range_end = 1; if (!skip_subroutines) + /* It is stepi. + Don't step over function calls, not even to functions lacking + line numbers. */ step_over_calls = 0; } diff --git a/gdb/infrun.c b/gdb/infrun.c index 58e3aee..30dfd72 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -138,12 +138,6 @@ static void sig_print_header PARAMS ((void)); static void -remove_step_breakpoint PARAMS ((void)); - -static void -insert_step_breakpoint PARAMS ((void)); - -static void resume_cleanups PARAMS ((int)); static int @@ -216,19 +210,6 @@ static int breakpoints_inserted; static struct symbol *step_start_function; -/* Nonzero => address for special breakpoint for resuming stepping. */ - -static CORE_ADDR step_resume_break_address; - -/* Pointer to orig contents of the byte where the special breakpoint is. */ - -static char step_resume_break_shadow[BREAKPOINT_MAX]; - -/* Nonzero means the special breakpoint is a duplicate - so it has not itself been inserted. */ - -static int step_resume_break_duplicate; - /* Nonzero if we are expecting a trace trap and should proceed from it. */ static int trap_expected; @@ -335,7 +316,6 @@ clear_proceed_status () step_range_end = 0; step_frame_address = 0; step_over_calls = -1; - step_resume_break_address = 0; stop_after_trap = 0; stop_soon_quietly = 0; proceed_to_finish = 0; @@ -468,7 +448,14 @@ init_wait_for_inferior () stop_signal = 0; /* Don't confuse first call to proceed(). */ } - +static void +delete_breakpoint_current_contents (arg) + PTR arg; +{ + struct breakpoint **breakpointp = (struct breakpoint **)arg; + if (*breakpointp != NULL) + delete_breakpoint (*breakpointp); +} /* Wait for control to return from inferior to debugger. If inferior gets a signal, we may decide to start it up again @@ -479,6 +466,7 @@ init_wait_for_inferior () void wait_for_inferior () { + struct cleanup *old_cleanups; WAITTYPE w; int another_trap; int random_signal; @@ -486,13 +474,15 @@ wait_for_inferior () CORE_ADDR stop_func_start; char *stop_func_name; CORE_ADDR prologue_pc, tmp; - int stop_step_resume_break; struct symtab_and_line sal; int remove_breakpoints_on_following_step = 0; int current_line; int handling_longjmp = 0; /* FIXME */ struct symtab *symtab; + struct breakpoint *step_resume_breakpoint = NULL; + old_cleanups = make_cleanup (delete_breakpoint_current_contents, + &step_resume_breakpoint); sal = find_pc_line(prev_pc, 0); current_line = sal.line; @@ -577,7 +567,7 @@ wait_for_inferior () stop_pc = read_pc (); set_current_frame ( create_new_frame (read_fp (), read_pc ())); - + stop_frame_address = FRAME_FP (get_current_frame ()); stop_sp = read_sp (); stop_func_start = 0; @@ -591,7 +581,6 @@ wait_for_inferior () stop_step = 0; stop_stack_dummy = 0; stop_print_frame = 1; - stop_step_resume_break = 0; random_signal = 0; stopped_by_random_signal = 0; breakpoints_failed = 0; @@ -634,11 +623,11 @@ wait_for_inferior () if just proceeded over a breakpoint. However, if we are trying to proceed over a breakpoint - and end up in sigtramp, then step_resume_break_address + and end up in sigtramp, then step_resume_breakpoint will be set and we should check whether we've hit the step breakpoint. */ if (stop_signal == SIGTRAP && trap_expected - && step_resume_break_address == 0) + && step_resume_breakpoint == NULL) bpstat_clear (&stop_bpstat); else { @@ -652,47 +641,28 @@ wait_for_inferior () the address of the breakpoint before the current pc. */ if (prev_pc == stop_pc - DECR_PC_AFTER_BREAK || !step_range_end - || step_resume_break_address + || step_resume_breakpoint != NULL || handling_longjmp /* FIXME */) #endif /* DECR_PC_AFTER_BREAK not zero */ { - /* See if we stopped at the special breakpoint for - stepping over a subroutine call. If both are zero, - this wasn't the reason for the stop. */ - if (step_resume_break_address - && stop_pc - DECR_PC_AFTER_BREAK - == step_resume_break_address) - { - stop_step_resume_break = 1; - if (DECR_PC_AFTER_BREAK) - { - stop_pc -= DECR_PC_AFTER_BREAK; - write_pc (stop_pc); - } - } - else - { - stop_bpstat = - bpstat_stop_status (&stop_pc, stop_frame_address); - /* Following in case break condition called a - function. */ - stop_print_frame = 1; - } + stop_bpstat = + bpstat_stop_status (&stop_pc, stop_frame_address); + /* Following in case break condition called a + function. */ + stop_print_frame = 1; } } - + if (stop_signal == SIGTRAP) random_signal = !(bpstat_explains_signal (stop_bpstat) || trap_expected - || stop_step_resume_break || PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address) - || (step_range_end && !step_resume_break_address)); + || (step_range_end && step_resume_breakpoint == NULL)); else { random_signal = !(bpstat_explains_signal (stop_bpstat) - || stop_step_resume_break /* End of a stack dummy. Some systems (e.g. Sony news) give another signal besides SIGTRAP, so check here as well as above. */ @@ -704,10 +674,10 @@ wait_for_inferior () } else random_signal = 1; - + /* For the program's own signals, act according to the signal handling tables. */ - + if (random_signal) { /* Signal not for debugging purposes. */ @@ -747,132 +717,103 @@ wait_for_inferior () if (signal_program[stop_signal] == 0) stop_signal = 0; - /* Note that virtually all the code below does `if !random_signal'. - Perhaps this code should end with a goto or continue. At least - one (now fixed) bug was caused by this -- a !random_signal was - missing in one of the tests below. */ + /* I'm not sure whether this needs to be check_sigtramp2 or + whether it could/should be keep_going. */ + goto check_sigtramp2; } /* Handle cases caused by hitting a breakpoint. */ + { + CORE_ADDR jmp_buf_pc; + struct bpstat_what what = bpstat_what (stop_bpstat); - if (!random_signal) - { - CORE_ADDR jmp_buf_pc; - enum bpstat_what what = bpstat_what (stop_bpstat); - - switch (what) - { - case BPSTAT_WHAT_SET_LONGJMP_RESUME: - /* If we hit the breakpoint at longjmp, disable it for the - duration of this command. Then, install a temporary - breakpoint at the target of the jmp_buf. */ - disable_longjmp_breakpoint(); - remove_breakpoints (); - breakpoints_inserted = 0; - if (!GET_LONGJMP_TARGET(&jmp_buf_pc)) goto keep_going; - - /* Need to blow away step-resume breakpoint, as it - interferes with us */ - remove_step_breakpoint (); - step_resume_break_address = 0; - stop_step_resume_break = 0; + switch (what.main_action) + { + case BPSTAT_WHAT_SET_LONGJMP_RESUME: + /* If we hit the breakpoint at longjmp, disable it for the + duration of this command. Then, install a temporary + breakpoint at the target of the jmp_buf. */ + disable_longjmp_breakpoint(); + remove_breakpoints (); + breakpoints_inserted = 0; + if (!GET_LONGJMP_TARGET(&jmp_buf_pc)) goto keep_going; + + /* Need to blow away step-resume breakpoint, as it + interferes with us */ + if (step_resume_breakpoint != NULL) + { + delete_breakpoint (step_resume_breakpoint); + step_resume_breakpoint = NULL; + what.step_resume = 0; + } #if 0 - /* FIXME - Need to implement nested temporary breakpoints */ - if (step_over_calls > 0) - set_longjmp_resume_breakpoint(jmp_buf_pc, - get_current_frame()); - else + /* FIXME - Need to implement nested temporary breakpoints */ + if (step_over_calls > 0) + set_longjmp_resume_breakpoint(jmp_buf_pc, + get_current_frame()); + else #endif /* 0 */ - set_longjmp_resume_breakpoint(jmp_buf_pc, NULL); - handling_longjmp = 1; /* FIXME */ - goto keep_going; - - case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME: - case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE: - remove_breakpoints (); - breakpoints_inserted = 0; + set_longjmp_resume_breakpoint(jmp_buf_pc, NULL); + handling_longjmp = 1; /* FIXME */ + goto keep_going; + + case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME: + case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE: + remove_breakpoints (); + breakpoints_inserted = 0; #if 0 - /* FIXME - Need to implement nested temporary breakpoints */ - if (step_over_calls - && (stop_frame_address - INNER_THAN step_frame_address)) - { - another_trap = 1; - goto keep_going; - } + /* FIXME - Need to implement nested temporary breakpoints */ + if (step_over_calls + && (stop_frame_address + INNER_THAN step_frame_address)) + { + another_trap = 1; + goto keep_going; + } #endif /* 0 */ - disable_longjmp_breakpoint(); - handling_longjmp = 0; /* FIXME */ - if (what == BPSTAT_WHAT_CLEAR_LONGJMP_RESUME) - break; - /* else fallthrough */ - - case BPSTAT_WHAT_SINGLE: - if (breakpoints_inserted) - remove_breakpoints (); - remove_step_breakpoint (); - breakpoints_inserted = 0; - another_trap = 1; - /* Still need to check other stuff, at least the case - where we are stepping and step out of the right range. */ - break; - - case BPSTAT_WHAT_STOP_NOISY: - stop_print_frame = 1; - goto stop_stepping; - - case BPSTAT_WHAT_STOP_SILENT: - stop_print_frame = 0; - goto stop_stepping; - - case BPSTAT_WHAT_KEEP_CHECKING: + disable_longjmp_breakpoint(); + handling_longjmp = 0; /* FIXME */ + if (what.main_action == BPSTAT_WHAT_CLEAR_LONGJMP_RESUME) break; - } + /* else fallthrough */ + + case BPSTAT_WHAT_SINGLE: + if (breakpoints_inserted) + remove_breakpoints (); + breakpoints_inserted = 0; + another_trap = 1; + /* Still need to check other stuff, at least the case + where we are stepping and step out of the right range. */ + break; + + case BPSTAT_WHAT_STOP_NOISY: + stop_print_frame = 1; + /* We are about to nuke the step_resume_breakpoint via the + cleanup chain, so no need to worry about it here. */ + goto stop_stepping; - if (stop_step_resume_break) + case BPSTAT_WHAT_STOP_SILENT: + stop_print_frame = 0; + /* We are about to nuke the step_resume_breakpoint via the + cleanup chain, so no need to worry about it here. */ + goto stop_stepping; + + case BPSTAT_WHAT_KEEP_CHECKING: + break; + } + + if (what.step_resume) { - /* But if we have hit the step-resumption breakpoint, - remove it. It has done its job getting us here. - The sp test is to make sure that we don't get hung - up in recursive calls in functions without frame - pointers. If the stack pointer isn't outside of - where the breakpoint was set (within a routine to be - stepped over), we're in the middle of a recursive - call. Not true for reg window machines (sparc) - because the must change frames to call things and - the stack pointer doesn't have to change if it - the bp was set in a routine without a frame (pc can - be stored in some other window). - - The removal of the sp test is to allow calls to - alloca. Nasty things were happening. Oh, well, - gdb can only handle one level deep of lack of - frame pointer. */ - - /* - Disable test for step_frame_address match so that we always stop even if the - frames don't match. Reason: if we hit the step_resume_breakpoint, there is - no way to temporarily disable it so that we can step past it. If we leave - the breakpoint in, then we loop forever repeatedly hitting, but never - getting past the breakpoint. This change keeps nexting over recursive - function calls from hanging gdb. - */ -#if 0 - if (* step_frame_address == 0 - || (step_frame_address == stop_frame_address)) -#endif - { - remove_step_breakpoint (); - step_resume_break_address = 0; + delete_breakpoint (step_resume_breakpoint); + step_resume_breakpoint = NULL; - /* If were waiting for a trap, hitting the step_resume_break - doesn't count as getting it. */ - if (trap_expected) - another_trap = 1; - } + /* If were waiting for a trap, hitting the step_resume_break + doesn't count as getting it. */ + if (trap_expected) + another_trap = 1; } - } + } /* We come here if we hit a breakpoint but should not stop for it. Possibly we also were stepping @@ -882,8 +823,7 @@ wait_for_inferior () /* If this is the breakpoint at the end of a stack dummy, just stop silently. */ - if (!random_signal - && PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)) + if (PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)) { stop_print_frame = 0; stop_stack_dummy = 1; @@ -893,194 +833,241 @@ wait_for_inferior () break; } - if (step_resume_break_address) + if (step_resume_breakpoint) /* Having a step-resume breakpoint overrides anything else having to do with stepping commands until that breakpoint is reached. */ - ; + /* I suspect this could/should be keep_going, because if the + check_sigtramp2 check succeeds, then it will put in another + step_resume_breakpoint, and we aren't (yet) prepared to nest + them. */ + goto check_sigtramp2; + + if (step_range_end == 0) + /* Likewise if we aren't even stepping. */ + /* I'm not sure whether this needs to be check_sigtramp2 or + whether it could/should be keep_going. */ + goto check_sigtramp2; + /* If stepping through a line, keep going if still within it. */ - else if (!random_signal - && step_range_end - && stop_pc >= step_range_start - && stop_pc < step_range_end - /* The step range might include the start of the - function, so if we are at the start of the - step range and either the stack or frame pointers - just changed, we've stepped outside */ - && !(stop_pc == step_range_start - && stop_frame_address - && (stop_sp INNER_THAN prev_sp - || stop_frame_address != step_frame_address))) + if (stop_pc >= step_range_start + && stop_pc < step_range_end + /* The step range might include the start of the + function, so if we are at the start of the + step range and either the stack or frame pointers + just changed, we've stepped outside */ + && !(stop_pc == step_range_start + && stop_frame_address + && (stop_sp INNER_THAN prev_sp + || stop_frame_address != step_frame_address))) { - ; + /* We might be doing a BPSTAT_WHAT_SINGLE and getting a signal. + So definately need to check for sigtramp here. */ + goto check_sigtramp2; } - + /* We stepped out of the stepping range. See if that was due to a subroutine call that we should proceed to the end of. */ - else if (!random_signal && step_range_end) + + /* Did we just take a signal? */ + if (IN_SIGTRAMP (stop_pc, stop_func_name) + && !IN_SIGTRAMP (prev_pc, prev_func_name)) { - /* Did we just take a signal? */ - if (IN_SIGTRAMP (stop_pc, stop_func_name) - && !IN_SIGTRAMP (prev_pc, prev_func_name)) - { - /* This code is needed at least in the following case: - The user types "next" and then a signal arrives (before - the "next" is done). */ - /* We've just taken a signal; go until we are back to - the point where we took it and one more. */ - step_resume_break_address = prev_pc; - step_resume_break_duplicate = - breakpoint_here_p (step_resume_break_address); - if (breakpoints_inserted) - insert_step_breakpoint (); - /* Make sure that the stepping range gets us past - that instruction. */ - if (step_range_end == 1) - step_range_end = (step_range_start = prev_pc) + 1; - remove_breakpoints_on_following_step = 1; - goto save_pc; - } + /* This code is needed at least in the following case: + The user types "next" and then a signal arrives (before + the "next" is done). */ + /* We've just taken a signal; go until we are back to + the point where we took it and one more. */ + { + struct symtab_and_line sr_sal; + + sr_sal.pc = prev_pc; + sr_sal.symtab = NULL; + sr_sal.line = 0; + step_resume_breakpoint = + set_momentary_breakpoint (sr_sal, get_current_frame (), + bp_step_resume); + if (breakpoints_inserted) + insert_breakpoints (); + } - if (stop_func_start) - { - /* Do this after the IN_SIGTRAMP check; it might give - an error. */ - prologue_pc = stop_func_start; - SKIP_PROLOGUE (prologue_pc); - } + /* If this is stepi or nexti, make sure that the stepping range + gets us past that instruction. */ + if (step_range_end == 1) + /* FIXME: Does this run afoul of the code below which, if + we step into the middle of a line, resets the stepping + range? */ + step_range_end = (step_range_start = prev_pc) + 1; - /* ==> See comments at top of file on this algorithm. <==*/ - - if ((stop_pc == stop_func_start - || IN_SOLIB_TRAMPOLINE (stop_pc, stop_func_name)) - && (stop_func_start != prev_func_start - || prologue_pc != stop_func_start - || stop_sp != prev_sp)) - { - /* It's a subroutine call. - (0) If we are not stepping over any calls ("stepi"), we - just stop. - (1) If we're doing a "next", we want to continue through - the call ("step over the call"). - (2) If we are in a function-call trampoline (a stub between - the calling routine and the real function), locate - the real function and change stop_func_start. - (3) If we're doing a "step", and there are no debug symbols - at the target of the call, we want to continue through - it ("step over the call"). - (4) Otherwise, we want to stop soon, after the function - prologue ("step into the call"). */ - - if (step_over_calls == 0) - { - /* I presume that step_over_calls is only 0 when we're - supposed to be stepping at the assembly language level. */ - stop_step = 1; - break; - } + remove_breakpoints_on_following_step = 1; + goto keep_going; + } - if (step_over_calls > 0) - goto step_over_function; + if (stop_func_start) + { + /* Do this after the IN_SIGTRAMP check; it might give + an error. */ + prologue_pc = stop_func_start; + SKIP_PROLOGUE (prologue_pc); + } - tmp = SKIP_TRAMPOLINE_CODE (stop_pc); - if (tmp != 0) - stop_func_start = tmp; + /* ==> See comments at top of file on this algorithm. <==*/ - /* If we have line number information for the function we - are thinking of stepping into, step into it. + if ((stop_pc == stop_func_start + || IN_SOLIB_TRAMPOLINE (stop_pc, stop_func_name)) + && (stop_func_start != prev_func_start + || prologue_pc != stop_func_start + || stop_sp != prev_sp)) + { + /* It's a subroutine call. */ - 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; + if (step_over_calls == 0) + { + /* I presume that step_over_calls is only 0 when we're + supposed to be stepping at the assembly language level + ("stepi"). Just stop. */ + stop_step = 1; + break; + } - tmp_sal = find_pc_line (stop_func_start, 0); - if (tmp_sal.line != 0) - goto step_into_function; - } + if (step_over_calls > 0) + /* We're doing a "next". */ + goto step_over_function; + + /* 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. */ + tmp = SKIP_TRAMPOLINE_CODE (stop_pc); + if (tmp != 0) + stop_func_start = tmp; + + /* 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 (stop_func_start, 0); + if (tmp_sal.line != 0) + goto step_into_function; + } step_over_function: - /* A subroutine call has happened. */ - /* Set a special breakpoint after the return */ - step_resume_break_address = - ADDR_BITS_REMOVE - (SAVED_PC_AFTER_CALL (get_current_frame ())); - step_resume_break_duplicate - = breakpoint_here_p (step_resume_break_address); - if (breakpoints_inserted) - insert_step_breakpoint (); - goto save_pc; + /* A subroutine call has happened. */ + { + /* Set a special breakpoint after the return */ + struct symtab_and_line sr_sal; + sr_sal.pc = + ADDR_BITS_REMOVE + (SAVED_PC_AFTER_CALL (get_current_frame ())); + sr_sal.symtab = NULL; + sr_sal.line = 0; + step_resume_breakpoint = + set_momentary_breakpoint (sr_sal, get_current_frame (), + bp_step_resume); + if (breakpoints_inserted) + insert_breakpoints (); + } + goto keep_going; step_into_function: - /* Subroutine call with source code we should not step over. - Do step to the first line of code in it. */ - SKIP_PROLOGUE (stop_func_start); - sal = find_pc_line (stop_func_start, 0); - /* Use the step_resume_break to step until - the end of the prologue, even if that involves jumps - (as it seems to on the vax under 4.2). */ - /* If the prologue ends in the middle of a source line, - continue to the end of that source line. - Otherwise, just go to end of prologue. */ + /* Subroutine call with source code we should not step over. + Do step to the first line of code in it. */ + SKIP_PROLOGUE (stop_func_start); + sal = find_pc_line (stop_func_start, 0); + /* Use the step_resume_break to step until + the end of the prologue, even if that involves jumps + (as it seems to on the vax under 4.2). */ + /* If the prologue ends in the middle of a source line, + continue to the end of that source line. + Otherwise, just go to end of prologue. */ #ifdef PROLOGUE_FIRSTLINE_OVERLAP - /* no, don't either. It skips any code that's - legitimately on the first line. */ + /* no, don't either. It skips any code that's + legitimately on the first line. */ #else - if (sal.end && sal.pc != stop_func_start) - stop_func_start = sal.end; + if (sal.end && sal.pc != stop_func_start) + stop_func_start = sal.end; #endif - if (stop_func_start == stop_pc) - { - /* We are already there: stop now. */ - stop_step = 1; - break; - } - else - /* Put the step-breakpoint there and go until there. */ - { - step_resume_break_address = stop_func_start; - - step_resume_break_duplicate - = breakpoint_here_p (step_resume_break_address); - if (breakpoints_inserted) - insert_step_breakpoint (); - /* Do not specify what the fp should be when we stop - since on some machines the prologue - is where the new fp value is established. */ - step_frame_address = 0; - /* And make sure stepping stops right away then. */ - step_range_end = step_range_start; - } - goto save_pc; + if (stop_func_start == stop_pc) + { + /* We are already there: stop now. */ + stop_step = 1; + break; + } + else + /* Put the step-breakpoint there and go until there. */ + { + struct symtab_and_line sr_sal; + + sr_sal.pc = stop_func_start; + sr_sal.symtab = NULL; + sr_sal.line = 0; + /* Do not specify what the fp should be when we stop + since on some machines the prologue + is where the new fp value is established. */ + step_resume_breakpoint = + set_momentary_breakpoint (sr_sal, (CORE_ADDR)0, + bp_step_resume); + if (breakpoints_inserted) + insert_breakpoints (); + + /* And make sure stepping stops right away then. */ + step_range_end = step_range_start; } + goto keep_going; + } - /* We've wandered out of the step range (but haven't done a - subroutine call or return). */ + /* We've wandered out of the step range (but haven't done a + subroutine call or return). (Is that true? I think we get + here if we did a return and maybe a longjmp). */ - sal = find_pc_line(stop_pc, 0); - - if (step_range_end == 1 || /* stepi or nexti */ - sal.line == 0 || /* ...or no line # info */ - (stop_pc == sal.pc /* ...or we're at the start */ - && current_line != sal.line)) { /* of a different line */ - /* Stop because we're done stepping. */ - stop_step = 1; - break; - } else { - /* We aren't done stepping, and we have line number info for $pc. - Optimize by setting the step_range for the line. - (We might not be in the original line, but if we entered a - new line in mid-statement, we continue stepping. This makes - things like for(;;) statements work better.) */ - step_range_start = sal.pc; - step_range_end = sal.end; - goto save_pc; - } - /* We never fall through here */ + 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; + break; + } + + if (sal.line == 0) + { + /* We have no line number information. That means to stop + stepping (does this always happen right after one instruction, + when we do "s" in a function with no line numbers, + or can this happen as a result of a return or longjmp?). */ + stop_step = 1; + break; + } + + if (stop_pc == sal.pc && current_line != sal.line) + { + /* We are at the start of a different line. So stop. Note that + we don't stop if we step into the middle of a different line. + That is said to make things like for (;;) statements work + better. */ + stop_step = 1; + break; } + /* We aren't done stepping. + + Optimize by setting the stepping range to the line. + (We might not be in the original line, but if we entered a + new line in mid-statement, we continue stepping. This makes + things like for(;;) statements work better.) */ + step_range_start = sal.pc; + step_range_end = sal.end; + goto keep_going; + + check_sigtramp2: if (trap_expected && IN_SIGTRAMP (stop_pc, stop_func_name) && !IN_SIGTRAMP (prev_pc, prev_func_name)) @@ -1090,27 +1077,31 @@ step_into_function: us stop), thus stepping into sigtramp. So we need to set a step_resume_break_address breakpoint - and continue until we hit it, and then step. */ - step_resume_break_address = prev_pc; - /* Always 1, I think, but it's probably easier to have - the step_resume_break as usual rather than trying to - re-use the breakpoint which is already there. */ - step_resume_break_duplicate = - breakpoint_here_p (step_resume_break_address); + and continue until we hit it, and then step. FIXME: This should + be more enduring than a step_resume breakpoint; we should know + that we will later need to keep going rather than re-hitting + the breakpoint here (see testsuite/gdb.t06/signals.exp where + it says "exceedingly difficult"). */ + struct symtab_and_line sr_sal; + + sr_sal.pc = prev_pc; + sr_sal.symtab = NULL; + sr_sal.line = 0; + step_resume_breakpoint = + set_momentary_breakpoint (sr_sal, get_current_frame (), + bp_step_resume); if (breakpoints_inserted) - insert_step_breakpoint (); + insert_breakpoints (); + remove_breakpoints_on_following_step = 1; another_trap = 1; } -/* My apologies to the gods of structured programming. */ -/* Come to this label when you need to resume the inferior. It's really much - cleaner at this time to do a goto than to try and figure out what the - if-else chain ought to look like!! */ - keep_going: + /* Come to this label when you need to resume the inferior. + It's really much cleaner to do a goto than a maze of if-else + conditions. */ -save_pc: /* Save the pc before execution, to compare with pc after stop. */ prev_pc = read_pc (); /* Might have been DECR_AFTER_BREAK */ prev_func_start = stop_func_start; /* Ok, since if DECR_PC_AFTER @@ -1129,8 +1120,8 @@ save_pc: /* We took a signal (which we are supposed to pass through to the inferior, else we'd have done a break above) and we haven't yet gotten our trap. Simply continue. */ - resume ((step_range_end && !step_resume_break_address) - || (trap_expected && !step_resume_break_address) + resume ((step_range_end && step_resume_breakpoint == NULL) + || (trap_expected && step_resume_breakpoint == NULL) || bpstat_should_step (), stop_signal); } @@ -1149,7 +1140,7 @@ save_pc: to one-proceed past a breakpoint. */ /* If we've just finished a special step resume and we don't want to hit a breakpoint, pull em out. */ - if (!step_resume_break_address && + if (step_resume_breakpoint == NULL && remove_breakpoints_on_following_step) { remove_breakpoints_on_following_step = 0; @@ -1157,9 +1148,8 @@ save_pc: breakpoints_inserted = 0; } else if (!breakpoints_inserted && - (step_resume_break_address != 0 || !another_trap)) + (step_resume_breakpoint != NULL || !another_trap)) { - insert_step_breakpoint (); breakpoints_failed = insert_breakpoints (); if (breakpoints_failed) break; @@ -1190,7 +1180,7 @@ save_pc: } #endif /* SHIFT_INST_REGS */ - resume ((!step_resume_break_address + resume ((step_resume_breakpoint == NULL && !handling_longjmp && (step_range_end || trap_expected)) @@ -1210,6 +1200,7 @@ save_pc: prev_func_name = stop_func_name; prev_sp = stop_sp; } + do_cleanups (old_cleanups); } /* Here to return control to GDB when the inferior stops for real. @@ -1237,9 +1228,6 @@ normal_stop () The same program may be running in another process.\n"); } - if (target_has_execution) - remove_step_breakpoint (); - if (target_has_execution && breakpoints_inserted) if (remove_breakpoints ()) { @@ -1325,23 +1313,6 @@ hook_stop_stub (cmd) execute_user_command ((struct cmd_list_element *)cmd, 0); return (0); } - - -static void -insert_step_breakpoint () -{ - if (step_resume_break_address && !step_resume_break_duplicate) - target_insert_breakpoint (step_resume_break_address, - step_resume_break_shadow); -} - -static void -remove_step_breakpoint () -{ - if (step_resume_break_address && !step_resume_break_duplicate) - target_remove_breakpoint (step_resume_break_address, - step_resume_break_shadow); -} int signal_stop_state (signo) int signo; @@ -1612,7 +1583,6 @@ save_inferior_status (inf_status, restore_stack_info) inf_status->step_range_end = step_range_end; inf_status->step_frame_address = step_frame_address; inf_status->step_over_calls = step_over_calls; - inf_status->step_resume_break_address = step_resume_break_address; inf_status->stop_after_trap = stop_after_trap; inf_status->stop_soon_quietly = stop_soon_quietly; /* Save original bpstat chain here; replace it with copy of chain. @@ -1650,7 +1620,6 @@ restore_inferior_status (inf_status) step_range_end = inf_status->step_range_end; step_frame_address = inf_status->step_frame_address; step_over_calls = inf_status->step_over_calls; - step_resume_break_address = inf_status->step_resume_break_address; stop_after_trap = inf_status->stop_after_trap; stop_soon_quietly = inf_status->stop_soon_quietly; bpstat_clear (&stop_bpstat); -- 2.7.4