* 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.
This commit is contained in:
Jim Kingdon 1994-02-25 09:12:29 +00:00
parent 3fed1c4a60
commit bcc3771841
4 changed files with 140 additions and 64 deletions

View file

@ -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.

View file

@ -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;
}

View file

@ -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));

View file

@ -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,33 +852,43 @@ 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. */
/* 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_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;
}
if (what.step_resume)
{
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;
}
}
/* We come here if we hit a breakpoint but should not
@ -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);
}