forked from Imagelibrary/binutils-gdb
* 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.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -854,17 +827,6 @@ linux_detach_one_lwp (struct inferior_list_entry *entry, void *args)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user