detach work asynchronously.
* inf-ptrace.c (inf_ptrace_attach): Ditto.
* infcmd.c (attach_command): Ditto.
* inf-child.c (inf_child_target): Reset to_terminal_inferior/
to_terminal_ours to synchronous methods.
* async-nat-inferior.c (gdb_process_events): Don't poll for
exceptions.
(gdb_process_pending_event): Use pid_to_ptid.
(gdb_inferior_reset): Remove last_thread component.
* async-nat-inferior.h (struct gdb_inferior_status): Remove
last_thread component.
static void gdb_inferior_destroy (gdb_inferior_status *s);
-static void gdb_handle_signal (gdb_signal_thread_message *msg,
- struct target_waitstatus *status)
+static void
+gdb_handle_signal (gdb_signal_thread_message *msg,
+ struct target_waitstatus *status)
{
//CHECK_FATAL (gdb_status != NULL);
gdb_add_to_pending_events (source, buf);
}
- for (;;)
- {
- source = gdb_fetch_event (inferior, buf, sizeof (buf),
- NEXT_SOURCE_ALL, 0);
- if (source == NEXT_SOURCE_NONE)
- {
- break;
- }
- else
- {
- event_count++;
-
- /* Stuff the remaining events onto the pending_events queue.
- These will be dispatched when we run again. */
- /* PENDING_EVENTS */
- gdb_add_to_pending_events (source, buf);
- }
- }
-
- /*inferior_debug (2,
- "gdb_process_events: returning with (status->kind == %d)\n",
- status->kind); */
return event_count;
}
//inferior_debug (1, "Processing pending event type: %d\n", event->type);
gdb_service_event (event->type, (unsigned char *) event->buf, status);
- return ptid_build (gdb_status->pid, 0, gdb_status->last_thread);
+ return pid_to_ptid (gdb_status->pid);
}
void
s->suspend_count = 0;
- s->last_thread = 0;
-
gdb_signal_thread_init (&s->signal_status);
}
unsigned int suspend_count;
- int last_thread;
-
gdb_signal_thread_status signal_status;
};
typedef struct gdb_inferior_status gdb_inferior_status;
t->to_insert_breakpoint = memory_insert_breakpoint;
t->to_remove_breakpoint = memory_remove_breakpoint;
t->to_terminal_init = terminal_init_inferior;
- t->to_terminal_inferior = async_terminal_inferior;
+ t->to_terminal_inferior = terminal_inferior;
t->to_terminal_ours_for_output = terminal_ours_for_output;
t->to_terminal_save_ours = terminal_save_ours;
- t->to_terminal_ours = async_terminal_ours;
+ t->to_terminal_ours = terminal_ours;
t->to_terminal_info = child_terminal_info;
t->to_post_startup_inferior = inf_child_post_startup_inferior;
t->to_acknowledge_created_inferior = inf_child_acknowledge_created_inferior;
gdb_flush (gdb_stdout);
}
+ if (target_can_async_p ())
+ gdb_create_inferior (gdb_status, pid);
+
+
#ifdef PT_ATTACH
errno = 0;
ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
error (_("This system does not support attaching to a process"));
#endif
+ if (target_can_async_p ())
+ {
+ gdb_status->attached_in_ptrace = 1;
+ gdb_status->stopped_in_ptrace = 0;
+ gdb_status->stopped_in_softexc = 0;
+
+ gdb_status->suspend_count = 0;
+ }
+
inferior_ptid = pid_to_ptid (pid);
push_target (ptrace_ops_hack);
+
+ if (target_can_async_p () && gdb_status->attached_in_ptrace)
+ {
+ gdb_signal_thread_create (&gdb_status->signal_status, pid);
+ stop_soon = STOP_QUIETLY;
+ wait_for_inferior ();
+ }
}
#ifdef PT_GET_PROCESS_STATE
don't ignore SIGSTOPs on continue requests anymore. We need a
way for handle_inferior_event to reset the stop_signal variable
after an attach, and this is what STOP_QUIETLY_NO_SIGSTOP is for. */
- stop_soon = STOP_QUIETLY_NO_SIGSTOP;
- wait_for_inferior ();
- stop_soon = NO_STOP_QUIETLY;
+ if (!target_can_async_p ())
+ {
+ stop_soon = STOP_QUIETLY_NO_SIGSTOP;
+ wait_for_inferior ();
+ stop_soon = NO_STOP_QUIETLY;
+ }
#endif
/*
attach all of them. */
linux_ops->to_attach (args, from_tty);
- /* Add the initial process as the first LWP to the list. */
- inferior_ptid = BUILD_LWP (GET_PID (inferior_ptid), GET_PID (inferior_ptid));
- lp = add_lwp (inferior_ptid);
-
- /* Make sure the initial process is stopped. The user-level threads
- layer might want to poke around in the inferior, and that won't
- work if things haven't stabilized yet. */
- pid = my_waitpid (GET_PID (inferior_ptid), &status, 0);
- if (pid == -1 && errno == ECHILD)
+ if (!target_can_async_p ())
{
- warning (_("%s is a cloned process"), target_pid_to_str (inferior_ptid));
+ /* Add the initial process as the first LWP to the list. */
+ inferior_ptid = BUILD_LWP (GET_PID (inferior_ptid), GET_PID (inferior_ptid));
+ lp = add_lwp (inferior_ptid);
+
+ /* Make sure the initial process is stopped. The user-level threads
+ layer might want to poke around in the inferior, and that won't
+ work if things haven't stabilized yet. */
+ pid = my_waitpid (GET_PID (inferior_ptid), &status, 0);
+ if (pid == -1 && errno == ECHILD)
+ {
+ warning (_("%s is a cloned process"), target_pid_to_str (inferior_ptid));
- /* Try again with __WCLONE to check cloned processes. */
- pid = my_waitpid (GET_PID (inferior_ptid), &status, __WCLONE);
- lp->cloned = 1;
- }
+ /* Try again with __WCLONE to check cloned processes. */
+ pid = my_waitpid (GET_PID (inferior_ptid), &status, __WCLONE);
+ lp->cloned = 1;
+ }
- gdb_assert (pid == GET_PID (inferior_ptid)
- && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP);
+ gdb_assert (pid == GET_PID (inferior_ptid)
+ && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP);
- lp->stopped = 1;
+ lp->stopped = 1;
- /* Fake the SIGSTOP that core GDB expects. */
- lp->status = W_STOPCODE (SIGSTOP);
- lp->resumed = 1;
- if (debug_linux_nat)
- {
- fprintf_unfiltered (gdb_stdlog,
- "LLA: waitpid %ld, faking SIGSTOP\n", (long) pid);
+ /* Fake the SIGSTOP that core GDB expects. */
+ lp->status = W_STOPCODE (SIGSTOP);
+ lp->resumed = 1;
+ if (debug_linux_nat)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "LLA: waitpid %ld, faking SIGSTOP\n", (long) pid);
+ }
}
}
static void
linux_nat_detach (char *args, int from_tty)
{
- iterate_over_lwps (detach_callback, NULL);
+ if (!target_can_async_p ())
+ {
+ iterate_over_lwps (detach_callback, NULL);
- /* Only the initial process should be left right now. */
- gdb_assert (num_lwps == 1);
+ /* Only the initial process should be left right now. */
+ gdb_assert (num_lwps == 1);
- trap_ptid = null_ptid;
+ trap_ptid = null_ptid;
- /* Destroy LWP info; it's no longer valid. */
- init_lwp_list ();
+ /* Destroy LWP info; it's no longer valid. */
+ init_lwp_list ();
+ }
/* Restore the original signal mask. */
sigprocmask (SIG_SETMASK, &normal_mask, NULL);