process.
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ 2008 Free Software Foundation, Inc.
This file is part of GDB.
static ptid_t previous_inferior_ptid;
-/* This is true for configurations that may follow through execl() and
- similar functions. At present this is only true for HP-UX native. */
-
-#ifndef MAY_FOLLOW_EXEC
-#define MAY_FOLLOW_EXEC (0)
-#endif
-
-static int may_follow_exec = MAY_FOLLOW_EXEC;
-
static int debug_infrun = 0;
static void
show_debug_infrun (struct ui_file *file, int from_tty,
int saved_pid = pid;
struct target_ops *tgt;
- if (!may_follow_exec)
- return;
-
/* This is an exec event that we actually wish to pay attention to.
Refresh our symbol table to the newly exec'd program, remove any
momentary bp's, etc.
/* We've followed the inferior through an exec. Therefore, the
inferior has essentially been killed & reborn. */
- /* First collect the run target in effect. */
- tgt = find_run_target ();
- /* If we can't find one, things are in a very strange state... */
- if (tgt == NULL)
- error (_("Could find run target to save before following exec"));
-
gdb_flush (gdb_stdout);
- target_mourn_inferior ();
- inferior_ptid = pid_to_ptid (saved_pid);
+ generic_mourn_inferior ();
/* Because mourn_inferior resets inferior_ptid. */
- push_target (tgt);
+ inferior_ptid = pid_to_ptid (saved_pid);
+
+ if (gdb_sysroot && *gdb_sysroot)
+ {
+ char *name = alloca (strlen (gdb_sysroot)
+ + strlen (execd_pathname)
+ + 1);
+ strcpy (name, gdb_sysroot);
+ strcat (name, execd_pathname);
+ execd_pathname = name;
+ }
/* That a.out is now the one to use. */
exec_file_attach (execd_pathname, 0);
/* Reset the shared library package. This ensures that we get
a shlib event when the child reaches "_start", at which point
the dld will have had a chance to initialize the child. */
-#if defined(SOLIB_RESTART)
- SOLIB_RESTART ();
-#endif
+ no_shared_libraries (NULL, 0);
#ifdef SOLIB_CREATE_INFERIOR_HOOK
SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
#else
does not support asynchronous execution. */
if (!target_can_async_p ())
{
- wait_for_inferior ();
+ wait_for_inferior (0);
normal_stop ();
}
}
target_open() return to the caller an indication that the target
is currently running and GDB state should be set to the same as
for an async run. */
- wait_for_inferior ();
+ wait_for_inferior (0);
/* Now that the inferior has stopped, do any bookkeeping like
loading shared libraries. We want to do this before normal_stop,
int stop_info);
/* Wait for control to return from inferior to debugger.
+
+ If TREAT_EXEC_AS_SIGTRAP is non-zero, then handle EXEC signals
+ as if they were SIGTRAP signals. This can be useful during
+ the startup sequence on some targets such as HP/UX, where
+ we receive an EXEC event instead of the expected SIGTRAP.
+
If inferior gets a signal, we may decide to start it up again
instead of returning. That is why there is a loop in this function.
When this function actually returns it means the inferior
should be left stopped and GDB should read more commands. */
void
-wait_for_inferior (void)
+wait_for_inferior (int treat_exec_as_sigtrap)
{
struct cleanup *old_cleanups;
struct execution_control_state ecss;
struct execution_control_state *ecs;
if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: wait_for_inferior\n");
+ fprintf_unfiltered
+ (gdb_stdlog, "infrun: wait_for_inferior (treat_exec_as_sigtrap=%d)\n",
+ treat_exec_as_sigtrap);
old_cleanups = make_cleanup (delete_step_resume_breakpoint,
&step_resume_breakpoint);
else
ecs->ptid = target_wait (ecs->waiton_ptid, ecs->wp);
+ if (treat_exec_as_sigtrap && ecs->ws.kind == TARGET_WAITKIND_EXECD)
+ {
+ xfree (ecs->ws.value.execd_pathname);
+ ecs->ws.kind = TARGET_WAITKIND_STOPPED;
+ ecs->ws.value.sig = TARGET_SIGNAL_TRAP;
+ }
+
/* Now figure out what to do with the result of the result. */
handle_inferior_event (ecs);
if (ecs->ws.kind != TARGET_WAITKIND_EXITED
&& ecs->ws.kind != TARGET_WAITKIND_SIGNALLED && ecs->new_thread_event)
- {
- add_thread (ecs->ptid);
-
- ui_out_text (uiout, "[New ");
- ui_out_text (uiout, target_pid_or_tid_to_str (ecs->ptid));
- ui_out_text (uiout, "]\n");
- }
+ add_thread (ecs->ptid);
switch (ecs->ws.kind)
{
process until the child exits (well, okay, not
then either :-) or execs. */
if (remove_status != 0)
- {
- /* FIXME! This is obviously non-portable! */
- write_pc_pid (stop_pc + 4, ecs->ptid);
- /* We need to restart all the threads now,
- * unles we're running in scheduler-locked mode.
- * Use currently_stepping to determine whether to
- * step or continue.
- */
- /* FIXME MVS: is there any reason not to call resume()? */
- if (scheduler_mode == schedlock_on)
- target_resume (ecs->ptid,
- currently_stepping (ecs), TARGET_SIGNAL_0);
- else
- target_resume (RESUME_ALL,
- currently_stepping (ecs), TARGET_SIGNAL_0);
- prepare_to_wait (ecs);
- return;
- }
+ error (_("Cannot step over breakpoint hit in wrong thread"));
else
{ /* Single step */
if (!ptid_equal (inferior_ptid, ecs->ptid))
&& gdbarch_single_step_through_delay_p (current_gdbarch)
&& currently_stepping (ecs))
{
- /* We're trying to step of a breakpoint. Turns out that we're
+ /* We're trying to step off a breakpoint. Turns out that we're
also on an instruction that needs to be stepped multiple
times before it's been fully executing. E.g., architectures
with a delay slot. It needs to be stepped twice, once for
new line in mid-statement, we continue stepping. This makes
things like for(;;) statements work better.) */
- if (ecs->stop_func_end && ecs->sal.end >= ecs->stop_func_end)
- {
- /* If this is the last line of the function, don't keep stepping
- (it would probably step us out of the function).
- This is particularly necessary for a one-line function,
- in which after skipping the prologue we better stop even though
- we will be in mid-line. */
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: stepped to a different function\n");
- stop_step = 1;
- print_stop_reason (END_STEPPING_RANGE, 0);
- stop_stepping (ecs);
- return;
- }
step_range_start = ecs->sal.pc;
step_range_end = ecs->sal.end;
step_frame_id = get_frame_id (get_current_frame ());
{
target_terminal_ours_for_output ();
printf_filtered (_("[Switching to %s]\n"),
- target_pid_or_tid_to_str (inferior_ptid));
+ target_pid_to_str (inferior_ptid));
previous_inferior_ptid = inferior_ptid;
}