From: Nick Roberts Date: Mon, 28 Aug 2006 06:12:56 +0000 (+0000) Subject: * linux-nat.c (linux_nat_attach, linux_nat_detach): Make attach/ X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b3b33279f52454cc633da845a1c03025be035965;p=thirdparty%2Fbinutils-gdb.git * linux-nat.c (linux_nat_attach, linux_nat_detach): Make attach/ 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. --- diff --git a/gdb/async-nat-inferior.c b/gdb/async-nat-inferior.c index eac960c1c04..833822b50c3 100644 --- a/gdb/async-nat-inferior.c +++ b/gdb/async-nat-inferior.c @@ -117,8 +117,9 @@ static void gdb_inferior_reset (gdb_inferior_status *s); 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); @@ -381,28 +382,6 @@ gdb_process_events (struct gdb_inferior_status *inferior, 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; } @@ -417,7 +396,7 @@ gdb_process_pending_event (struct gdb_inferior_status *ns, //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 @@ -578,8 +557,6 @@ gdb_inferior_reset (gdb_inferior_status *s) s->suspend_count = 0; - s->last_thread = 0; - gdb_signal_thread_init (&s->signal_status); } diff --git a/gdb/async-nat-inferior.h b/gdb/async-nat-inferior.h index 8051ae510b7..0e850c8582f 100644 --- a/gdb/async-nat-inferior.h +++ b/gdb/async-nat-inferior.h @@ -17,8 +17,6 @@ struct gdb_inferior_status unsigned int suspend_count; - int last_thread; - gdb_signal_thread_status signal_status; }; typedef struct gdb_inferior_status gdb_inferior_status; diff --git a/gdb/inf-child.c b/gdb/inf-child.c index 29d59e92025..89d2c4d7a44 100644 --- a/gdb/inf-child.c +++ b/gdb/inf-child.c @@ -194,10 +194,10 @@ inf_child_target (void) 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; diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c index 9f0a8e717d8..4a9768f8e31 100644 --- a/gdb/inf-ptrace.c +++ b/gdb/inf-ptrace.c @@ -224,6 +224,10 @@ inf_ptrace_attach (char *args, int from_tty) 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); @@ -234,8 +238,24 @@ inf_ptrace_attach (char *args, int from_tty) 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 diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 12a305de2c3..723908bb172 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1887,9 +1887,12 @@ attach_command (char *args, int from_tty) 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 /* diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 67de281250a..8175dcf43df 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -1005,35 +1005,38 @@ linux_nat_attach (char *args, int from_tty) 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); + } } } @@ -1099,15 +1102,18 @@ detach_callback (struct lwp_info *lp, void *data) 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);