From: Doug Evans Date: Thu, 30 Apr 2009 22:21:06 +0000 (+0000) Subject: * inferiors.c (started_inferior_callback): New function. X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=9f767825692c9376d77aa5367719217ed591f358;p=deliverable%2Fbinutils-gdb.git * inferiors.c (started_inferior_callback): New function. (attached_inferior_callback): New function. (have_started_inferiors_p, have_attached_inferiors_p): New functions. * server.c (print_started_pid, print_attached_pid): New functions. (detach_or_kill_for_exit): New function. (main): Call it instead of for_each_inferior (kill_inferior_callback). * server.h (have_started_inferiors_p): Declare. (have_attached_inferiors_p): Declare. --- diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index a731bfff2e..d710f61ed8 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,14 @@ 2009-04-30 Doug Evans + * inferiors.c (started_inferior_callback): New function. + (attached_inferior_callback): New function. + (have_started_inferiors_p, have_attached_inferiors_p): New functions. + * server.c (print_started_pid, print_attached_pid): New functions. + (detach_or_kill_for_exit): New function. + (main): Call it instead of for_each_inferior (kill_inferior_callback). + * server.h (have_started_inferiors_p): Declare. + (have_attached_inferiors_p): Declare. + * inferiors.c (remove_process): Fix memory leak, free process. * linux-low.c (linux_remove_process): New function. (linux_kill): Call it instead of remove_process. diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c index 8d44d0160a..8111e28f51 100644 --- a/gdb/gdbserver/inferiors.c +++ b/gdb/gdbserver/inferiors.c @@ -127,6 +127,8 @@ add_inferior_to_list (struct inferior_list *list, list->tail = new_inferior; } +/* Invoke ACTION for each inferior in LIST. */ + void for_each_inferior (struct inferior_list *list, void (*action) (struct inferior_list_entry *)) @@ -447,6 +449,46 @@ find_process_pid (int pid) find_inferior_id (&all_processes, pid_to_ptid (pid)); } +/* Return non-zero if INF, a struct process_info, was started by us, + 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 + (as opposed to attached-to). */ + +int +have_started_inferiors_p (void) +{ + return (find_inferior (&all_processes, started_inferior_callback, NULL) + != 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. */ + +int +have_attached_inferiors_p (void) +{ + return (find_inferior (&all_processes, attached_inferior_callback, NULL) + != NULL); +} + struct process_info * get_thread_process (struct thread_info *thread) { diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 998fd0ce9a..24b163056a 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -1808,6 +1808,11 @@ kill_inferior_callback (struct inferior_list_entry *entry) discard_queued_stop_replies (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) { @@ -1822,6 +1827,65 @@ detach_or_kill_inferior_callback (struct inferior_list_entry *entry) discard_queued_stop_replies (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->head.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->head.id); + fprintf (stderr, " %d", pid); + } +} + +/* Call this when exiting gdbserver with possible inferiors that need + to be killed or detached from. */ + +static void +detach_or_kill_for_exit (void) +{ + /* First print a list of the inferiors we will be killing/detaching. + This is to assist the user, for example, in case the inferior unexpectedly + dies after we exit: did we screw up or did the inferior exit on its own? + Having this info will save some head-scratching. */ + + if (have_started_inferiors_p ()) + { + fprintf (stderr, "Killing process(es):"); + for_each_inferior (&all_processes, print_started_pid); + fprintf (stderr, "\n"); + } + if (have_attached_inferiors_p ()) + { + fprintf (stderr, "Detaching process(es):"); + for_each_inferior (&all_processes, print_attached_pid); + fprintf (stderr, "\n"); + } + + /* Now we can kill or detach the inferiors. */ + + for_each_inferior (&all_processes, detach_or_kill_inferior_callback); +} + static void join_inferiors_callback (struct inferior_list_entry *entry) { @@ -2015,9 +2079,7 @@ main (int argc, char *argv[]) if (setjmp (toplevel)) { - fprintf (stderr, "Killing all inferiors\n"); - for_each_inferior (&all_processes, - kill_inferior_callback); + detach_or_kill_for_exit (); exit (1); } @@ -2062,8 +2124,7 @@ main (int argc, char *argv[]) if (exit_requested) { - for_each_inferior (&all_processes, - detach_or_kill_inferior_callback); + detach_or_kill_for_exit (); exit (0); } else diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index 7a0b77054c..5138f1a3c7 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -236,6 +236,8 @@ void add_thread (ptid_t ptid, void *target_data); struct process_info *add_process (int pid, int attached); void remove_process (struct process_info *process); struct process_info *find_process_pid (int pid); +int have_started_inferiors_p (void); +int have_attached_inferiors_p (void); struct thread_info *find_thread_pid (ptid_t ptid);