From bcc377184156be31b11f59a95109baa6509c04b2 Mon Sep 17 00:00:00 2001 From: Jim Kingdon Date: Fri, 25 Feb 1994 09:12:29 +0000 Subject: [PATCH] * breakpoint.h (enum bptype): New type bp_through_sigtramp. (bpstat_what_main_action): New code BPSTAT_WHAT_THROUGH_SIGTRAMP. * breakpoint.c (bpstat_what): Return BPSTAT_WHAT_THROUGH_SIGTRAMP if we hit a bp_through_sigtramp breakpoint. Remove kludge which ignored bs->stop for a bp_step_resume breakpoint. * infrun.c (wait_for_inferior): Make a through_sigtramp_breakpoint which performs one (the check_sigtramp2 one) of the functions which had been handled by the step_resume_breakpoint. For each use of the step_resume_breakpoint, make it still use the step_resume_breakpoint, use the through_sigtramp_breakpoint, or operate on both. Deal with BPSTAT_WHAT_THROUGH_SIGTRAMP return from bpstat_what. When setting the frame address of the step resume breakpoint, set it to the address for frame *before* the call instruction is executed, not after. --- gdb/ChangeLog | 16 +++++++++ gdb/breakpoint.c | 47 +++++++++++++----------- gdb/breakpoint.h | 28 ++++++++++----- gdb/infrun.c | 107 ++++++++++++++++++++++++++++++++++++++----------------- 4 files changed, 137 insertions(+), 61 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index eea0215..35a3961 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,21 @@ Thu Feb 24 08:30:33 1994 Jim Kingdon (kingdon@deneb.cygnus.com) + * breakpoint.h (enum bptype): New type bp_through_sigtramp. + (bpstat_what_main_action): New code BPSTAT_WHAT_THROUGH_SIGTRAMP. + * breakpoint.c (bpstat_what): Return BPSTAT_WHAT_THROUGH_SIGTRAMP + if we hit a bp_through_sigtramp breakpoint. Remove kludge which + ignored bs->stop for a bp_step_resume breakpoint. + * infrun.c (wait_for_inferior): Make a through_sigtramp_breakpoint + which performs one (the check_sigtramp2 one) of the functions + which had been handled by the step_resume_breakpoint. For each + use of the step_resume_breakpoint, make it still use the + step_resume_breakpoint, use the through_sigtramp_breakpoint, or + operate on both. + Deal with BPSTAT_WHAT_THROUGH_SIGTRAMP return from bpstat_what. + When setting the frame address of the step resume breakpoint, set + it to the address for frame *before* the call instruction is + executed, not after. + * mips-tdep.c (mips_print_register): Print integers using print_scalar_formatted rather than duplicating all the CC_HAS_LONG_LONG and so on. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 717335f..93597d4 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1267,6 +1267,9 @@ bpstat_what (bs) /* We hit the step_resume breakpoint. */ step_resume, + /* We hit the through_sigtramp breakpoint. */ + through_sig, + /* This is just used to count how many enums there are. */ class_last }; @@ -1282,6 +1285,7 @@ bpstat_what (bs) #define clrlr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME #define clrlrs BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE #define sr BPSTAT_WHAT_STEP_RESUME +#define ts BPSTAT_WHAT_THROUGH_SIGTRAMP /* "Can't happen." Might want to print an error message. abort() is not out of the question, but chances are GDB is just @@ -1299,22 +1303,25 @@ bpstat_what (bs) /* step_resume entries: a step resume breakpoint overrides another breakpoint of signal handling (see comment in wait_for_inferior at first IN_SIGTRAMP where we set the step_resume breakpoint). */ + /* We handle the through_sigtramp_breakpoint the same way; having both + one of those and a step_resume_breakpoint is probably very rare (?). */ 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 sr */ - -/*no_effect*/ {keep_c, stop_s, stop_n, single, setlr , clrlr , clrlrs, sr}, -/*wp_silent*/ {stop_s, stop_s, stop_n, stop_s, stop_s, stop_s, stop_s, sr}, -/*wp_noisy*/ {stop_n, stop_n, stop_n, stop_n, stop_n, stop_n, stop_n, sr}, -/*bp_nostop*/ {single, stop_s, stop_n, single, setlr , clrlrs, clrlrs, sr}, -/*bp_silent*/ {stop_s, stop_s, stop_n, stop_s, stop_s, stop_s, stop_s, sr}, -/*bp_noisy*/ {stop_n, stop_n, stop_n, stop_n, stop_n, stop_n, stop_n, sr}, -/*long_jump*/ {setlr , stop_s, stop_n, setlr , err , err , err , sr}, -/*long_resume*/ {clrlr , stop_s, stop_n, clrlrs, err , err , err , sr}, -/*step_resume*/ {sr , sr , sr , sr , sr , sr , sr , sr} + /* keep_c stop_s stop_n single setlr clrlr clrlrs sr ts + */ +/*no_effect*/ {keep_c,stop_s,stop_n,single, setlr , clrlr , clrlrs, sr, ts}, +/*wp_silent*/ {stop_s,stop_s,stop_n,stop_s, stop_s, stop_s, stop_s, sr, ts}, +/*wp_noisy*/ {stop_n,stop_n,stop_n,stop_n, stop_n, stop_n, stop_n, sr, ts}, +/*bp_nostop*/ {single,stop_s,stop_n,single, setlr , clrlrs, clrlrs, sr, ts}, +/*bp_silent*/ {stop_s,stop_s,stop_n,stop_s, stop_s, stop_s, stop_s, sr, ts}, +/*bp_noisy*/ {stop_n,stop_n,stop_n,stop_n, stop_n, stop_n, stop_n, sr, ts}, +/*long_jump*/ {setlr ,stop_s,stop_n,setlr , err , err , err , sr, ts}, +/*long_resume*/ {clrlr ,stop_s,stop_n,clrlrs, err , err , err , sr, ts}, +/*step_resume*/ {sr ,sr ,sr ,sr , sr , sr , sr , sr, ts}, +/*through_sig*/ {ts ,ts ,ts ,ts , ts , ts , ts , ts, ts} }; #undef keep_c #undef stop_s @@ -1324,6 +1331,8 @@ bpstat_what (bs) #undef clrlr #undef clrlrs #undef err +#undef sr +#undef ts enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING; struct bpstat_what retval; @@ -1370,21 +1379,16 @@ bpstat_what (bs) 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 bs_class = step_resume; -#if 0 } else /* It is for the wrong frame. */ bs_class = bp_nostop; -#endif + break; + case bp_through_sigtramp: + bs_class = through_sig; break; case bp_call_dummy: /* Make sure the action is stop (silent or noisy), so infrun.c @@ -1468,6 +1472,7 @@ breakpoint_1 (bnum, allflag) case bp_longjmp: case bp_longjmp_resume: case bp_step_resume: + case bp_through_sigtramp: case bp_call_dummy: if (addressprint) printf_filtered ("%s ", local_hex_string_custom ((unsigned long) b->address, "08l")); @@ -1498,6 +1503,7 @@ breakpoint_1 (bnum, allflag) printf_filtered ("\tstop only in stack frame at "); print_address_numeric (b->frame, gdb_stdout); printf_filtered ("\n"); + } if (b->cond) { printf_filtered ("\tstop only if "); @@ -1824,7 +1830,7 @@ mention (b) break; case bp_breakpoint: printf_filtered ("Breakpoint %d at ", b->number); - print_address_numeric (b->address); + print_address_numeric (b->address, gdb_stdout); if (b->source_file) printf_filtered (": file %s, line %d.", b->source_file, b->line_number); @@ -1834,6 +1840,7 @@ mention (b) case bp_longjmp: case bp_longjmp_resume: case bp_step_resume: + case bp_through_sigtramp: case bp_call_dummy: break; } diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 2bebe3e..5f45ccd 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -49,6 +49,9 @@ enum bptype { stepping over signal handlers, and for skipping prologues. */ bp_step_resume, + /* Used by wait_for_inferior for stepping over signal handlers. */ + bp_through_sigtramp, + /* The breakpoint at the end of a call dummy. */ /* FIXME: What if the function we are calling longjmp()s out of the call, or the user gets out with the "return" command? We currently @@ -145,6 +148,8 @@ struct breakpoint struct block *exp_valid_block; /* Value of the watchpoint the last time we checked it. */ value val; + /* Thread number for thread-specific breakpoint, or -1 if don't care */ + int thread; }; /* The following stuff is an abstract data type "bpstat" ("breakpoint status"). @@ -205,23 +210,25 @@ enum bpstat_what_main_action { /* Clear longjmp_resume breakpoint, then handle as BPSTAT_WHAT_SINGLE. */ BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE, + /* Clear step resume breakpoint, and keep checking. */ + BPSTAT_WHAT_STEP_RESUME, + + /* Clear through_sigtramp breakpoint, muck with trap_expected, and keep + checking. */ + BPSTAT_WHAT_THROUGH_SIGTRAMP, + /* This is just used to keep track of how many enums there are. */ BPSTAT_WHAT_LAST }; struct bpstat_what { - enum bpstat_what_main_action main_action : 4; - - /* Did we hit the step resume breakpoint? This is separate from the - main_action to allow for it to be combined with any of the main - actions. */ - unsigned int step_resume : 1; + enum bpstat_what_main_action main_action; /* Did we hit a call dummy breakpoint? This only goes with a main_action of BPSTAT_WHAT_STOP_SILENT or BPSTAT_WHAT_STOP_NOISY (the concept of continuing from a call dummy without popping the frame is not a useful one). */ - unsigned int call_dummy : 1; + int call_dummy; }; /* Tell what to do about this bpstat. */ @@ -292,8 +299,11 @@ struct bpstat struct frame_info; #endif -extern int -breakpoint_here_p PARAMS ((CORE_ADDR)); +extern int breakpoint_here_p PARAMS ((CORE_ADDR)); + +extern int frame_in_dummy PARAMS ((struct frame_info *)); + +extern int breakpoint_thread_match PARAMS ((CORE_ADDR, int)); extern void until_break_command PARAMS ((char *, int)); diff --git a/gdb/infrun.c b/gdb/infrun.c index 9549bce..ef9b826 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -335,6 +335,7 @@ static CORE_ADDR prev_pc; static CORE_ADDR prev_sp; static CORE_ADDR prev_func_start; static char *prev_func_name; +static CORE_ADDR prev_frame_address; /* Start remote-debugging of a machine over a serial link. */ @@ -360,6 +361,7 @@ init_wait_for_inferior () prev_sp = 0; prev_func_start = 0; prev_func_name = NULL; + prev_frame_address = 0; trap_expected_after_continue = 0; breakpoints_inserted = 0; @@ -402,20 +404,24 @@ wait_for_inferior () struct symtab *current_symtab; int handling_longjmp = 0; /* FIXME */ struct breakpoint *step_resume_breakpoint = NULL; + struct breakpoint *through_sigtramp_breakpoint = NULL; int pid; old_cleanups = make_cleanup (delete_breakpoint_current_contents, &step_resume_breakpoint); + make_cleanup (delete_breakpoint_current_contents, + &through_sigtramp_breakpoint); sal = find_pc_line(prev_pc, 0); current_line = sal.line; current_symtab = sal.symtab; /* Are we stepping? */ -#define CURRENTLY_STEPPING() ((step_resume_breakpoint == NULL \ - && !handling_longjmp \ - && (step_range_end \ - || trap_expected)) \ - || bpstat_should_step ()) +#define CURRENTLY_STEPPING() \ + ((through_sigtramp_breakpoint == NULL \ + && !handling_longjmp \ + && ((step_range_end && step_resume_breakpoint == NULL) \ + || trap_expected)) \ + || bpstat_should_step ()) while (1) { @@ -571,6 +577,15 @@ switch_thread: delete_breakpoint (step_resume_breakpoint); step_resume_breakpoint = NULL; } + + /* Not sure whether we need to blow this away too, + but probably it is like the step-resume + breakpoint. */ + if (through_sigtramp_breakpoint) + { + delete_breakpoint (through_sigtramp_breakpoint); + through_sigtramp_breakpoint = NULL; + } prev_pc = 0; prev_sp = 0; prev_func_name = NULL; @@ -663,11 +678,11 @@ switch_thread: if just proceeded over a breakpoint. However, if we are trying to proceed over a breakpoint - and end up in sigtramp, then step_resume_breakpoint + and end up in sigtramp, then through_sigtramp_breakpoint will be set and we should check whether we've hit the step breakpoint. */ if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected - && step_resume_breakpoint == NULL) + && through_sigtramp_breakpoint == NULL) bpstat_clear (&stop_bpstat); else { @@ -786,7 +801,13 @@ switch_thread: { delete_breakpoint (step_resume_breakpoint); step_resume_breakpoint = NULL; - what.step_resume = 0; + } + /* Not sure whether we need to blow this away too, but probably + it is like the step-resume breakpoint. */ + if (through_sigtramp_breakpoint != NULL) + { + delete_breakpoint (through_sigtramp_breakpoint); + through_sigtramp_breakpoint = NULL; } #if 0 @@ -831,32 +852,42 @@ switch_thread: 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. */ + + /* We are about to nuke the step_resume_breakpoint and + through_sigtramp_breakpoint via the cleanup chain, so + no need to worry about it here. */ + goto stop_stepping; 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_LAST: - /* Not a real code, but listed here to shut up gcc -Wall. */ + /* We are about to nuke the step_resume_breakpoint and + through_sigtramp_breakpoint via the cleanup chain, so + no need to worry about it here. */ - case BPSTAT_WHAT_KEEP_CHECKING: - break; - } + goto stop_stepping; - if (what.step_resume) - { + case BPSTAT_WHAT_STEP_RESUME: delete_breakpoint (step_resume_breakpoint); step_resume_breakpoint = NULL; + break; + + case BPSTAT_WHAT_THROUGH_SIGTRAMP: + delete_breakpoint (through_sigtramp_breakpoint); + through_sigtramp_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; + break; + + case BPSTAT_WHAT_LAST: + /* Not a real code, but listed here to shut up gcc -Wall. */ + + case BPSTAT_WHAT_KEEP_CHECKING: + break; } } @@ -892,10 +923,8 @@ switch_thread: /* 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. */ + /* I'm not sure whether this needs to be check_sigtramp2 or + whether it could/should be keep_going. */ goto check_sigtramp2; if (step_range_end == 0) @@ -928,20 +957,29 @@ switch_thread: if (IN_SIGTRAMP (stop_pc, stop_func_name) && !IN_SIGTRAMP (prev_pc, prev_func_name)) { + /* We've just taken a signal; go until we are back to + the point where we took it and one more. */ + /* 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. */ + + /* Note that if we are stopped at a breakpoint, then we need + the step_resume breakpoint to override any breakpoints at + the same location, so that we will still step over the + breakpoint even though the signal happened. */ + { struct symtab_and_line sr_sal; sr_sal.pc = prev_pc; sr_sal.symtab = NULL; sr_sal.line = 0; + /* We perhaps could set the frame if we kept track of what + the frame corresponding to prev_pc was. But we don't, + so don't. */ step_resume_breakpoint = - set_momentary_breakpoint (sr_sal, get_current_frame (), - bp_step_resume); + set_momentary_breakpoint (sr_sal, NULL, bp_step_resume); if (breakpoints_inserted) insert_breakpoints (); } @@ -1054,6 +1092,7 @@ step_over_function: step_resume_breakpoint = set_momentary_breakpoint (sr_sal, get_current_frame (), bp_step_resume); + step_resume_breakpoint->frame = prev_frame_address; if (breakpoints_inserted) insert_breakpoints (); } @@ -1180,9 +1219,11 @@ step_into_function: 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); + /* We perhaps could set the frame if we kept track of what + the frame corresponding to prev_pc was. But we don't, + so don't. */ + through_sigtramp_breakpoint = + set_momentary_breakpoint (sr_sal, NULL, bp_through_sigtramp); if (breakpoints_inserted) insert_breakpoints (); @@ -1204,6 +1245,7 @@ step_into_function: function. */ prev_func_name = stop_func_name; prev_sp = stop_sp; + prev_frame_address = stop_frame_address; /* If we did not do break;, it means we should keep running the inferior and not return to debugger. */ @@ -1238,7 +1280,7 @@ step_into_function: breakpoints_inserted = 0; } else if (!breakpoints_inserted && - (step_resume_breakpoint != NULL || !another_trap)) + (through_sigtramp_breakpoint != NULL || !another_trap)) { breakpoints_failed = insert_breakpoints (); if (breakpoints_failed) @@ -1278,6 +1320,7 @@ step_into_function: prev_func_start = stop_func_start; prev_func_name = stop_func_name; prev_sp = stop_sp; + prev_frame_address = stop_frame_address; } do_cleanups (old_cleanups); } -- 2.7.4