(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.
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.
/* 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
};
#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
/* 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
#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;
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
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"));
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 ");
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);
case bp_longjmp:
case bp_longjmp_resume:
case bp_step_resume:
+ case bp_through_sigtramp:
case bp_call_dummy:
break;
}
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
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;
};
\f
/* The following stuff is an abstract data type "bpstat" ("breakpoint status").
/* 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. */
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));
static CORE_ADDR prev_sp;
static CORE_ADDR prev_func_start;
static char *prev_func_name;
+static CORE_ADDR prev_frame_address;
\f
/* Start remote-debugging of a machine over a serial link. */
prev_sp = 0;
prev_func_start = 0;
prev_func_name = NULL;
+ prev_frame_address = 0;
trap_expected_after_continue = 0;
breakpoints_inserted = 0;
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)
{
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;
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
{
{
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
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;
}
}
/* 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)
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 ();
}
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 ();
}
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 ();
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. */
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)
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);
}