2004-05-10 Andrew Cagney <cagney@redhat.com>
* infrun.c (check_sigtramp2): Delete function. (handle_inferior_event): When single stepping, and taking a signal, set a breakpoint at the signal return address. Delete redundant calls to check_sigtramp2. (insert_step_resume_breakpoint): New function. (through_sigtramp_breakpoint, handle_inferior_event) (follow_exec, wait_for_inferior, fetch_inferior_event) (currently_stepping, keep_going): Delete most uses of through_sigtramp_breakpoint, not that it should be deleted. (delete_breakpoint_current_contents): Delete function. Index: testsuite/ChangeLog 2004-05-10 Andrew Cagney <cagney@redhat.com> * gdb.base/signals.exp (signal_tests_1): Simplify "continue to func1" and "next to 2nd alarm", kernel bug avoided.
This commit is contained in:
parent
03f4cc205b
commit
d303a6c766
|
@ -1,3 +1,16 @@
|
||||||
|
2004-05-10 Andrew Cagney <cagney@redhat.com>
|
||||||
|
|
||||||
|
* infrun.c (check_sigtramp2): Delete function.
|
||||||
|
(handle_inferior_event): When single stepping, and taking a
|
||||||
|
signal, set a breakpoint at the signal return address. Delete
|
||||||
|
redundant calls to check_sigtramp2.
|
||||||
|
(insert_step_resume_breakpoint): New function.
|
||||||
|
(through_sigtramp_breakpoint, handle_inferior_event)
|
||||||
|
(follow_exec, wait_for_inferior, fetch_inferior_event)
|
||||||
|
(currently_stepping, keep_going): Delete most uses of
|
||||||
|
through_sigtramp_breakpoint, not that it should be deleted.
|
||||||
|
(delete_breakpoint_current_contents): Delete function.
|
||||||
|
|
||||||
2004-05-10 Randolph Chung <tausq@debian.org>
|
2004-05-10 Randolph Chung <tausq@debian.org>
|
||||||
|
|
||||||
* config/pa/linux.mt (TM_FILE): Use new tm-linux.h for hppa-linux
|
* config/pa/linux.mt (TM_FILE): Use new tm-linux.h for hppa-linux
|
||||||
|
|
189
gdb/infrun.c
189
gdb/infrun.c
|
@ -60,8 +60,6 @@ static void resume_cleanups (void *);
|
||||||
|
|
||||||
static int hook_stop_stub (void *);
|
static int hook_stop_stub (void *);
|
||||||
|
|
||||||
static void delete_breakpoint_current_contents (void *);
|
|
||||||
|
|
||||||
static int restore_selected_frame (void *);
|
static int restore_selected_frame (void *);
|
||||||
|
|
||||||
static void build_infrun (void);
|
static void build_infrun (void);
|
||||||
|
@ -305,6 +303,8 @@ static int breakpoints_failed;
|
||||||
static int stop_print_frame;
|
static int stop_print_frame;
|
||||||
|
|
||||||
static struct breakpoint *step_resume_breakpoint = NULL;
|
static struct breakpoint *step_resume_breakpoint = NULL;
|
||||||
|
/* NOTE: cagney/2004-05-08: This variable needs to be garbage
|
||||||
|
collected, it isn't used. */
|
||||||
static struct breakpoint *through_sigtramp_breakpoint = NULL;
|
static struct breakpoint *through_sigtramp_breakpoint = NULL;
|
||||||
|
|
||||||
/* On some platforms (e.g., HP-UX), hardware watchpoints have bad
|
/* On some platforms (e.g., HP-UX), hardware watchpoints have bad
|
||||||
|
@ -423,9 +423,6 @@ follow_exec (int pid, char *execd_pathname)
|
||||||
step_range_start = 0;
|
step_range_start = 0;
|
||||||
step_range_end = 0;
|
step_range_end = 0;
|
||||||
|
|
||||||
/* If there was one, it's gone now. */
|
|
||||||
through_sigtramp_breakpoint = NULL;
|
|
||||||
|
|
||||||
/* What is this a.out's name? */
|
/* What is this a.out's name? */
|
||||||
printf_unfiltered ("Executing new program: %s\n", execd_pathname);
|
printf_unfiltered ("Executing new program: %s\n", execd_pathname);
|
||||||
|
|
||||||
|
@ -905,17 +902,6 @@ init_wait_for_inferior (void)
|
||||||
|
|
||||||
stepping_past_singlestep_breakpoint = 0;
|
stepping_past_singlestep_breakpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
delete_breakpoint_current_contents (void *arg)
|
|
||||||
{
|
|
||||||
struct breakpoint **breakpointp = (struct breakpoint **) arg;
|
|
||||||
if (*breakpointp != NULL)
|
|
||||||
{
|
|
||||||
delete_breakpoint (*breakpointp);
|
|
||||||
*breakpointp = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This enum encodes possible reasons for doing a target_wait, so that
|
/* This enum encodes possible reasons for doing a target_wait, so that
|
||||||
wfi can call target_wait in one place. (Ultimately the call will be
|
wfi can call target_wait in one place. (Ultimately the call will be
|
||||||
|
@ -984,9 +970,10 @@ void init_execution_control_state (struct execution_control_state *ecs);
|
||||||
static void handle_step_into_function (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);
|
void handle_inferior_event (struct execution_control_state *ecs);
|
||||||
|
|
||||||
static void check_sigtramp2 (struct execution_control_state *ecs);
|
|
||||||
static void step_into_function (struct execution_control_state *ecs);
|
static void step_into_function (struct execution_control_state *ecs);
|
||||||
static void step_over_function (struct execution_control_state *ecs);
|
static void step_over_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 stop_stepping (struct execution_control_state *ecs);
|
||||||
static void prepare_to_wait (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 keep_going (struct execution_control_state *ecs);
|
||||||
|
@ -1008,8 +995,6 @@ wait_for_inferior (void)
|
||||||
|
|
||||||
old_cleanups = make_cleanup (delete_step_resume_breakpoint,
|
old_cleanups = make_cleanup (delete_step_resume_breakpoint,
|
||||||
&step_resume_breakpoint);
|
&step_resume_breakpoint);
|
||||||
make_cleanup (delete_breakpoint_current_contents,
|
|
||||||
&through_sigtramp_breakpoint);
|
|
||||||
|
|
||||||
/* wfi still stays in a loop, so it's OK just to take the address of
|
/* wfi still stays in a loop, so it's OK just to take the address of
|
||||||
a local to get the ecs pointer. */
|
a local to get the ecs pointer. */
|
||||||
|
@ -1070,8 +1055,6 @@ fetch_inferior_event (void *client_data)
|
||||||
{
|
{
|
||||||
old_cleanups = make_exec_cleanup (delete_step_resume_breakpoint,
|
old_cleanups = make_exec_cleanup (delete_step_resume_breakpoint,
|
||||||
&step_resume_breakpoint);
|
&step_resume_breakpoint);
|
||||||
make_exec_cleanup (delete_breakpoint_current_contents,
|
|
||||||
&through_sigtramp_breakpoint);
|
|
||||||
|
|
||||||
/* Fill in with reasonable starting values. */
|
/* Fill in with reasonable starting values. */
|
||||||
init_execution_control_state (async_ecs);
|
init_execution_control_state (async_ecs);
|
||||||
|
@ -1989,15 +1972,9 @@ handle_inferior_event (struct execution_control_state *ecs)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't even think about breakpoints
|
/* Don't even think about breakpoints if just proceeded over a
|
||||||
if just proceeded over a breakpoint.
|
breakpoint. */
|
||||||
|
if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected)
|
||||||
However, if we are trying to proceed over a 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
|
|
||||||
&& through_sigtramp_breakpoint == NULL)
|
|
||||||
bpstat_clear (&stop_bpstat);
|
bpstat_clear (&stop_bpstat);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2080,39 +2057,22 @@ process_event_stop_test:
|
||||||
if (signal_program[stop_signal] == 0)
|
if (signal_program[stop_signal] == 0)
|
||||||
stop_signal = TARGET_SIGNAL_0;
|
stop_signal = TARGET_SIGNAL_0;
|
||||||
|
|
||||||
/* I'm not sure whether this needs to be check_sigtramp2 or
|
if (step_range_end != 0
|
||||||
whether it could/should be keep_going.
|
&& stop_signal != TARGET_SIGNAL_0
|
||||||
|
&& stop_pc >= step_range_start && stop_pc < step_range_end
|
||||||
|
&& frame_id_eq (get_frame_id (get_current_frame ()), step_frame_id))
|
||||||
|
{
|
||||||
|
/* The inferior is about to take a signal that will take it
|
||||||
|
out of the single step range. Set a breakpoint at the
|
||||||
|
current PC (which is presumably where the signal handler
|
||||||
|
will eventually return) and then allow the inferior to
|
||||||
|
run free.
|
||||||
|
|
||||||
This used to jump to step_over_function if we are stepping,
|
Note that this is only needed for a signal delivered
|
||||||
which is wrong.
|
while in the single-step range. Nested signals aren't a
|
||||||
|
problem as they eventually all return. */
|
||||||
Suppose the user does a `next' over a function call, and while
|
insert_step_resume_breakpoint (get_current_frame (), ecs);
|
||||||
that call is in progress, the inferior receives a signal for
|
}
|
||||||
which GDB does not stop (i.e., signal_stop[SIG] is false). In
|
|
||||||
that case, when we reach this point, there is already a
|
|
||||||
step-resume breakpoint established, right where it should be:
|
|
||||||
immediately after the function call the user is "next"-ing
|
|
||||||
over. If we call step_over_function now, two bad things
|
|
||||||
happen:
|
|
||||||
|
|
||||||
- we'll create a new breakpoint, at wherever the current
|
|
||||||
frame's return address happens to be. That could be
|
|
||||||
anywhere, depending on what function call happens to be on
|
|
||||||
the top of the stack at that point. Point is, it's probably
|
|
||||||
not where we need it.
|
|
||||||
|
|
||||||
- the existing step-resume breakpoint (which is at the correct
|
|
||||||
address) will get orphaned: step_resume_breakpoint will point
|
|
||||||
to the new breakpoint, and the old step-resume breakpoint
|
|
||||||
will never be cleaned up.
|
|
||||||
|
|
||||||
The old behavior was meant to help HP-UX single-step out of
|
|
||||||
sigtramps. It would place the new breakpoint at prev_pc, which
|
|
||||||
was certainly wrong. I don't know the details there, so fixing
|
|
||||||
this probably breaks that. As with anything else, it's up to
|
|
||||||
the HP-UX maintainer to furnish a fix that doesn't break other
|
|
||||||
platforms. --JimB, 20 May 1999 */
|
|
||||||
check_sigtramp2 (ecs);
|
|
||||||
keep_going (ecs);
|
keep_going (ecs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2153,13 +2113,6 @@ process_event_stop_test:
|
||||||
{
|
{
|
||||||
delete_step_resume_breakpoint (&step_resume_breakpoint);
|
delete_step_resume_breakpoint (&step_resume_breakpoint);
|
||||||
}
|
}
|
||||||
/* 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
|
#if 0
|
||||||
/* FIXME - Need to implement nested temporary breakpoints */
|
/* FIXME - Need to implement nested temporary breakpoints */
|
||||||
|
@ -2207,9 +2160,8 @@ process_event_stop_test:
|
||||||
case BPSTAT_WHAT_STOP_NOISY:
|
case BPSTAT_WHAT_STOP_NOISY:
|
||||||
stop_print_frame = 1;
|
stop_print_frame = 1;
|
||||||
|
|
||||||
/* We are about to nuke the step_resume_breakpoint and
|
/* We are about to nuke the step_resume_breakpointt via the
|
||||||
through_sigtramp_breakpoint via the cleanup chain, so
|
cleanup chain, so no need to worry about it here. */
|
||||||
no need to worry about it here. */
|
|
||||||
|
|
||||||
stop_stepping (ecs);
|
stop_stepping (ecs);
|
||||||
return;
|
return;
|
||||||
|
@ -2217,9 +2169,8 @@ process_event_stop_test:
|
||||||
case BPSTAT_WHAT_STOP_SILENT:
|
case BPSTAT_WHAT_STOP_SILENT:
|
||||||
stop_print_frame = 0;
|
stop_print_frame = 0;
|
||||||
|
|
||||||
/* We are about to nuke the step_resume_breakpoint and
|
/* We are about to nuke the step_resume_breakpoin via the
|
||||||
through_sigtramp_breakpoint via the cleanup chain, so
|
cleanup chain, so no need to worry about it here. */
|
||||||
no need to worry about it here. */
|
|
||||||
|
|
||||||
stop_stepping (ecs);
|
stop_stepping (ecs);
|
||||||
return;
|
return;
|
||||||
|
@ -2251,10 +2202,6 @@ process_event_stop_test:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BPSTAT_WHAT_THROUGH_SIGTRAMP:
|
case BPSTAT_WHAT_THROUGH_SIGTRAMP:
|
||||||
if (through_sigtramp_breakpoint)
|
|
||||||
delete_breakpoint (through_sigtramp_breakpoint);
|
|
||||||
through_sigtramp_breakpoint = NULL;
|
|
||||||
|
|
||||||
/* If were waiting for a trap, hitting the step_resume_break
|
/* If were waiting for a trap, hitting the step_resume_break
|
||||||
doesn't count as getting it. */
|
doesn't count as getting it. */
|
||||||
if (trap_expected)
|
if (trap_expected)
|
||||||
|
@ -2398,9 +2345,6 @@ process_event_stop_test:
|
||||||
/* Having a step-resume breakpoint overrides anything
|
/* Having a step-resume breakpoint overrides anything
|
||||||
else having to do with stepping commands until
|
else having to do with stepping commands until
|
||||||
that breakpoint is reached. */
|
that breakpoint is reached. */
|
||||||
/* I'm not sure whether this needs to be check_sigtramp2 or
|
|
||||||
whether it could/should be keep_going. */
|
|
||||||
check_sigtramp2 (ecs);
|
|
||||||
keep_going (ecs);
|
keep_going (ecs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2408,9 +2352,6 @@ process_event_stop_test:
|
||||||
if (step_range_end == 0)
|
if (step_range_end == 0)
|
||||||
{
|
{
|
||||||
/* Likewise if we aren't even stepping. */
|
/* 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. */
|
|
||||||
check_sigtramp2 (ecs);
|
|
||||||
keep_going (ecs);
|
keep_going (ecs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2422,9 +2363,6 @@ process_event_stop_test:
|
||||||
within it! */
|
within it! */
|
||||||
if (stop_pc >= step_range_start && stop_pc < step_range_end)
|
if (stop_pc >= step_range_start && stop_pc < step_range_end)
|
||||||
{
|
{
|
||||||
/* We might be doing a BPSTAT_WHAT_SINGLE and getting a signal.
|
|
||||||
So definately need to check for sigtramp here. */
|
|
||||||
check_sigtramp2 (ecs);
|
|
||||||
keep_going (ecs);
|
keep_going (ecs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2688,50 +2626,13 @@ process_event_stop_test:
|
||||||
static int
|
static int
|
||||||
currently_stepping (struct execution_control_state *ecs)
|
currently_stepping (struct execution_control_state *ecs)
|
||||||
{
|
{
|
||||||
return ((through_sigtramp_breakpoint == NULL
|
return ((!ecs->handling_longjmp
|
||||||
&& !ecs->handling_longjmp
|
|
||||||
&& ((step_range_end && step_resume_breakpoint == NULL)
|
&& ((step_range_end && step_resume_breakpoint == NULL)
|
||||||
|| trap_expected))
|
|| trap_expected))
|
||||||
|| ecs->stepping_through_solib_after_catch
|
|| ecs->stepping_through_solib_after_catch
|
||||||
|| bpstat_should_step ());
|
|| bpstat_should_step ());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
check_sigtramp2 (struct execution_control_state *ecs)
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
struct symtab_and_line sr_sal;
|
|
||||||
|
|
||||||
/* Check that what has happened here is that we have just stepped
|
|
||||||
the inferior with a signal (because it is a signal which
|
|
||||||
shouldn't make us stop), thus stepping into sigtramp. */
|
|
||||||
|
|
||||||
if (!trap_expected)
|
|
||||||
return;
|
|
||||||
if (get_frame_type (get_current_frame ()) != SIGTRAMP_FRAME)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* So we need to set a step_resume_break_address breakpoint 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 the testsuite, gdb.base/signals.exp where it
|
|
||||||
says "exceedingly difficult"). */
|
|
||||||
|
|
||||||
init_sal (&sr_sal); /* initialize to zeroes */
|
|
||||||
sr_sal.pc = prev_pc;
|
|
||||||
sr_sal.section = find_pc_overlay (sr_sal.pc);
|
|
||||||
/* 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_frame_id, bp_through_sigtramp);
|
|
||||||
if (breakpoints_inserted)
|
|
||||||
insert_breakpoints ();
|
|
||||||
|
|
||||||
ecs->remove_breakpoints_on_following_step = 1;
|
|
||||||
ecs->another_trap = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Subroutine call with source code we should not step over. Do step
|
/* Subroutine call with source code we should not step over. Do step
|
||||||
to the first line of code in it. */
|
to the first line of code in it. */
|
||||||
|
|
||||||
|
@ -2809,6 +2710,38 @@ step_into_function (struct execution_control_state *ecs)
|
||||||
keep_going (ecs);
|
keep_going (ecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The inferior, as a result of a function call (has left) or signal
|
||||||
|
(about to leave) the single-step range. Set a momentary breakpoint
|
||||||
|
within the step range where the inferior is expected to later
|
||||||
|
return. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
insert_step_resume_breakpoint (struct frame_info *step_frame,
|
||||||
|
struct execution_control_state *ecs)
|
||||||
|
{
|
||||||
|
struct symtab_and_line sr_sal;
|
||||||
|
|
||||||
|
/* This is only used within the step-resume range/frame. */
|
||||||
|
gdb_assert (frame_id_eq (step_frame_id, get_frame_id (step_frame)));
|
||||||
|
gdb_assert (step_range_end != 0);
|
||||||
|
gdb_assert (get_frame_pc (step_frame) >= step_range_start
|
||||||
|
&& get_frame_pc (step_frame) < step_range_end);
|
||||||
|
|
||||||
|
init_sal (&sr_sal); /* initialize to zeros */
|
||||||
|
|
||||||
|
sr_sal.pc = ADDR_BITS_REMOVE (get_frame_pc (step_frame));
|
||||||
|
sr_sal.section = find_pc_overlay (sr_sal.pc);
|
||||||
|
|
||||||
|
check_for_old_step_resume_breakpoint ();
|
||||||
|
|
||||||
|
step_resume_breakpoint
|
||||||
|
= set_momentary_breakpoint (sr_sal, get_frame_id (step_frame),
|
||||||
|
bp_step_resume);
|
||||||
|
|
||||||
|
if (breakpoints_inserted)
|
||||||
|
insert_breakpoints ();
|
||||||
|
}
|
||||||
|
|
||||||
/* We've just entered a callee, and we wish to resume until it returns
|
/* We've just entered a callee, and we wish to resume until it returns
|
||||||
to the caller. Setting a step_resume breakpoint on the return
|
to the caller. Setting a step_resume breakpoint on the return
|
||||||
address will catch a return from the callee.
|
address will catch a return from the callee.
|
||||||
|
@ -2933,15 +2866,13 @@ keep_going (struct execution_control_state *ecs)
|
||||||
/* If we've just finished a special step resume and we don't
|
/* If we've just finished a special step resume and we don't
|
||||||
want to hit a breakpoint, pull em out. */
|
want to hit a breakpoint, pull em out. */
|
||||||
if (step_resume_breakpoint == NULL
|
if (step_resume_breakpoint == NULL
|
||||||
&& through_sigtramp_breakpoint == NULL
|
|
||||||
&& ecs->remove_breakpoints_on_following_step)
|
&& ecs->remove_breakpoints_on_following_step)
|
||||||
{
|
{
|
||||||
ecs->remove_breakpoints_on_following_step = 0;
|
ecs->remove_breakpoints_on_following_step = 0;
|
||||||
remove_breakpoints ();
|
remove_breakpoints ();
|
||||||
breakpoints_inserted = 0;
|
breakpoints_inserted = 0;
|
||||||
}
|
}
|
||||||
else if (!breakpoints_inserted &&
|
else if (!breakpoints_inserted && !ecs->another_trap)
|
||||||
(through_sigtramp_breakpoint != NULL || !ecs->another_trap))
|
|
||||||
{
|
{
|
||||||
breakpoints_failed = insert_breakpoints ();
|
breakpoints_failed = insert_breakpoints ();
|
||||||
if (breakpoints_failed)
|
if (breakpoints_failed)
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2004-05-10 Andrew Cagney <cagney@redhat.com>
|
||||||
|
|
||||||
|
* gdb.base/signals.exp (signal_tests_1): Simplify "continue to
|
||||||
|
func1" and "next to 2nd alarm", kernel bug avoided.
|
||||||
|
|
||||||
2004-05-10 Daniel Jacobowitz <dan@debian.org>
|
2004-05-10 Daniel Jacobowitz <dan@debian.org>
|
||||||
|
|
||||||
PR external/1568
|
PR external/1568
|
||||||
|
|
|
@ -60,102 +60,47 @@ proc signal_tests_1 {} {
|
||||||
# An alarm has been signaled, give the signal time to get delivered.
|
# An alarm has been signaled, give the signal time to get delivered.
|
||||||
sleep 2
|
sleep 2
|
||||||
|
|
||||||
# i386 BSD currently fails the next test with a SIGTRAP.
|
# NOTE: cagney/2004-05-09: The following is retained as an
|
||||||
setup_xfail "i*86-*-bsd*"
|
# historical reference. Because signal delivery when doing a
|
||||||
# But Dynix has a DECR_PC_AFTER_BREAK of zero, so the failure
|
# next has been changed to use a continue, and not a
|
||||||
# is shadowed by hitting the through_sigtramp_breakpoint.
|
# single-step, the kernel bug of a stuck trace-bit in the
|
||||||
clear_xfail "i*86-sequent-bsd*"
|
# trampoline's saved PS register is avoided.
|
||||||
# Univel SVR4 i386 continues instead of stepping.
|
|
||||||
setup_xfail "i*86-univel-sysv4*"
|
|
||||||
# lynx fails with "next" acting like "continue"
|
|
||||||
setup_xfail "*-*-*lynx*"
|
|
||||||
# linux (aout versions) also fails with "next" acting like "continue"
|
|
||||||
# this is probably more dependant on the kernel version than on the
|
|
||||||
# object file format or utils. (sigh)
|
|
||||||
setup_xfail "i*86-pc-linuxaout-gnu" "i*86-pc-linuxoldld-gnu"
|
|
||||||
send_gdb "next\n"
|
|
||||||
gdb_expect {
|
|
||||||
-re "alarm .*$gdb_prompt $" { pass "next to 2nd alarm (1)" }
|
|
||||||
-re "Program received signal SIGTRAP.*first.*$gdb_prompt $" {
|
|
||||||
|
|
||||||
# This can happen on machines that have a trace flag
|
# This can happen on machines that have a trace flag in their
|
||||||
# in their PS register.
|
# PS register. The trace flag in the PS register will be set
|
||||||
# The trace flag in the PS register will be set due to
|
# due to the `next' command. Before calling the signal
|
||||||
# the `next' command.
|
# handler, the PS register is pushed along with the context on
|
||||||
# Before calling the signal handler, the PS register
|
# the user stack. When the signal handler has finished, it
|
||||||
# is pushed along with the context on the user stack.
|
# reenters the the kernel via a sigreturn syscall, which
|
||||||
# When the signal handler has finished, it reenters the
|
# restores the PS register along with the context. If the
|
||||||
# the kernel via a sigreturn syscall, which restores the
|
# kernel erroneously does not clear the trace flag in the
|
||||||
# PS register along with the context.
|
# pushed context, gdb will receive a SIGTRAP from the set
|
||||||
# If the kernel erroneously does not clear the trace flag
|
# trace flag in the restored context after the signal handler
|
||||||
# in the pushed context, gdb will receive a SIGTRAP from
|
# has finished.
|
||||||
# the set trace flag in the restored context after the
|
|
||||||
# signal handler has finished.
|
|
||||||
|
|
||||||
# I do not yet understand why the SIGTRAP does not occur
|
# I do not yet understand why the SIGTRAP does not occur after
|
||||||
# after stepping the instruction at the restored PC on
|
# stepping the instruction at the restored PC on i386 BSDI 1.0
|
||||||
# i386 BSDI 1.0 systems.
|
# systems.
|
||||||
|
|
||||||
# Note that the vax under Ultrix also exhibits
|
# Note that the vax under Ultrix also exhibits this behaviour
|
||||||
# this behaviour (it is uncovered by the `continue from
|
# (it is uncovered by the `continue from a break in a signal
|
||||||
# a break in a signal handler' test below).
|
# handler' test below). With this test the failure is
|
||||||
# With this test the failure is shadowed by hitting the
|
# shadowed by hitting the through_sigtramp_breakpoint upon
|
||||||
# through_sigtramp_breakpoint upon return from the signal
|
# return from the signal handler.
|
||||||
# handler.
|
|
||||||
|
# SVR4 and Linux based i*86 systems exhibit this behaviour as
|
||||||
|
# well (it is uncovered by the `continue from a break in a
|
||||||
|
# signal handler' test below). As these systems use procfs,
|
||||||
|
# where we tell the kernel not to tell gdb about `pass'
|
||||||
|
# signals, and the trace flag is cleared by the kernel before
|
||||||
|
# entering the sigtramp routine, GDB will not notice the
|
||||||
|
# execution of the signal handler. Upon return from the
|
||||||
|
# signal handler, GDB will receive a SIGTRAP from the set
|
||||||
|
# trace flag in the restored context. The SIGTRAP marks the
|
||||||
|
# end of a (albeit long winded) single step for GDB, causing
|
||||||
|
# this test to pass.
|
||||||
|
|
||||||
# SVR4 and Linux based i*86 systems exhibit this behaviour
|
gdb_test "next" "alarm .*" "next to 2nd alarm"
|
||||||
# as well (it is uncovered by the `continue from a break
|
|
||||||
# in a signal handler' test below).
|
|
||||||
# As these systems use procfs, where we tell the kernel not
|
|
||||||
# to tell gdb about `pass' signals, and the trace flag is
|
|
||||||
# cleared by the kernel before entering the sigtramp
|
|
||||||
# routine, GDB will not notice the execution of the signal
|
|
||||||
# handler.
|
|
||||||
# Upon return from the signal handler, GDB will receive
|
|
||||||
# a SIGTRAP from the set trace flag in the restored context.
|
|
||||||
# The SIGTRAP marks the end of a (albeit long winded)
|
|
||||||
# single step for GDB, causing this test to pass.
|
|
||||||
|
|
||||||
fail "next to 2nd alarm (1) (probably kernel bug)"
|
|
||||||
gdb_test "next" "alarm.*" "next to 2nd alarm (1)"
|
|
||||||
}
|
|
||||||
-re "Program exited with code.*$gdb_prompt $" {
|
|
||||||
|
|
||||||
# This is apparently a bug in the UnixWare kernel (but
|
|
||||||
# has not been investigated beyond the
|
|
||||||
# resume/target_wait level, and has not been reported
|
|
||||||
# to Univel). If it steps when a signal is pending,
|
|
||||||
# it does a continue instead. I don't know whether
|
|
||||||
# there is a workaround.
|
|
||||||
|
|
||||||
# Perhaps this problem exists on other SVR4 systems;
|
|
||||||
# but (a) we have no reason to think so, and (b) if we
|
|
||||||
# put a wrong xfail here, we never get an XPASS to let
|
|
||||||
# us know that it was incorrect (and then if such a
|
|
||||||
# configuration regresses we have no way of knowing).
|
|
||||||
# Solaris is not a relevant data point either way
|
|
||||||
# because it lacks single stepping.
|
|
||||||
|
|
||||||
# fnf: I don't agree with the above philosophy. We
|
|
||||||
# can never be sure that any particular XFAIL is
|
|
||||||
# specified 100% correctly in that no systems with
|
|
||||||
# the bug are missed and all systems without the bug
|
|
||||||
# are excluded. If we include an XFAIL that isn't
|
|
||||||
# appropriate for a particular system, then when that
|
|
||||||
# system gets tested it will XPASS, and someone should
|
|
||||||
# investigate and fix the setup_xfail as appropriate,
|
|
||||||
# or more preferably, the actual bug. Each such case
|
|
||||||
# adds more data to narrowing down the scope of the
|
|
||||||
# problem and ultimately fixing it.
|
|
||||||
|
|
||||||
setup_xfail "i*86-*-sysv4*"
|
|
||||||
fail "'next' behaved as 'continue (known SVR4 bug)'"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
-re ".*$gdb_prompt $" { fail "next to 2nd alarm (1)" }
|
|
||||||
timeout { fail "next to 2nd alarm (1); (timeout)" }
|
|
||||||
eof { fail "next to 2nd alarm (1); (eof)" }
|
|
||||||
}
|
|
||||||
|
|
||||||
gdb_test "break handler" "Breakpoint \[0-9\]+ .*"
|
gdb_test "break handler" "Breakpoint \[0-9\]+ .*"
|
||||||
gdb_test "next" "\\+\\+count; /\\* second \\*/" \
|
gdb_test "next" "\\+\\+count; /\\* second \\*/" \
|
||||||
|
@ -191,41 +136,13 @@ proc signal_tests_1 {} {
|
||||||
gdb_test "break func1" "Breakpoint \[0-9\]+ .*"
|
gdb_test "break func1" "Breakpoint \[0-9\]+ .*"
|
||||||
gdb_test "break func2" "Breakpoint \[0-9\]+ .*"
|
gdb_test "break func2" "Breakpoint \[0-9\]+ .*"
|
||||||
|
|
||||||
# Vax Ultrix and i386 BSD currently fail the next test with
|
# NOTE: cagney/2004-05-09: Ref "next to 2nd alarm" above.
|
||||||
# a SIGTRAP, but with different symptoms.
|
# Because signal delivery when doing a next has been changed
|
||||||
setup_xfail "vax-*-ultrix*"
|
# to use a continue, and not a single-step, the kernel bug of
|
||||||
setup_xfail "i*86-*-bsd*"
|
# a stuck trace-bit in the trampoline's saved PS register is
|
||||||
setup_xfail "i*86-*-freebsd*"
|
# avoided.
|
||||||
setup_xfail "i*86-pc-linux-gnu*"
|
|
||||||
setup_xfail "i*86-*-solaris2*"
|
|
||||||
send_gdb "continue\n"
|
|
||||||
gdb_expect {
|
|
||||||
-re "Breakpoint.*func1.*$gdb_prompt $" { pass "continue to func1" }
|
|
||||||
-re "Program received signal SIGTRAP.*second.*$gdb_prompt $" {
|
|
||||||
|
|
||||||
# See explanation for `next to 2nd alarm (1)' fail above.
|
gdb_test "continue" "Breakpoint.*func1.*" "continue to func1"
|
||||||
# We did step into the signal handler, hit a breakpoint
|
|
||||||
# in the handler and continued from the breakpoint.
|
|
||||||
# The set trace flag in the restored context is causing
|
|
||||||
# the SIGTRAP, without stepping an instruction.
|
|
||||||
|
|
||||||
fail "continue to func1 (probably kernel bug)"
|
|
||||||
gdb_test "continue" "Breakpoint.*func1.*" \
|
|
||||||
"extra continue to func1"
|
|
||||||
}
|
|
||||||
-re "Program received signal SIGTRAP.*func1 ..;.*$gdb_prompt $" {
|
|
||||||
|
|
||||||
# On the vax under Ultrix the set trace flag in the restored
|
|
||||||
# context is causing the SIGTRAP, but after stepping one
|
|
||||||
# instruction, as expected.
|
|
||||||
|
|
||||||
fail "continue to func1 (probably kernel bug)"
|
|
||||||
gdb_test "continue" "Breakpoint.*func1.*" \
|
|
||||||
"extra continue to func1"
|
|
||||||
}
|
|
||||||
-re ".*$gdb_prompt $" { fail "continue to func1" }
|
|
||||||
default { fail "continue to func1" }
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_xfail "*-*-irix*"
|
setup_xfail "*-*-irix*"
|
||||||
send_gdb "signal SIGUSR1\n"
|
send_gdb "signal SIGUSR1\n"
|
||||||
|
|
Loading…
Reference in New Issue