gdbserver: Use std::list for all_processes
Remove the usage of inferior_list for the all_processes list in gdbserver, replace it with an std::list. The entry field in process_info is removed, and replaced by a simple pid field. The pid_of macro, used for both processes and threads, is replaced with separate functions. For completeness, I changed ptid_of and lwpid_of to functions as well. gdb/gdbserver/ChangeLog: * gdbthread.h (ptid_of, pid_of, lwpid_of): New functions. * inferiors.h: Include <list>. (struct process_info) <entry>: Remove field. <pid>: New field. (pid_of): Change macro to function. (ptid_of, lwpid_of): Remove macro. (all_processes): Change type to std::list<process_info *>. (ALL_PROCESSES): Remove macro. (for_each_process, find_process): New function. * inferiors.c (all_processes): Change type to std::list<process_info *>. (find_thread_process): Adjust. (add_process): Likewise. (remove_process): Likewise. (find_process_pid): Likewise. (get_first_process): Likewise. (started_inferior_callback): Remove. (have_started_inferiors_p): Adjust. (attached_inferior_callback): Remove. (have_attached_inferiors_p): Adjust. * linux-low.c (check_zombie_leaders): Likewise. * linux-x86-low.c (x86_arch_setup_process_callback): Remove. (x86_linux_update_xmltarget): Adjust. * server.c (handle_query): Likewise. (gdb_reattached_process): Remove. (handle_status): Adjust. (kill_inferior_callback): Likewise. (detach_or_kill_inferior): Remove. (print_started_pid): Likewise. (print_attached_pid): Likewise. (detach_or_kill_for_exit): Update. (process_serial_event): Likewise. * linux-arm-low.c (arm_new_fork): Likewise.
This commit is contained in:
parent
c9cb8905b4
commit
9179355e65
8 changed files with 218 additions and 183 deletions
|
@ -1,3 +1,39 @@
|
||||||
|
2017-10-14 Simon Marchi <simon.marchi@polymtl.ca>
|
||||||
|
|
||||||
|
* gdbthread.h (ptid_of, pid_of, lwpid_of): New functions.
|
||||||
|
* inferiors.h: Include <list>.
|
||||||
|
(struct process_info) <entry>: Remove field.
|
||||||
|
<pid>: New field.
|
||||||
|
(pid_of): Change macro to function.
|
||||||
|
(ptid_of, lwpid_of): Remove macro.
|
||||||
|
(all_processes): Change type to std::list<process_info *>.
|
||||||
|
(ALL_PROCESSES): Remove macro.
|
||||||
|
(for_each_process, find_process): New function.
|
||||||
|
* inferiors.c (all_processes): Change type to
|
||||||
|
std::list<process_info *>.
|
||||||
|
(find_thread_process): Adjust.
|
||||||
|
(add_process): Likewise.
|
||||||
|
(remove_process): Likewise.
|
||||||
|
(find_process_pid): Likewise.
|
||||||
|
(get_first_process): Likewise.
|
||||||
|
(started_inferior_callback): Remove.
|
||||||
|
(have_started_inferiors_p): Adjust.
|
||||||
|
(attached_inferior_callback): Remove.
|
||||||
|
(have_attached_inferiors_p): Adjust.
|
||||||
|
* linux-low.c (check_zombie_leaders): Likewise.
|
||||||
|
* linux-x86-low.c (x86_arch_setup_process_callback): Remove.
|
||||||
|
(x86_linux_update_xmltarget): Adjust.
|
||||||
|
* server.c (handle_query): Likewise.
|
||||||
|
(gdb_reattached_process): Remove.
|
||||||
|
(handle_status): Adjust.
|
||||||
|
(kill_inferior_callback): Likewise.
|
||||||
|
(detach_or_kill_inferior): Remove.
|
||||||
|
(print_started_pid): Likewise.
|
||||||
|
(print_attached_pid): Likewise.
|
||||||
|
(detach_or_kill_for_exit): Update.
|
||||||
|
(process_serial_event): Likewise.
|
||||||
|
* linux-arm-low.c (arm_new_fork): Likewise.
|
||||||
|
|
||||||
2017-10-14 Simon Marchi <simon.marchi@polymtl.ca>
|
2017-10-14 Simon Marchi <simon.marchi@polymtl.ca>
|
||||||
|
|
||||||
* dll.h: Include <list>.
|
* dll.h: Include <list>.
|
||||||
|
|
|
@ -88,6 +88,30 @@ struct thread_info *find_any_thread_of_pid (int pid);
|
||||||
/* Get current thread ID (Linux task ID). */
|
/* Get current thread ID (Linux task ID). */
|
||||||
#define current_ptid (current_thread->entry.id)
|
#define current_ptid (current_thread->entry.id)
|
||||||
|
|
||||||
|
/* Get the ptid of THREAD. */
|
||||||
|
|
||||||
|
static inline ptid_t
|
||||||
|
ptid_of (const thread_info *thread)
|
||||||
|
{
|
||||||
|
return thread->entry.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the pid of THREAD. */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
pid_of (const thread_info *thread)
|
||||||
|
{
|
||||||
|
return thread->entry.id.pid ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the lwp of THREAD. */
|
||||||
|
|
||||||
|
static inline long
|
||||||
|
lwpid_of (const thread_info *thread)
|
||||||
|
{
|
||||||
|
return thread->entry.id.lwp ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a cleanup to restore current_thread. */
|
/* Create a cleanup to restore current_thread. */
|
||||||
struct cleanup *make_cleanup_restore_current_thread (void);
|
struct cleanup *make_cleanup_restore_current_thread (void);
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "gdbthread.h"
|
#include "gdbthread.h"
|
||||||
#include "dll.h"
|
#include "dll.h"
|
||||||
|
|
||||||
struct inferior_list all_processes;
|
std::list<process_info *> all_processes;
|
||||||
struct inferior_list all_threads;
|
struct inferior_list all_threads;
|
||||||
|
|
||||||
struct thread_info *current_thread;
|
struct thread_info *current_thread;
|
||||||
|
@ -144,7 +144,7 @@ find_thread_ptid (ptid_t ptid)
|
||||||
static struct thread_info *
|
static struct thread_info *
|
||||||
find_thread_process (const struct process_info *const process)
|
find_thread_process (const struct process_info *const process)
|
||||||
{
|
{
|
||||||
return find_any_thread_of_pid (process->entry.id.pid ());
|
return find_any_thread_of_pid (process->pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper for find_any_thread_of_pid. Returns true if a thread
|
/* Helper for find_any_thread_of_pid. Returns true if a thread
|
||||||
|
@ -336,10 +336,10 @@ add_process (int pid, int attached)
|
||||||
{
|
{
|
||||||
struct process_info *process = XCNEW (struct process_info);
|
struct process_info *process = XCNEW (struct process_info);
|
||||||
|
|
||||||
process->entry.id = pid_to_ptid (pid);
|
process->pid = pid;
|
||||||
process->attached = attached;
|
process->attached = attached;
|
||||||
|
|
||||||
add_inferior_to_list (&all_processes, &process->entry);
|
all_processes.push_back (process);
|
||||||
|
|
||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
|
@ -354,35 +354,28 @@ remove_process (struct process_info *process)
|
||||||
clear_symbol_cache (&process->symbol_cache);
|
clear_symbol_cache (&process->symbol_cache);
|
||||||
free_all_breakpoints (process);
|
free_all_breakpoints (process);
|
||||||
gdb_assert (find_thread_process (process) == NULL);
|
gdb_assert (find_thread_process (process) == NULL);
|
||||||
remove_inferior (&all_processes, &process->entry);
|
all_processes.remove (process);
|
||||||
VEC_free (int, process->syscalls_to_catch);
|
VEC_free (int, process->syscalls_to_catch);
|
||||||
free (process);
|
free (process);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct process_info *
|
process_info *
|
||||||
find_process_pid (int pid)
|
find_process_pid (int pid)
|
||||||
{
|
{
|
||||||
return (struct process_info *)
|
return find_process ([&] (process_info *process) {
|
||||||
find_inferior_id (&all_processes, pid_to_ptid (pid));
|
return process->pid == pid;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrapper around get_first_inferior to return a struct process_info *. */
|
/* Get the first process in the process list, or NULL if the list is empty. */
|
||||||
|
|
||||||
struct process_info *
|
process_info *
|
||||||
get_first_process (void)
|
get_first_process (void)
|
||||||
{
|
{
|
||||||
return (struct process_info *) get_first_inferior (&all_processes);
|
if (!all_processes.empty ())
|
||||||
}
|
return all_processes.front ();
|
||||||
|
else
|
||||||
/* Return non-zero if INF, a struct process_info, was started by us,
|
return NULL;
|
||||||
i.e. not attached to. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
started_inferior_callback (struct inferior_list_entry *entry, void *args)
|
|
||||||
{
|
|
||||||
struct process_info *process = (struct process_info *) entry;
|
|
||||||
|
|
||||||
return ! process->attached;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return non-zero if there are any inferiors that we have created
|
/* Return non-zero if there are any inferiors that we have created
|
||||||
|
@ -391,18 +384,9 @@ started_inferior_callback (struct inferior_list_entry *entry, void *args)
|
||||||
int
|
int
|
||||||
have_started_inferiors_p (void)
|
have_started_inferiors_p (void)
|
||||||
{
|
{
|
||||||
return (find_inferior (&all_processes, started_inferior_callback, NULL)
|
return find_process ([] (process_info *process) {
|
||||||
!= NULL);
|
return !process->attached;
|
||||||
}
|
}) != NULL;
|
||||||
|
|
||||||
/* Return non-zero if INF, a struct process_info, was attached to. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
attached_inferior_callback (struct inferior_list_entry *entry, void *args)
|
|
||||||
{
|
|
||||||
struct process_info *process = (struct process_info *) entry;
|
|
||||||
|
|
||||||
return process->attached;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return non-zero if there are any inferiors that we have attached to. */
|
/* Return non-zero if there are any inferiors that we have attached to. */
|
||||||
|
@ -410,8 +394,9 @@ attached_inferior_callback (struct inferior_list_entry *entry, void *args)
|
||||||
int
|
int
|
||||||
have_attached_inferiors_p (void)
|
have_attached_inferiors_p (void)
|
||||||
{
|
{
|
||||||
return (find_inferior (&all_processes, attached_inferior_callback, NULL)
|
return find_process ([] (process_info *process) {
|
||||||
!= NULL);
|
return process->attached;
|
||||||
|
}) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct process_info *
|
struct process_info *
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#define INFERIORS_H
|
#define INFERIORS_H
|
||||||
|
|
||||||
#include "gdb_vecs.h"
|
#include "gdb_vecs.h"
|
||||||
|
#include <list>
|
||||||
|
|
||||||
/* Generic information for tracking a list of ``inferiors'' - threads,
|
/* Generic information for tracking a list of ``inferiors'' - threads,
|
||||||
processes, etc. */
|
processes, etc. */
|
||||||
|
@ -45,9 +46,8 @@ struct process_info_private;
|
||||||
|
|
||||||
struct process_info
|
struct process_info
|
||||||
{
|
{
|
||||||
/* This must appear first.
|
/* This process' pid. */
|
||||||
The list iterator functions assume it. */
|
int pid;
|
||||||
struct inferior_list_entry entry;
|
|
||||||
|
|
||||||
/* Nonzero if this child process was attached rather than
|
/* Nonzero if this child process was attached rather than
|
||||||
spawned. */
|
spawned. */
|
||||||
|
@ -79,9 +79,13 @@ struct process_info
|
||||||
struct process_info_private *priv;
|
struct process_info_private *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ptid_of(inf) ((inf)->entry.id)
|
/* Get the pid of PROC. */
|
||||||
#define pid_of(inf) ptid_get_pid ((inf)->entry.id)
|
|
||||||
#define lwpid_of(inf) ptid_get_lwp ((inf)->entry.id)
|
static inline int
|
||||||
|
pid_of (const process_info *proc)
|
||||||
|
{
|
||||||
|
return proc->pid;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return a pointer to the process that corresponds to the current
|
/* Return a pointer to the process that corresponds to the current
|
||||||
thread (current_thread). It is an error to call this if there is
|
thread (current_thread). It is an error to call this if there is
|
||||||
|
@ -90,7 +94,7 @@ struct process_info
|
||||||
struct process_info *current_process (void);
|
struct process_info *current_process (void);
|
||||||
struct process_info *get_thread_process (const struct thread_info *);
|
struct process_info *get_thread_process (const struct thread_info *);
|
||||||
|
|
||||||
extern struct inferior_list all_processes;
|
extern std::list<process_info *> all_processes;
|
||||||
|
|
||||||
void add_inferior_to_list (struct inferior_list *list,
|
void add_inferior_to_list (struct inferior_list *list,
|
||||||
struct inferior_list_entry *new_inferior);
|
struct inferior_list_entry *new_inferior);
|
||||||
|
@ -124,9 +128,45 @@ int one_inferior_p (struct inferior_list *list);
|
||||||
#define ALL_INFERIORS(list, cur, tmp) \
|
#define ALL_INFERIORS(list, cur, tmp) \
|
||||||
ALL_INFERIORS_TYPE (struct inferior_list_entry, list, cur, tmp)
|
ALL_INFERIORS_TYPE (struct inferior_list_entry, list, cur, tmp)
|
||||||
|
|
||||||
/* Iterate over all processes, open loop style. */
|
/* Invoke FUNC for each process. */
|
||||||
#define ALL_PROCESSES(cur, tmp) \
|
|
||||||
ALL_INFERIORS_TYPE (struct process_info, &all_processes, cur, tmp)
|
template <typename Func>
|
||||||
|
static void
|
||||||
|
for_each_process (Func func)
|
||||||
|
{
|
||||||
|
std::list<process_info *>::iterator next, cur = all_processes.begin ();
|
||||||
|
|
||||||
|
while (cur != all_processes.end ())
|
||||||
|
{
|
||||||
|
next = cur;
|
||||||
|
next++;
|
||||||
|
func (*cur);
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the first process for which FUNC returns true. Return NULL if no
|
||||||
|
process satisfying FUNC is found. */
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
static process_info *
|
||||||
|
find_process (Func func)
|
||||||
|
{
|
||||||
|
std::list<process_info *>::iterator next, cur = all_processes.begin ();
|
||||||
|
|
||||||
|
while (cur != all_processes.end ())
|
||||||
|
{
|
||||||
|
next = cur;
|
||||||
|
next++;
|
||||||
|
|
||||||
|
if (func (*cur))
|
||||||
|
return *cur;
|
||||||
|
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
extern struct thread_info *current_thread;
|
extern struct thread_info *current_thread;
|
||||||
void remove_inferior (struct inferior_list *list,
|
void remove_inferior (struct inferior_list *list,
|
||||||
|
|
|
@ -707,7 +707,7 @@ arm_new_fork (struct process_info *parent, struct process_info *child)
|
||||||
|
|
||||||
/* Mark all the hardware breakpoints and watchpoints as changed to
|
/* Mark all the hardware breakpoints and watchpoints as changed to
|
||||||
make sure that the registers will be updated. */
|
make sure that the registers will be updated. */
|
||||||
child_lwp = find_lwp_pid (ptid_of (child));
|
child_lwp = find_lwp_pid (ptid_t (child->pid));
|
||||||
child_lwp_info = child_lwp->arch_private;
|
child_lwp_info = child_lwp->arch_private;
|
||||||
for (i = 0; i < MAX_BPTS; i++)
|
for (i = 0; i < MAX_BPTS; i++)
|
||||||
child_lwp_info->bpts_changed[i] = 1;
|
child_lwp_info->bpts_changed[i] = 1;
|
||||||
|
|
|
@ -1944,63 +1944,60 @@ iterate_over_lwps (ptid_t filter,
|
||||||
static void
|
static void
|
||||||
check_zombie_leaders (void)
|
check_zombie_leaders (void)
|
||||||
{
|
{
|
||||||
struct process_info *proc, *tmp;
|
for_each_process ([] (process_info *proc) {
|
||||||
|
pid_t leader_pid = pid_of (proc);
|
||||||
|
struct lwp_info *leader_lp;
|
||||||
|
|
||||||
ALL_PROCESSES (proc, tmp)
|
leader_lp = find_lwp_pid (pid_to_ptid (leader_pid));
|
||||||
{
|
|
||||||
pid_t leader_pid = pid_of (proc);
|
|
||||||
struct lwp_info *leader_lp;
|
|
||||||
|
|
||||||
leader_lp = find_lwp_pid (pid_to_ptid (leader_pid));
|
if (debug_threads)
|
||||||
|
debug_printf ("leader_pid=%d, leader_lp!=NULL=%d, "
|
||||||
|
"num_lwps=%d, zombie=%d\n",
|
||||||
|
leader_pid, leader_lp!= NULL, num_lwps (leader_pid),
|
||||||
|
linux_proc_pid_is_zombie (leader_pid));
|
||||||
|
|
||||||
if (debug_threads)
|
if (leader_lp != NULL && !leader_lp->stopped
|
||||||
debug_printf ("leader_pid=%d, leader_lp!=NULL=%d, "
|
/* Check if there are other threads in the group, as we may
|
||||||
"num_lwps=%d, zombie=%d\n",
|
have raced with the inferior simply exiting. */
|
||||||
leader_pid, leader_lp!= NULL, num_lwps (leader_pid),
|
&& !last_thread_of_process_p (leader_pid)
|
||||||
linux_proc_pid_is_zombie (leader_pid));
|
&& linux_proc_pid_is_zombie (leader_pid))
|
||||||
|
{
|
||||||
|
/* A leader zombie can mean one of two things:
|
||||||
|
|
||||||
if (leader_lp != NULL && !leader_lp->stopped
|
- It exited, and there's an exit status pending
|
||||||
/* Check if there are other threads in the group, as we may
|
available, or only the leader exited (not the whole
|
||||||
have raced with the inferior simply exiting. */
|
program). In the latter case, we can't waitpid the
|
||||||
&& !last_thread_of_process_p (leader_pid)
|
leader's exit status until all other threads are gone.
|
||||||
&& linux_proc_pid_is_zombie (leader_pid))
|
|
||||||
{
|
|
||||||
/* A leader zombie can mean one of two things:
|
|
||||||
|
|
||||||
- It exited, and there's an exit status pending
|
- There are 3 or more threads in the group, and a thread
|
||||||
available, or only the leader exited (not the whole
|
other than the leader exec'd. On an exec, the Linux
|
||||||
program). In the latter case, we can't waitpid the
|
kernel destroys all other threads (except the execing
|
||||||
leader's exit status until all other threads are gone.
|
one) in the thread group, and resets the execing thread's
|
||||||
|
tid to the tgid. No exit notification is sent for the
|
||||||
|
execing thread -- from the ptracer's perspective, it
|
||||||
|
appears as though the execing thread just vanishes.
|
||||||
|
Until we reap all other threads except the leader and the
|
||||||
|
execing thread, the leader will be zombie, and the
|
||||||
|
execing thread will be in `D (disc sleep)'. As soon as
|
||||||
|
all other threads are reaped, the execing thread changes
|
||||||
|
it's tid to the tgid, and the previous (zombie) leader
|
||||||
|
vanishes, giving place to the "new" leader. We could try
|
||||||
|
distinguishing the exit and exec cases, by waiting once
|
||||||
|
more, and seeing if something comes out, but it doesn't
|
||||||
|
sound useful. The previous leader _does_ go away, and
|
||||||
|
we'll re-add the new one once we see the exec event
|
||||||
|
(which is just the same as what would happen if the
|
||||||
|
previous leader did exit voluntarily before some other
|
||||||
|
thread execs). */
|
||||||
|
|
||||||
- There are 3 or more threads in the group, and a thread
|
if (debug_threads)
|
||||||
other than the leader exec'd. On an exec, the Linux
|
debug_printf ("CZL: Thread group leader %d zombie "
|
||||||
kernel destroys all other threads (except the execing
|
"(it exited, or another thread execd).\n",
|
||||||
one) in the thread group, and resets the execing thread's
|
leader_pid);
|
||||||
tid to the tgid. No exit notification is sent for the
|
|
||||||
execing thread -- from the ptracer's perspective, it
|
|
||||||
appears as though the execing thread just vanishes.
|
|
||||||
Until we reap all other threads except the leader and the
|
|
||||||
execing thread, the leader will be zombie, and the
|
|
||||||
execing thread will be in `D (disc sleep)'. As soon as
|
|
||||||
all other threads are reaped, the execing thread changes
|
|
||||||
it's tid to the tgid, and the previous (zombie) leader
|
|
||||||
vanishes, giving place to the "new" leader. We could try
|
|
||||||
distinguishing the exit and exec cases, by waiting once
|
|
||||||
more, and seeing if something comes out, but it doesn't
|
|
||||||
sound useful. The previous leader _does_ go away, and
|
|
||||||
we'll re-add the new one once we see the exec event
|
|
||||||
(which is just the same as what would happen if the
|
|
||||||
previous leader did exit voluntarily before some other
|
|
||||||
thread execs). */
|
|
||||||
|
|
||||||
if (debug_threads)
|
delete_lwp (leader_lp);
|
||||||
debug_printf ("CZL: Thread group leader %d zombie "
|
}
|
||||||
"(it exited, or another thread execd).\n",
|
});
|
||||||
leader_pid);
|
|
||||||
|
|
||||||
delete_lwp (leader_lp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback for `find_inferior'. Returns the first LWP that is not
|
/* Callback for `find_inferior'. Returns the first LWP that is not
|
||||||
|
|
|
@ -854,20 +854,6 @@ x86_linux_read_description (void)
|
||||||
gdb_assert_not_reached ("failed to return tdesc");
|
gdb_assert_not_reached ("failed to return tdesc");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback for for_each_inferior. Calls the arch_setup routine for
|
|
||||||
each process. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
x86_arch_setup_process_callback (struct inferior_list_entry *entry)
|
|
||||||
{
|
|
||||||
int pid = ptid_get_pid (entry->id);
|
|
||||||
|
|
||||||
/* Look up any thread of this processes. */
|
|
||||||
current_thread = find_any_thread_of_pid (pid);
|
|
||||||
|
|
||||||
the_low_target.arch_setup ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update all the target description of all processes; a new GDB
|
/* Update all the target description of all processes; a new GDB
|
||||||
connected, and it may or not support xml target descriptions. */
|
connected, and it may or not support xml target descriptions. */
|
||||||
|
|
||||||
|
@ -881,7 +867,14 @@ x86_linux_update_xmltarget (void)
|
||||||
release the current regcache objects. */
|
release the current regcache objects. */
|
||||||
regcache_release ();
|
regcache_release ();
|
||||||
|
|
||||||
for_each_inferior (&all_processes, x86_arch_setup_process_callback);
|
for_each_process ([] (process_info *proc) {
|
||||||
|
int pid = proc->pid;
|
||||||
|
|
||||||
|
/* Look up any thread of this process. */
|
||||||
|
current_thread = find_any_thread_of_pid (pid);
|
||||||
|
|
||||||
|
the_low_target.arch_setup ();
|
||||||
|
});
|
||||||
|
|
||||||
current_thread = saved_thread;
|
current_thread = saved_thread;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2615,8 +2615,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
|
||||||
if (own_buf[sizeof ("qAttached") - 1])
|
if (own_buf[sizeof ("qAttached") - 1])
|
||||||
{
|
{
|
||||||
int pid = strtoul (own_buf + sizeof ("qAttached:") - 1, NULL, 16);
|
int pid = strtoul (own_buf + sizeof ("qAttached:") - 1, NULL, 16);
|
||||||
process = (struct process_info *)
|
process = find_process_pid (pid);
|
||||||
find_inferior_id (&all_processes, pid_to_ptid (pid));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3305,16 +3304,6 @@ gdb_wants_all_threads_stopped (void)
|
||||||
for_each_inferior (&all_threads, gdb_wants_thread_stopped);
|
for_each_inferior (&all_threads, gdb_wants_thread_stopped);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the gdb_detached flag of every process. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
gdb_reattached_process (struct inferior_list_entry *entry)
|
|
||||||
{
|
|
||||||
struct process_info *process = (struct process_info *) entry;
|
|
||||||
|
|
||||||
process->gdb_detached = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Callback for for_each_inferior. Clear the thread's pending status
|
/* Callback for for_each_inferior. Clear the thread's pending status
|
||||||
flag. */
|
flag. */
|
||||||
|
|
||||||
|
@ -3363,7 +3352,9 @@ static void
|
||||||
handle_status (char *own_buf)
|
handle_status (char *own_buf)
|
||||||
{
|
{
|
||||||
/* GDB is connected, don't forward events to the target anymore. */
|
/* GDB is connected, don't forward events to the target anymore. */
|
||||||
for_each_inferior (&all_processes, gdb_reattached_process);
|
for_each_process ([] (process_info *process) {
|
||||||
|
process->gdb_detached = 0;
|
||||||
|
});
|
||||||
|
|
||||||
/* In non-stop mode, we must send a stop reply for each stopped
|
/* In non-stop mode, we must send a stop reply for each stopped
|
||||||
thread. In all-stop mode, just send one for the first stopped
|
thread. In all-stop mode, just send one for the first stopped
|
||||||
|
@ -3517,64 +3508,14 @@ gdbserver_show_disableable (FILE *stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
kill_inferior_callback (struct inferior_list_entry *entry)
|
kill_inferior_callback (process_info *process)
|
||||||
{
|
{
|
||||||
struct process_info *process = (struct process_info *) entry;
|
int pid = process->pid;
|
||||||
int pid = ptid_get_pid (process->entry.id);
|
|
||||||
|
|
||||||
kill_inferior (pid);
|
kill_inferior (pid);
|
||||||
discard_queued_stop_replies (pid_to_ptid (pid));
|
discard_queued_stop_replies (pid_to_ptid (pid));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback for for_each_inferior to detach or kill the inferior,
|
|
||||||
depending on whether we attached to it or not.
|
|
||||||
We inform the user whether we're detaching or killing the process
|
|
||||||
as this is only called when gdbserver is about to exit. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
detach_or_kill_inferior_callback (struct inferior_list_entry *entry)
|
|
||||||
{
|
|
||||||
struct process_info *process = (struct process_info *) entry;
|
|
||||||
int pid = ptid_get_pid (process->entry.id);
|
|
||||||
|
|
||||||
if (process->attached)
|
|
||||||
detach_inferior (pid);
|
|
||||||
else
|
|
||||||
kill_inferior (pid);
|
|
||||||
|
|
||||||
discard_queued_stop_replies (pid_to_ptid (pid));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for_each_inferior callback for detach_or_kill_for_exit to print
|
|
||||||
the pids of started inferiors. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_started_pid (struct inferior_list_entry *entry)
|
|
||||||
{
|
|
||||||
struct process_info *process = (struct process_info *) entry;
|
|
||||||
|
|
||||||
if (! process->attached)
|
|
||||||
{
|
|
||||||
int pid = ptid_get_pid (process->entry.id);
|
|
||||||
fprintf (stderr, " %d", pid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for_each_inferior callback for detach_or_kill_for_exit to print
|
|
||||||
the pids of attached inferiors. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_attached_pid (struct inferior_list_entry *entry)
|
|
||||||
{
|
|
||||||
struct process_info *process = (struct process_info *) entry;
|
|
||||||
|
|
||||||
if (process->attached)
|
|
||||||
{
|
|
||||||
int pid = ptid_get_pid (process->entry.id);
|
|
||||||
fprintf (stderr, " %d", pid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call this when exiting gdbserver with possible inferiors that need
|
/* Call this when exiting gdbserver with possible inferiors that need
|
||||||
to be killed or detached from. */
|
to be killed or detached from. */
|
||||||
|
|
||||||
|
@ -3589,19 +3530,37 @@ detach_or_kill_for_exit (void)
|
||||||
if (have_started_inferiors_p ())
|
if (have_started_inferiors_p ())
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Killing process(es):");
|
fprintf (stderr, "Killing process(es):");
|
||||||
for_each_inferior (&all_processes, print_started_pid);
|
|
||||||
|
for_each_process ([] (process_info *process) {
|
||||||
|
if (!process->attached)
|
||||||
|
fprintf (stderr, " %d", process->pid);
|
||||||
|
});
|
||||||
|
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
if (have_attached_inferiors_p ())
|
if (have_attached_inferiors_p ())
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Detaching process(es):");
|
fprintf (stderr, "Detaching process(es):");
|
||||||
for_each_inferior (&all_processes, print_attached_pid);
|
|
||||||
|
for_each_process ([] (process_info *process) {
|
||||||
|
if (process->attached)
|
||||||
|
fprintf (stderr, " %d", process->pid);
|
||||||
|
});
|
||||||
|
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now we can kill or detach the inferiors. */
|
/* Now we can kill or detach the inferiors. */
|
||||||
|
for_each_process ([] (process_info *process) {
|
||||||
|
int pid = process->pid;
|
||||||
|
|
||||||
for_each_inferior (&all_processes, detach_or_kill_inferior_callback);
|
if (process->attached)
|
||||||
|
detach_inferior (pid);
|
||||||
|
else
|
||||||
|
kill_inferior (pid);
|
||||||
|
|
||||||
|
discard_queued_stop_replies (pid_to_ptid (pid));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Value that will be passed to exit(3) when gdbserver exits. */
|
/* Value that will be passed to exit(3) when gdbserver exits. */
|
||||||
|
@ -4332,7 +4291,8 @@ process_serial_event (void)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fprintf (stderr, "Killing all inferiors\n");
|
fprintf (stderr, "Killing all inferiors\n");
|
||||||
for_each_inferior (&all_processes, kill_inferior_callback);
|
|
||||||
|
for_each_process (kill_inferior_callback);
|
||||||
|
|
||||||
/* When using the extended protocol, we wait with no program
|
/* When using the extended protocol, we wait with no program
|
||||||
running. The traditional protocol will exit instead. */
|
running. The traditional protocol will exit instead. */
|
||||||
|
@ -4370,8 +4330,8 @@ process_serial_event (void)
|
||||||
if (extended_protocol)
|
if (extended_protocol)
|
||||||
{
|
{
|
||||||
if (target_running ())
|
if (target_running ())
|
||||||
for_each_inferior (&all_processes,
|
for_each_process (kill_inferior_callback);
|
||||||
kill_inferior_callback);
|
|
||||||
fprintf (stderr, "GDBserver restarting\n");
|
fprintf (stderr, "GDBserver restarting\n");
|
||||||
|
|
||||||
/* Wait till we are at 1st instruction in prog. */
|
/* Wait till we are at 1st instruction in prog. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue