diff options
author | Pedro Alves <palves@redhat.com> | 2010-05-02 00:47:34 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2010-05-02 00:47:34 +0000 |
commit | f9e39928dc25d4f8ec5cad87c6cea4cd5ef08f58 (patch) | |
tree | 630db2ced76156c381815d049c88d847b30506ab /gdb/gdbserver/linux-low.c | |
parent | 9dbc5bd27584aef258ea89fb41d21006f59dcfa5 (diff) | |
download | gdb-f9e39928dc25d4f8ec5cad87c6cea4cd5ef08f58.zip gdb-f9e39928dc25d4f8ec5cad87c6cea4cd5ef08f58.tar.gz gdb-f9e39928dc25d4f8ec5cad87c6cea4cd5ef08f58.tar.bz2 |
* linux-low.c (linux_kill_one_lwp): Assume the lwp is stopped.
(linux_kill): Stop all lwps here. Don't delete the main lwp here.
(linux_detach_one_lwp): Assume the lwp is stopped.
(any_thread_of): Delete.
(linux_detach): Stop all lwps here. Don't blindly delete all
breakpoints.
(delete_lwp_callback): New.
(linux_mourn): Delete all lwps of the process that is gone.
(linux_wait_1): Don't delete the last lwp of the process here.
* mem-break.h (mark_breakpoints_out): Declare.
* mem-break.c (mark_breakpoints_out): New.
(free_all_breakpoints): Use it.
* server.c (handle_target_event): If the process is gone, mark
breakpoints out.
* thread-db.c (struct thread_db) <create_bp>: New field.
(thread_db_enable_reporting): Fix prototype. Store a thread event
breakpoint reference in the thread_db struct.
(thread_db_load_search): Clear the thread_db object.
(try_thread_db_load_1): Ditto.
(switch_to_process): New.
(disable_thread_event_reporting): Use it.
(remove_thread_event_breakpoints): New.
(thread_db_detach, thread_db_mourn): Use it.
Diffstat (limited to 'gdb/gdbserver/linux-low.c')
-rw-r--r-- | gdb/gdbserver/linux-low.c | 90 |
1 files changed, 35 insertions, 55 deletions
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 302f702..65a87f6 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -739,11 +739,6 @@ linux_kill_one_lwp (struct inferior_list_entry *entry, void *args) return 0; } - /* If we're killing a running inferior, make sure it is stopped - first, as PTRACE_KILL will not work otherwise. */ - if (!lwp->stopped) - send_sigstop (lwp); - do { ptrace (PTRACE_KILL, lwpid_of (lwp), 0, 0); @@ -768,6 +763,10 @@ linux_kill (int pid) if (process == NULL) return -1; + /* If we're killing a running inferior, make sure it is stopped + first, as PTRACE_KILL will not work otherwise. */ + stop_all_lwps (); + find_inferior (&all_threads, linux_kill_one_lwp, &pid); /* See the comment in linux_kill_one_lwp. We did not kill the first @@ -779,11 +778,6 @@ linux_kill (int pid) fprintf (stderr, "lk_1: killing lwp %ld, for pid: %d\n", lwpid_of (lwp), pid); - /* If we're killing a running inferior, make sure it is stopped - first, as PTRACE_KILL will not work otherwise. */ - if (!lwp->stopped) - send_sigstop (lwp); - do { ptrace (PTRACE_KILL, lwpid_of (lwp), 0, 0); @@ -792,9 +786,11 @@ linux_kill (int pid) lwpid = linux_wait_for_event (lwp->head.id, &wstat, __WALL); } while (lwpid > 0 && WIFSTOPPED (wstat)); - delete_lwp (lwp); - the_target->mourn (process); + + /* Since we presently can only stop all lwps of all processes, we + need to unstop lwps of other processes. */ + unstop_all_lwps (NULL); return 0; } @@ -808,28 +804,6 @@ linux_detach_one_lwp (struct inferior_list_entry *entry, void *args) if (ptid_get_pid (entry->id) != pid) return 0; - /* If we're detaching from a running inferior, make sure it is - stopped first, as PTRACE_DETACH will not work otherwise. */ - if (!lwp->stopped) - { - int lwpid = lwpid_of (lwp); - - stopping_threads = 1; - send_sigstop (lwp); - - /* If this detects a new thread through a clone event, the new - thread is appended to the end of the lwp list, so we'll - eventually detach from it. */ - wait_for_sigstop (&lwp->head); - stopping_threads = 0; - - /* If LWP exits while we're trying to stop it, there's nothing - left to do. */ - lwp = find_lwp_pid (pid_to_ptid (lwpid)); - if (lwp == NULL) - return 0; - } - /* If this process is stopped but is expecting a SIGSTOP, then make sure we take care of that now. This isn't absolutely guaranteed to collect the SIGSTOP, but is fairly likely to. */ @@ -838,8 +812,7 @@ linux_detach_one_lwp (struct inferior_list_entry *entry, void *args) int wstat; /* Clear stop_expected, so that the SIGSTOP will be reported. */ lwp->stop_expected = 0; - if (lwp->stopped) - linux_resume_one_lwp (lwp, 0, 0, NULL); + linux_resume_one_lwp (lwp, 0, 0, NULL); linux_wait_for_event (lwp->head.id, &wstat, __WALL); } @@ -855,17 +828,6 @@ linux_detach_one_lwp (struct inferior_list_entry *entry, void *args) } static int -any_thread_of (struct inferior_list_entry *entry, void *args) -{ - int *pid_p = args; - - if (ptid_get_pid (entry->id) == *pid_p) - return 1; - - return 0; -} - -static int linux_detach (int pid) { struct process_info *process; @@ -874,17 +836,37 @@ linux_detach (int pid) if (process == NULL) return -1; + /* Stop all threads before detaching. First, ptrace requires that + the thread is stopped to sucessfully detach. Second, thread_db + may need to uninstall thread event breakpoints from memory, which + only works with a stopped process anyway. */ + stop_all_lwps (); + #ifdef USE_THREAD_DB thread_db_detach (process); #endif - current_inferior = - (struct thread_info *) find_inferior (&all_threads, any_thread_of, &pid); - - delete_all_breakpoints (); find_inferior (&all_threads, linux_detach_one_lwp, &pid); the_target->mourn (process); + + /* Since we presently can only stop all lwps of all processes, we + need to unstop lwps of other processes. */ + unstop_all_lwps (NULL); + return 0; +} + +/* Remove all LWPs that belong to process PROC from the lwp list. */ + +static int +delete_lwp_callback (struct inferior_list_entry *entry, void *proc) +{ + struct lwp_info *lwp = (struct lwp_info *) entry; + struct process_info *process = proc; + + if (pid_of (lwp) == pid_of (process)) + delete_lwp (lwp); + return 0; } @@ -897,6 +879,8 @@ linux_mourn (struct process_info *process) thread_db_mourn (process); #endif + find_inferior (&all_lwps, delete_lwp_callback, process); + /* Freeing all private data. */ priv = process->private; free (priv->arch_private); @@ -1695,10 +1679,6 @@ retry: { if (WIFEXITED (w) || WIFSIGNALED (w)) { - delete_lwp (event_child); - - current_inferior = NULL; - if (WIFEXITED (w)) { ourstatus->kind = TARGET_WAITKIND_EXITED; |