summaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r--gdb/infrun.c74
1 files changed, 55 insertions, 19 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 594523f1716..d6075770ac6 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -46,7 +46,7 @@ static void sig_print_info (enum target_signal);
static void sig_print_header (void);
-static void resume_cleanups (int);
+static void resume_cleanups (void *);
static int hook_stop_stub (void *);
@@ -436,13 +436,13 @@ static int follow_vfork_when_exec;
static char *follow_fork_mode_kind_names[] =
{
-/* ??rehrauer: The "both" option is broken, by what may be a 10.20
- kernel problem. It's also not terribly useful without a GUI to
- help the user drive two debuggers. So for now, I'm disabling
- the "both" option.
- "parent", "child", "both", "ask" };
- */
- "parent", "child", "ask"};
+ /* ??rehrauer: The "both" option is broken, by what may be a 10.20
+ kernel problem. It's also not terribly useful without a GUI to
+ help the user drive two debuggers. So for now, I'm disabling the
+ "both" option. */
+ /* "parent", "child", "both", "ask" */
+ "parent", "child", "ask", NULL
+};
static char *follow_fork_mode_string = NULL;
@@ -752,7 +752,7 @@ static int singlestep_breakpoints_inserted_p = 0;
/* Things to clean up if we QUIT out of resume (). */
/* ARGSUSED */
static void
-resume_cleanups (int arg)
+resume_cleanups (void *ignore)
{
normal_stop ();
}
@@ -762,7 +762,12 @@ static char schedlock_on[] = "on";
static char schedlock_step[] = "step";
static char *scheduler_mode = schedlock_off;
static char *scheduler_enums[] =
-{schedlock_off, schedlock_on, schedlock_step};
+{
+ schedlock_off,
+ schedlock_on,
+ schedlock_step,
+ NULL
+};
static void
set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c)
@@ -791,8 +796,7 @@ void
resume (int step, enum target_signal sig)
{
int should_resume = 1;
- struct cleanup *old_cleanups = make_cleanup ((make_cleanup_func)
- resume_cleanups, 0);
+ struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
QUIT;
#ifdef CANNOT_STEP_BREAKPOINT
@@ -1044,9 +1048,11 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
int temp = insert_breakpoints ();
if (temp)
{
- print_sys_errmsg ("ptrace", temp);
+ print_sys_errmsg ("insert_breakpoints", temp);
error ("Cannot insert breakpoints.\n\
-The same program may be running in another process.");
+The same program may be running in another process,\n\
+or you may have requested too many hardware\n\
+breakpoints and/or watchpoints.\n");
}
breakpoints_inserted = 1;
@@ -2267,6 +2273,8 @@ handle_inferior_event (struct execution_control_state *ecs)
the HP-UX maintainer to furnish a fix that doesn't break other
platforms. --JimB, 20 May 1999 */
check_sigtramp2 (ecs);
+ keep_going (ecs);
+ return;
}
/* Handle cases caused by hitting a breakpoint. */
@@ -2738,6 +2746,20 @@ handle_inferior_event (struct execution_control_state *ecs)
if (step_over_calls > 0 || IGNORE_HELPER_CALL (stop_pc))
{
/* We're doing a "next". */
+
+ if (IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
+ && INNER_THAN (step_frame_address, read_sp()))
+ /* We stepped out of a signal handler, and into its
+ calling trampoline. This is misdetected as a
+ subroutine call, but stepping over the signal
+ trampoline isn't such a bad idea. In order to do
+ that, we have to ignore the value in
+ step_frame_address, since that doesn't represent the
+ frame that'll reach when we return from the signal
+ trampoline. Otherwise we'll probably continue to the
+ end of the program. */
+ step_frame_address = 0;
+
step_over_function (ecs);
keep_going (ecs);
return;
@@ -3038,7 +3060,7 @@ step_over_function (struct execution_control_state *ecs)
step_resume_breakpoint =
set_momentary_breakpoint (sr_sal, get_current_frame (), bp_step_resume);
- if (!IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
+ if (step_frame_address && !IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
step_resume_breakpoint->frame = step_frame_address;
if (breakpoints_inserted)
@@ -3383,9 +3405,11 @@ normal_stop (void)
if (breakpoints_failed)
{
target_terminal_ours_for_output ();
- print_sys_errmsg ("ptrace", breakpoints_failed);
+ print_sys_errmsg ("While inserting breakpoints", breakpoints_failed);
printf_filtered ("Stopped; cannot insert breakpoints.\n\
-The same program may be running in another process.\n");
+The same program may be running in another process,\n\
+or you may have requested too many hardware breakpoints\n\
+and/or watchpoints.\n");
}
if (target_has_execution && breakpoints_inserted)
@@ -4089,6 +4113,18 @@ restore_inferior_status (struct inferior_status *inf_status)
free_inferior_status (inf_status);
}
+static void
+do_restore_inferior_status_cleanup (void *sts)
+{
+ restore_inferior_status (sts);
+}
+
+struct cleanup *
+make_cleanup_restore_inferior_status (struct inferior_status *inf_status)
+{
+ return make_cleanup (do_restore_inferior_status_cleanup, inf_status);
+}
+
void
discard_inferior_status (struct inferior_status *inf_status)
{
@@ -4242,7 +4278,7 @@ to the user would be loading/unloading of a new library.\n",
c = add_set_enum_cmd ("follow-fork-mode",
class_run,
follow_fork_mode_kind_names,
- (char *) &follow_fork_mode_string,
+ &follow_fork_mode_string,
/* ??rehrauer: The "both" option is broken, by what may be a 10.20
kernel problem. It's also not terribly useful without a GUI to
help the user drive two debuggers. So for now, I'm disabling
@@ -4277,7 +4313,7 @@ By default, the debugger will follow the parent process.",
c = add_set_enum_cmd ("scheduler-locking", class_run,
scheduler_enums, /* array of string names */
- (char *) &scheduler_mode, /* current mode */
+ &scheduler_mode, /* current mode */
"Set mode for locking scheduler during execution.\n\
off == no locking (threads may preempt at any time)\n\
on == full locking (no thread except the current thread may run)\n\