/* Prototypes for local functions */
-static void signals_info PARAMS ((char *, int));
+static void signals_info (char *, int);
-static void handle_command PARAMS ((char *, int));
+static void handle_command (char *, int);
-static void sig_print_info PARAMS ((enum target_signal));
+static void sig_print_info (enum target_signal);
-static void sig_print_header PARAMS ((void));
+static void sig_print_header (void);
-static void resume_cleanups PARAMS ((int));
+static void resume_cleanups (int);
-static int hook_stop_stub PARAMS ((PTR));
+static int hook_stop_stub (void *);
-static void delete_breakpoint_current_contents PARAMS ((PTR));
+static void delete_breakpoint_current_contents (void *);
-static void set_follow_fork_mode_command PARAMS ((char *arg, int from_tty, struct cmd_list_element * c));
+static void set_follow_fork_mode_command (char *arg, int from_tty,
+ struct cmd_list_element * c);
-static void complete_execution PARAMS ((void));
+static void complete_execution (void);
+
+static struct inferior_status *xmalloc_inferior_status (void);
+
+static void free_inferior_status (struct inferior_status *);
+
+static int restore_selected_frame (void *);
+
+static void build_infrun (void);
+
+static void follow_inferior_fork (int parent_pid, int child_pid,
+ int has_forked, int has_vforked);
+
+static void follow_fork (int parent_pid, int child_pid);
+
+static void follow_vfork (int parent_pid, int child_pid);
+
+static void set_schedlock_func (char *args, int from_tty,
+ struct cmd_list_element * c);
+
+static int is_internal_shlib_eventpoint (struct breakpoint * ep);
+
+static int stopped_for_internal_shlib_event (bpstat bs);
+
+struct execution_control_state;
+
+static int currently_stepping (struct execution_control_state *ecs);
+
+static void xdb_handle_command (char *args, int from_tty);
+
+void _initialize_infrun (void);
int inferior_ignoring_startup_exec_events = 0;
int inferior_ignoring_leading_exec_events = 0;
/* In asynchronous mode, but simulating synchronous execution. */
+
int sync_execution = 0;
/* wait_for_inferior and normal_stop use this to notify the user
when the inferior stopped in a different thread than it had been
- running in. */
+ running in. */
+
static int switched_from_inferior_pid;
/* This will be true for configurations that may actually report an
Versions of gdb which don't use the "step == this thread steps
and others continue" model but instead use the "step == this
- thread steps and others wait" shouldn't do this. */
+ thread steps and others wait" shouldn't do this. */
+
static int thread_step_needed = 0;
/* This is true if thread_step_needed should actually be used. At
static int use_thread_step_needed = USE_THREAD_STEP_NEEDED;
-static void follow_inferior_fork PARAMS ((int parent_pid,
- int child_pid,
- int has_forked,
- int has_vforked));
-
-static void follow_fork PARAMS ((int parent_pid, int child_pid));
-
-static void follow_vfork PARAMS ((int parent_pid, int child_pid));
-
-static void set_schedlock_func PARAMS ((char *args, int from_tty,
- struct cmd_list_element * c));
-
-static int is_internal_shlib_eventpoint PARAMS ((struct breakpoint * ep));
-
-static int stopped_for_internal_shlib_event PARAMS ((bpstat bs));
-
-static int stopped_for_shlib_catchpoint PARAMS ((bpstat bs,
- struct breakpoint ** cp_p));
-
-#if __STDC__
-struct execution_control_state;
-#endif
-static int currently_stepping PARAMS ((struct execution_control_state * ecs));
-
-static void xdb_handle_command PARAMS ((char *args, int from_tty));
-
-void _initialize_infrun PARAMS ((void));
-
/* GET_LONGJMP_TARGET returns the PC at which longjmp() will resume the
program. It needs to examine the jmp_buf argument and extract the PC
from it. The return value is non-zero on success, zero otherwise. */
\f
static void
-follow_inferior_fork (parent_pid, child_pid, has_forked, has_vforked)
- int parent_pid;
- int child_pid;
- int has_forked;
- int has_vforked;
+follow_inferior_fork (int parent_pid, int child_pid, int has_forked,
+ int has_vforked)
{
int followed_parent = 0;
int followed_child = 0;
- int ima_clone = 0;
/* Which process did the user want us to follow? */
char *follow_mode =
- savestring (follow_fork_mode_string, strlen (follow_fork_mode_string));
+ savestring (follow_fork_mode_string, strlen (follow_fork_mode_string));
/* Or, did the user not know, and want us to ask? */
if (STREQ (follow_fork_mode_string, "ask"))
}
static void
-follow_fork (parent_pid, child_pid)
- int parent_pid;
- int child_pid;
+follow_fork (int parent_pid, int child_pid)
{
follow_inferior_fork (parent_pid, child_pid, 1, 0);
}
/* Forward declaration. */
-static void follow_exec PARAMS ((int, char *));
+static void follow_exec (int, char *);
static void
-follow_vfork (parent_pid, child_pid)
- int parent_pid;
- int child_pid;
+follow_vfork (int parent_pid, int child_pid)
{
follow_inferior_fork (parent_pid, child_pid, 0, 1);
}
static void
-follow_exec (pid, execd_pathname)
- int pid;
- char *execd_pathname;
+follow_exec (int pid, char *execd_pathname)
{
int saved_pid = pid;
struct target_ops *tgt;
/* Things to clean up if we QUIT out of resume (). */
/* ARGSUSED */
static void
-resume_cleanups (arg)
- int arg;
+resume_cleanups (int arg)
{
normal_stop ();
}
{schedlock_off, schedlock_on, schedlock_step};
static void
-set_schedlock_func (args, from_tty, c)
- char *args;
- int from_tty;
- struct cmd_list_element *c;
+set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c)
{
if (c->type == set_cmd)
if (!target_can_lock_scheduler)
STEP nonzero if we should step (zero to continue instead).
SIG is the signal to give the inferior (zero for none). */
void
-resume (step, sig)
- int step;
- enum target_signal sig;
+resume (int step, enum target_signal sig)
{
int should_resume = 1;
struct cleanup *old_cleanups = make_cleanup ((make_cleanup_func)
First do this, then set the ones you want, then call `proceed'. */
void
-clear_proceed_status ()
+clear_proceed_status (void)
{
trap_expected = 0;
step_range_start = 0;
You should call clear_proceed_status before calling proceed. */
void
-proceed (addr, siggnal, step)
- CORE_ADDR addr;
- enum target_signal siggnal;
- int step;
+proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
{
int oneproc = 0;
\f
/* Start remote-debugging of a machine over a serial link. */
+
void
-start_remote ()
+start_remote (void)
{
init_thread_list ();
init_wait_for_inferior ();
/* Initialize static vars when a new inferior begins. */
void
-init_wait_for_inferior ()
+init_wait_for_inferior (void)
{
/* These are meaningless until the first time through wait_for_inferior. */
prev_pc = 0;
}
static void
-delete_breakpoint_current_contents (arg)
- PTR arg;
+delete_breakpoint_current_contents (void *arg)
{
struct breakpoint **breakpointp = (struct breakpoint **) arg;
if (*breakpointp != NULL)
int wait_some_more;
};
-void init_execution_control_state PARAMS ((struct execution_control_state * ecs));
+void init_execution_control_state (struct execution_control_state * ecs);
-void handle_inferior_event PARAMS ((struct execution_control_state * ecs));
+void handle_inferior_event (struct execution_control_state * ecs);
/* Wait for control to return from inferior to debugger.
If inferior gets a signal, we may decide to start it up again
should be left stopped and GDB should read more commands. */
void
-wait_for_inferior ()
+wait_for_inferior (void)
{
struct cleanup *old_cleanups;
struct execution_control_state ecss;
struct execution_control_state *async_ecs;
void
-fetch_inferior_event ()
+fetch_inferior_event (void)
{
static struct cleanup *old_cleanups;
wait_for_inferior-type loop. */
void
-init_execution_control_state (ecs)
- struct execution_control_state *ecs;
+init_execution_control_state (struct execution_control_state *ecs)
{
ecs->random_signal = 0;
ecs->remove_breakpoints_on_following_step = 0;
ecs->wp = &(ecs->ws);
}
+/* Call this function before setting step_resume_breakpoint, as a
+ sanity check. There should never be more than one step-resume
+ breakpoint per thread, so we should never be setting a new
+ step_resume_breakpoint when one is already active. */
+static void
+check_for_old_step_resume_breakpoint (void)
+{
+ if (step_resume_breakpoint)
+ warning ("GDB bug: infrun.c (wait_for_inferior): dropping old step_resume breakpoint");
+}
+
/* Given an execution control state that has been freshly filled in
by an event from the inferior, figure out what it means and take
appropriate action. */
void
-handle_inferior_event (ecs)
- struct execution_control_state *ecs;
+handle_inferior_event (struct execution_control_state *ecs)
{
CORE_ADDR tmp;
int stepped_after_stopped_by_watchpoint;
inferior_ignoring_leading_exec_events =
target_reported_exec_events_per_exec_call () - 1;
- pending_follow.execd_pathname = savestring (ecs->ws.value.execd_pathname,
- strlen (ecs->ws.value.execd_pathname));
+ pending_follow.execd_pathname =
+ savestring (ecs->ws.value.execd_pathname,
+ strlen (ecs->ws.value.execd_pathname));
/* Did inferior_pid exec, or did a (possibly not-yet-followed)
child of a vfork exec?
if (signal_program[stop_signal] == 0)
stop_signal = TARGET_SIGNAL_0;
- /* If we're in the middle of a "next" command, let the code for
- stepping over a function handle this. pai/1997-09-10
-
- A previous comment here suggested it was possible to change
- this to jump to keep_going in all cases. */
-
- if (step_over_calls > 0)
- goto step_over_function;
- else
- goto check_sigtramp2;
+ /* I'm not sure whether this needs to be check_sigtramp2 or
+ whether it could/should be keep_going.
+
+ This used to jump to step_over_function if we are stepping,
+ which is wrong.
+
+ Suppose the user does a `next' over a function call, and while
+ 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 jump to 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 */
+ goto check_sigtramp2;
}
/* Handle cases caused by hitting a breakpoint. */
If we reach here and step_resume_breakpoint is already
NULL, then apparently we have multiple active
step-resume bp's. We'll just delete the breakpoint we
- stopped at, and carry on. */
+ stopped at, and carry on.
+
+ Correction: what the code currently does is delete a
+ step-resume bp, but it makes no effort to ensure that
+ the one deleted is the one currently stopped at. MVS */
+
if (step_resume_breakpoint == NULL)
{
step_resume_breakpoint =
/* We could probably be setting the frame to
step_frame_address; I don't think anyone thought to
try it. */
+ check_for_old_step_resume_breakpoint ();
step_resume_breakpoint =
set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
if (breakpoints_inserted)
INIT_SAL (&xxx); /* initialize to zeroes */
xxx.pc = tmp;
xxx.section = find_pc_overlay (xxx.pc);
+ check_for_old_step_resume_breakpoint ();
step_resume_breakpoint =
set_momentary_breakpoint (xxx, NULL, bp_step_resume);
insert_breakpoints ();
step_over_function:
/* A subroutine call has happened. */
{
- /* Set a special breakpoint after the return */
- struct symtab_and_line sr_sal;
+ /* 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 address will catch a return from the callee.
+
+ However, if the callee is recursing, we want to be careful
+ not to catch returns of those recursive calls, but only of
+ THIS instance of the call.
- INIT_SAL (&sr_sal);
- sr_sal.symtab = NULL;
- sr_sal.line = 0;
+ To do this, we set the step_resume bp's frame to our current
+ caller's frame (step_frame_address, which is set by the "next"
+ or "until" command, before execution begins). */
+ struct symtab_and_line sr_sal;
- /* If we came here after encountering a signal in the middle of
- a "next", use the stashed-away previous frame pc */
- sr_sal.pc
- = stopped_by_random_signal
- ? prev_pc
- : ADDR_BITS_REMOVE (SAVED_PC_AFTER_CALL (get_current_frame ()));
+ INIT_SAL (&sr_sal); /* initialize to zeros */
+ sr_sal.pc =
+ ADDR_BITS_REMOVE (SAVED_PC_AFTER_CALL (get_current_frame ()));
+ sr_sal.section = find_pc_overlay (sr_sal.pc);
+ check_for_old_step_resume_breakpoint ();
step_resume_breakpoint =
- set_momentary_breakpoint (sr_sal,
- stopped_by_random_signal ?
- NULL : get_current_frame (),
+ set_momentary_breakpoint (sr_sal, get_current_frame (),
bp_step_resume);
- /* We've just entered a callee, and we wish to resume until
- it returns to the caller. Setting a step_resume bp on
- the return PC will catch a return from the callee.
-
- However, if the callee is recursing, we want to be
- careful not to catch returns of those recursive calls,
- but of THIS instance of the call.
-
- To do this, we set the step_resume bp's frame to our
- current caller's frame (step_frame_address, which is
- set by the "next" or "until" command, before execution
- begins).
-
- But ... don't do it if we're single-stepping out of a
- sigtramp, because the reason we're single-stepping is
- precisely because unwinding is a problem (HP-UX 10.20,
- e.g.) and the frame address is likely to be incorrect.
- No danger of sigtramp recursion. */
-
- if (ecs->stepping_through_sigtramp)
- {
- step_resume_breakpoint->frame = (CORE_ADDR) NULL;
- ecs->stepping_through_sigtramp = 0;
- }
- else if (!IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
+ if (!IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
step_resume_breakpoint->frame = step_frame_address;
if (breakpoints_inserted)
/* Do not specify what the fp should be when we stop
since on some machines the prologue
is where the new fp value is established. */
+ check_for_old_step_resume_breakpoint ();
step_resume_breakpoint =
set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
if (breakpoints_inserted)
/* Do not specify what the fp should be when we stop
since on some machines the prologue
is where the new fp value is established. */
+ check_for_old_step_resume_breakpoint ();
step_resume_breakpoint =
set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
if (breakpoints_inserted)
/* Are we in the middle of stepping? */
static int
-currently_stepping (ecs)
- struct execution_control_state *ecs;
+currently_stepping (struct execution_control_state *ecs)
{
return ((through_sigtramp_breakpoint == NULL
&& !ecs->handling_longjmp
something gdb sets for its own use, and isn't ever shown to a
user.) */
static int
-is_internal_shlib_eventpoint (ep)
- struct breakpoint *ep;
+is_internal_shlib_eventpoint (struct breakpoint *ep)
{
return
(ep->type == bp_shlib_event)
/* This function returns TRUE if bs indicates that the inferior
stopped due to a shared library (aka dynamically-linked library)
event. */
+
static int
-stopped_for_internal_shlib_event (bs)
- bpstat bs;
+stopped_for_internal_shlib_event (bpstat bs)
{
/* Note that multiple eventpoints may've caused the stop. Any
that are associated with shlib events will be accepted. */
/* If we get here, then no candidate was found. */
return 0;
}
-
-/* This function returns TRUE if bs indicates that the inferior
- stopped due to a shared library (aka dynamically-linked library)
- event caught by a catchpoint.
-
- If TRUE, cp_p is set to point to the catchpoint.
-
- Else, the value of cp_p is undefined. */
-static int
-stopped_for_shlib_catchpoint (bs, cp_p)
- bpstat bs;
- struct breakpoint **cp_p;
-{
- /* Note that multiple eventpoints may've caused the stop. Any
- that are associated with shlib events will be accepted. */
- *cp_p = NULL;
-
- for (; bs != NULL; bs = bs->next)
- {
- if ((bs->breakpoint_at != NULL)
- && ep_is_shlib_catchpoint (bs->breakpoint_at))
- {
- *cp_p = bs->breakpoint_at;
- return 1;
- }
- }
-
- /* If we get here, then no candidate was found. */
- return 0;
-}
\f
-
/* Reset proper settings after an asynchronous command has finished.
If the execution command was in synchronous mode, register stdin
with the event loop, and reset the prompt. */
+
static void
-complete_execution ()
+complete_execution (void)
{
- extern cleanup_sigint_signal_handler PARAMS ((void));
+ extern int cleanup_sigint_signal_handler (void);
target_executing = 0;
if (sync_execution)
{
- add_file_handler (input_fd, (file_handler_func *) call_readline, 0);
+ add_file_handler (input_fd, call_readline, 0);
pop_prompt ();
sync_execution = 0;
cleanup_sigint_signal_handler ();
attempting to insert breakpoints. */
void
-normal_stop ()
+normal_stop (void)
{
/* As with the notification of thread events, we want to delay
notifying the user that we've switched thread context until
}
static int
-hook_stop_stub (cmd)
- PTR cmd;
+hook_stop_stub (void *cmd)
{
execute_user_command ((struct cmd_list_element *) cmd, 0);
return (0);
}
\f
int
-signal_stop_state (signo)
- int signo;
+signal_stop_state (int signo)
{
return signal_stop[signo];
}
int
-signal_print_state (signo)
- int signo;
+signal_print_state (int signo)
{
return signal_print[signo];
}
int
-signal_pass_state (signo)
- int signo;
+signal_pass_state (int signo)
{
return signal_program[signo];
}
static void
-sig_print_header ()
+sig_print_header (void)
{
printf_filtered ("\
Signal Stop\tPrint\tPass to program\tDescription\n");
}
static void
-sig_print_info (oursig)
- enum target_signal oursig;
+sig_print_info (enum target_signal oursig)
{
char *name = target_signal_to_name (oursig);
int name_padding = 13 - strlen (name);
+
if (name_padding <= 0)
name_padding = 0;
/* Specify how various signals in the inferior should be handled. */
static void
-handle_command (args, from_tty)
- char *args;
- int from_tty;
+handle_command (char *args, int from_tty)
{
char **argv;
int digits, wordlen;
}
static void
-xdb_handle_command (args, from_tty)
- char *args;
- int from_tty;
+xdb_handle_command (char *args, int from_tty)
{
char **argv;
struct cleanup *old_chain;
targets, all signals should be in the signal tables). */
static void
-signals_info (signum_exp, from_tty)
- char *signum_exp;
- int from_tty;
+signals_info (char *signum_exp, int from_tty)
{
enum target_signal oursig;
sig_print_header ();
int proceed_to_finish;
};
-
-static struct inferior_status *xmalloc_inferior_status PARAMS ((void));
static struct inferior_status *
-xmalloc_inferior_status ()
+xmalloc_inferior_status (void)
{
struct inferior_status *inf_status;
inf_status = xmalloc (sizeof (struct inferior_status));
return inf_status;
}
-static void free_inferior_status PARAMS ((struct inferior_status *));
static void
-free_inferior_status (inf_status)
- struct inferior_status *inf_status;
+free_inferior_status (struct inferior_status *inf_status)
{
free (inf_status->registers);
free (inf_status->stop_registers);
}
void
-write_inferior_status_register (inf_status, regno, val)
- struct inferior_status *inf_status;
- int regno;
- LONGEST val;
+write_inferior_status_register (struct inferior_status *inf_status, int regno,
+ LONGEST val)
{
int size = REGISTER_RAW_SIZE (regno);
void *buf = alloca (size);
memcpy (&inf_status->registers[REGISTER_BYTE (regno)], buf, size);
}
-
-
/* Save all of the information associated with the inferior<==>gdb
connection. INF_STATUS is a pointer to a "struct inferior_status"
(defined in inferior.h). */
struct inferior_status *
-save_inferior_status (restore_stack_info)
- int restore_stack_info;
+save_inferior_status (int restore_stack_info)
{
struct inferior_status *inf_status = xmalloc_inferior_status ();
int level;
};
-static int restore_selected_frame PARAMS ((PTR));
-
static int
-restore_selected_frame (args)
- PTR args;
+restore_selected_frame (void *args)
{
struct restore_selected_frame_args *fr =
(struct restore_selected_frame_args *) args;
}
void
-restore_inferior_status (inf_status)
- struct inferior_status *inf_status;
+restore_inferior_status (struct inferior_status *inf_status)
{
stop_signal = inf_status->stop_signal;
stop_pc = inf_status->stop_pc;
}
void
-discard_inferior_status (inf_status)
- struct inferior_status *inf_status;
+discard_inferior_status (struct inferior_status *inf_status)
{
/* See save_inferior_status for info on stop_bpstat. */
bpstat_clear (&inf_status->stop_bpstat);
}
static void
-set_follow_fork_mode_command (arg, from_tty, c)
- char *arg;
- int from_tty;
- struct cmd_list_element *c;
+set_follow_fork_mode_command (char *arg, int from_tty,
+ struct cmd_list_element *c)
{
if (!STREQ (arg, "parent") &&
!STREQ (arg, "child") &&
follow_fork_mode_string = savestring (arg, strlen (arg));
}
\f
-
-
-static void build_infrun PARAMS ((void));
static void
-build_infrun ()
+build_infrun (void)
{
stop_registers = xmalloc (REGISTER_BYTES);
}
-
void
-_initialize_infrun ()
+_initialize_infrun (void)
{
register int i;
register int numsigs;