linux_child_follow_fork (struct target_ops *ops, int follow_child)
{
sigset_t prev_mask;
- ptid_t last_ptid;
- struct target_waitstatus last_status;
int has_vforked;
int parent_pid, child_pid;
block_child_signals (&prev_mask);
- get_last_target_status (&last_ptid, &last_status);
- has_vforked = (last_status.kind == TARGET_WAITKIND_VFORKED);
- parent_pid = ptid_get_lwp (last_ptid);
+ has_vforked = (inferior_thread ()->pending_follow.kind
+ == TARGET_WAITKIND_VFORKED);
+ parent_pid = ptid_get_lwp (inferior_ptid);
if (parent_pid == 0)
- parent_pid = ptid_get_pid (last_ptid);
- child_pid = PIDGET (last_status.value.related_pid);
+ parent_pid = ptid_get_pid (inferior_ptid);
+ child_pid = PIDGET (inferior_thread ()->pending_follow.value.related_pid);
if (! follow_child)
{
/* Add process to GDB's tables. */
child_inf = add_inferior (child_pid);
- parent_inf = find_inferior_pid (GET_PID (last_ptid));
+ parent_inf = current_inferior ();
child_inf->attach_flag = parent_inf->attach_flag;
copy_terminal_info (child_inf, parent_inf);
}
else
{
- struct thread_info *last_tp = find_thread_pid (last_ptid);
struct thread_info *tp;
- char child_pid_spelling[40];
struct inferior *parent_inf, *child_inf;
- /* Copy user stepping state to the new inferior thread. */
- struct breakpoint *step_resume_breakpoint = last_tp->step_resume_breakpoint;
- CORE_ADDR step_range_start = last_tp->step_range_start;
- CORE_ADDR step_range_end = last_tp->step_range_end;
- struct frame_id step_frame_id = last_tp->step_frame_id;
-
- /* Otherwise, deleting the parent would get rid of this
- breakpoint. */
- last_tp->step_resume_breakpoint = NULL;
-
/* Before detaching from the parent, remove all breakpoints from it. */
remove_breakpoints ();
child_inf = add_inferior (child_pid);
- parent_inf = find_inferior_pid (GET_PID (last_ptid));
+ parent_inf = current_inferior ();
child_inf->attach_flag = parent_inf->attach_flag;
copy_terminal_info (child_inf, parent_inf);
linux_nat_switch_fork (inferior_ptid);
check_for_thread_db ();
-
- tp = inferior_thread ();
- tp->step_resume_breakpoint = step_resume_breakpoint;
- tp->step_range_start = step_range_start;
- tp->step_range_end = step_range_end;
- tp->step_frame_id = step_frame_id;
-
- /* Reset breakpoints in the child as appropriate. */
- follow_inferior_reset_breakpoints ();
}
restore_child_signals_mask (&prev_mask);
static void
exit_lwp (struct lwp_info *lp)
{
- struct thread_info *th = find_thread_pid (lp->ptid);
+ struct thread_info *th = find_thread_ptid (lp->ptid);
if (th)
{
char *exec_file, char *allargs, char **env,
int from_tty)
{
- int saved_async = 0;
#ifdef HAVE_PERSONALITY
int personality_orig = 0, personality_set = 0;
#endif /* HAVE_PERSONALITY */
/* The fork_child mechanism is synchronous and calls target_wait, so
we have to mask the async mode. */
- if (target_can_async_p ())
- /* Mask async mode. Creating a child requires a loop calling
- wait_for_inferior currently. */
- saved_async = linux_nat_async_mask (0);
-
#ifdef HAVE_PERSONALITY
if (disable_randomization)
{
safe_strerror (errno));
}
#endif /* HAVE_PERSONALITY */
-
- if (saved_async)
- linux_nat_async_mask (saved_async);
}
static void
have the last signal recorded in
thread_info->stop_signal. */
- struct thread_info *tp = find_thread_pid (lp->ptid);
+ struct thread_info *tp = find_thread_ptid (lp->ptid);
signo = tp->stop_signal;
}
{
if (GET_LWP (lp->ptid) == GET_LWP (last_ptid))
{
- struct thread_info *tp = find_thread_pid (lp->ptid);
+ struct thread_info *tp = find_thread_ptid (lp->ptid);
if (tp->stop_signal != TARGET_SIGNAL_0
&& signal_pass_state (tp->stop_signal))
*status = W_STOPCODE (target_signal_to_host (tp->stop_signal));
if (event == PTRACE_EVENT_EXEC)
{
+ if (debug_linux_nat)
+ fprintf_unfiltered (gdb_stdlog,
+ "LHEW: Got exec event from LWP %ld\n",
+ GET_LWP (lp->ptid));
+
ourstatus->kind = TARGET_WAITKIND_EXECD;
ourstatus->value.execd_pathname
= xstrdup (linux_child_pid_to_exec_file (pid));
static ptid_t
linux_nat_wait_1 (struct target_ops *ops,
- ptid_t ptid, struct target_waitstatus *ourstatus)
+ ptid_t ptid, struct target_waitstatus *ourstatus,
+ int target_options)
{
static sigset_t prev_mask;
struct lwp_info *lp = NULL;
set_sigint_trap ();
}
- if (target_can_async_p ())
- options |= WNOHANG; /* In async mode, don't block. */
+ /* Translate generic target_wait options into waitpid options. */
+ if (target_options & TARGET_WNOHANG)
+ options |= WNOHANG;
while (lp == NULL)
{
In sync mode, suspend waiting for a SIGCHLD signal. */
if (options & __WCLONE)
{
- if (target_can_async_p ())
+ if (target_options & TARGET_WNOHANG)
{
/* No interesting event. */
ourstatus->kind = TARGET_WAITKIND_IGNORE;
static ptid_t
linux_nat_wait (struct target_ops *ops,
- ptid_t ptid, struct target_waitstatus *ourstatus)
+ ptid_t ptid, struct target_waitstatus *ourstatus,
+ int target_options)
{
ptid_t event_ptid;
if (target_can_async_p ())
async_file_flush ();
- event_ptid = linux_nat_wait_1 (ops, ptid, ourstatus);
+ event_ptid = linux_nat_wait_1 (ops, ptid, ourstatus, target_options);
/* If we requested any event, and something came out, assume there
may be more. If we requested a specific lwp or process, also
return linux_xfer_siginfo (ops, object, annex, readbuf, writebuf,
offset, len);
+ /* The target is connected but no live inferior is selected. Pass
+ this request down to a lower stratum (e.g., the executable
+ file). */
+ if (object == TARGET_OBJECT_MEMORY && ptid_equal (inferior_ptid, null_ptid))
+ return 0;
+
old_chain = save_inferior_ptid ();
if (is_lwp (inferior_ptid))
cleanup = make_cleanup_fclose (procfile);
printf_filtered (_("Mapped address spaces:\n\n"));
- if (gdbarch_addr_bit (current_gdbarch) == 32)
+ if (gdbarch_addr_bit (target_gdbarch) == 32)
{
printf_filtered ("\t%10s %10s %10s %10s %7s\n",
"Start Addr",
a generic local_address_string instead to print out
the addresses; that makes sense to me, too. */
- if (gdbarch_addr_bit (current_gdbarch) == 32)
+ if (gdbarch_addr_bit (target_gdbarch) == 32)
{
printf_filtered ("\t%#10lx %#10lx %#10x %#10x %7s\n",
(unsigned long) addr, /* FIXME: pr_addr */
return;
}
- /* GDB should never give the terminal to the inferior, if the
- inferior is running in the background (run&, continue&, etc.).
- This check can be removed when the common code is fixed. */
- if (!sync_execution)
- return;
-
terminal_inferior ();
+ /* Calls to target_terminal_*() are meant to be idempotent. */
if (!async_terminal_is_ours)
return;
but claiming it sure should. */
terminal_ours ();
- if (!sync_execution)
- return;
-
if (async_terminal_is_ours)
return;
if (debug_linux_nat)
{
- if (find_thread_pid (lwp->ptid)->stop_requested)
+ if (find_thread_ptid (lwp->ptid)->stop_requested)
fprintf_unfiltered (gdb_stdlog, "\
LNSL: already stopped/stop_requested %s\n",
target_pid_to_str (lwp->ptid));