X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Finferiors.c;h=8111e28f51874094d7d801529b00038ab33a5c6f;hb=9f767825692c9376d77aa5367719217ed591f358;hp=c73bf452e0aeadec95dbaf8cf33483241f591be8;hpb=255e7678a93693bd4d16cc3246442a1b8e11064e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c index c73bf452e0..8111e28f51 100644 --- a/gdb/gdbserver/inferiors.c +++ b/gdb/gdbserver/inferiors.c @@ -1,5 +1,5 @@ /* Inferior process information for the remote server for GDB. - Copyright (C) 2002, 2005, 2007 Free Software Foundation, Inc. + Copyright (C) 2002, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by MontaVista Software. @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,9 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ #include @@ -32,12 +30,88 @@ struct thread_info unsigned int gdb_id; }; +struct inferior_list all_processes; struct inferior_list all_threads; struct inferior_list all_dlls; int dlls_changed; struct thread_info *current_inferior; + +/* Oft used ptids */ +ptid_t null_ptid; +ptid_t minus_one_ptid; + +/* Create a ptid given the necessary PID, LWP, and TID components. */ + +ptid_t +ptid_build (int pid, long lwp, long tid) +{ + ptid_t ptid; + + ptid.pid = pid; + ptid.lwp = lwp; + ptid.tid = tid; + return ptid; +} + +/* Create a ptid from just a pid. */ + +ptid_t +pid_to_ptid (int pid) +{ + return ptid_build (pid, 0, 0); +} + +/* Fetch the pid (process id) component from a ptid. */ + +int +ptid_get_pid (ptid_t ptid) +{ + return ptid.pid; +} + +/* Fetch the lwp (lightweight process) component from a ptid. */ + +long +ptid_get_lwp (ptid_t ptid) +{ + return ptid.lwp; +} + +/* Fetch the tid (thread id) component from a ptid. */ + +long +ptid_get_tid (ptid_t ptid) +{ + return ptid.tid; +} + +/* ptid_equal() is used to test equality of two ptids. */ + +int +ptid_equal (ptid_t ptid1, ptid_t ptid2) +{ + return (ptid1.pid == ptid2.pid + && ptid1.lwp == ptid2.lwp + && ptid1.tid == ptid2.tid); +} + +/* Return true if this ptid represents a process. */ + +int +ptid_is_pid (ptid_t ptid) +{ + if (ptid_equal (minus_one_ptid, ptid)) + return 0; + if (ptid_equal (null_ptid, ptid)) + return 0; + + return (ptid_get_pid (ptid) != 0 + && ptid_get_lwp (ptid) == 0 + && ptid_get_tid (ptid) == 0); +} + #define get_thread(inf) ((struct thread_info *)(inf)) #define get_dll(inf) ((struct dll_info *)(inf)) @@ -53,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 *)) @@ -67,21 +143,6 @@ for_each_inferior (struct inferior_list *list, } } -/* When debugging a single-threaded program, the threads list (such as - it is) is indexed by PID. When debugging a multi-threaded program, - we index by TID. This ugly routine replaces the - first-debugged-thread's PID with its TID. */ - -void -change_inferior_id (struct inferior_list *list, - unsigned long new_id) -{ - if (list->head != list->tail) - error ("tried to change thread ID after multiple threads are created"); - - list->head->id = new_id; -} - void remove_inferior (struct inferior_list *list, struct inferior_list_entry *entry) @@ -110,9 +171,9 @@ remove_inferior (struct inferior_list *list, } void -add_thread (unsigned long thread_id, void *target_data, unsigned int gdb_id) +add_thread (ptid_t thread_id, void *target_data) { - struct thread_info *new_thread = malloc (sizeof (*new_thread)); + struct thread_info *new_thread = xmalloc (sizeof (*new_thread)); memset (new_thread, 0, sizeof (*new_thread)); @@ -125,40 +186,38 @@ add_thread (unsigned long thread_id, void *target_data, unsigned int gdb_id) new_thread->target_data = target_data; set_inferior_regcache_data (new_thread, new_register_cache ()); - new_thread->gdb_id = gdb_id; } -unsigned int -thread_id_to_gdb_id (unsigned long thread_id) +ptid_t +thread_id_to_gdb_id (ptid_t thread_id) { struct inferior_list_entry *inf = all_threads.head; while (inf != NULL) { - struct thread_info *thread = get_thread (inf); - if (inf->id == thread_id) - return thread->gdb_id; + if (ptid_equal (inf->id, thread_id)) + return thread_id; inf = inf->next; } - return 0; + return null_ptid; } -unsigned int +ptid_t thread_to_gdb_id (struct thread_info *thread) { - return thread->gdb_id; + return thread->entry.id; } struct thread_info * -gdb_id_to_thread (unsigned int gdb_id) +find_thread_pid (ptid_t ptid) { struct inferior_list_entry *inf = all_threads.head; while (inf != NULL) { struct thread_info *thread = get_thread (inf); - if (thread->gdb_id == gdb_id) + if (ptid_equal (thread->entry.id, ptid)) return thread; inf = inf->next; } @@ -166,12 +225,12 @@ gdb_id_to_thread (unsigned int gdb_id) return NULL; } -unsigned long -gdb_id_to_thread_id (unsigned int gdb_id) +ptid_t +gdb_id_to_thread_id (ptid_t gdb_id) { - struct thread_info *thread = gdb_id_to_thread (gdb_id); + struct thread_info *thread = find_thread_pid (gdb_id); - return thread ? thread->entry.id : 0; + return thread ? thread->entry.id : null_ptid; } static void @@ -197,22 +256,25 @@ find_inferior (struct inferior_list *list, while (inf != NULL) { + struct inferior_list_entry *next; + + next = inf->next; if ((*func) (inf, arg)) return inf; - inf = inf->next; + inf = next; } return NULL; } struct inferior_list_entry * -find_inferior_id (struct inferior_list *list, unsigned long id) +find_inferior_id (struct inferior_list *list, ptid_t id) { struct inferior_list_entry *inf = list->head; while (inf != NULL) { - if (inf->id == id) + if (ptid_equal (inf->id, id)) return inf; inf = inf->next; } @@ -278,12 +340,12 @@ match_dll (struct inferior_list_entry *inf, void *arg) void loaded_dll (const char *name, CORE_ADDR base_addr) { - struct dll_info *new_dll = malloc (sizeof (*new_dll)); + struct dll_info *new_dll = xmalloc (sizeof (*new_dll)); memset (new_dll, 0, sizeof (*new_dll)); - new_dll->entry.id = -1; + new_dll->entry.id = minus_one_ptid; - new_dll->name = strdup (name); + new_dll->name = xstrdup (name); new_dll->base_addr = base_addr; add_inferior_to_list (&all_dlls, &new_dll->entry); @@ -319,4 +381,133 @@ clear_inferiors (void) clear_list (&all_threads); clear_list (&all_dlls); + + current_inferior = NULL; +} + +/* Two utility functions for a truly degenerate inferior_list: a simple + PID listing. */ + +void +add_pid_to_list (struct inferior_list *list, unsigned long pid) +{ + struct inferior_list_entry *new_entry; + + new_entry = xmalloc (sizeof (struct inferior_list_entry)); + new_entry->id = pid_to_ptid (pid); + add_inferior_to_list (list, new_entry); +} + +int +pull_pid_from_list (struct inferior_list *list, unsigned long pid) +{ + struct inferior_list_entry *new_entry; + + new_entry = find_inferior_id (list, pid_to_ptid (pid)); + if (new_entry == NULL) + return 0; + else + { + remove_inferior (list, new_entry); + free (new_entry); + return 1; + } +} + +struct process_info * +add_process (int pid, int attached) +{ + struct process_info *process; + + process = xcalloc (1, sizeof (*process)); + + process->head.id = pid_to_ptid (pid); + process->attached = attached; + + add_inferior_to_list (&all_processes, &process->head); + + return process; +} + +/* Remove a process from the common process list and free the memory + allocated for it. + The caller is responsible for freeing private data first. */ + +void +remove_process (struct process_info *process) +{ + clear_symbol_cache (&process->symbol_cache); + free_all_breakpoints (process); + remove_inferior (&all_processes, &process->head); + free (process); +} + +struct process_info * +find_process_pid (int pid) +{ + return (struct process_info *) + 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) +{ + int pid = ptid_get_pid (thread->entry.id); + return find_process_pid (pid); +} + +struct process_info * +current_process (void) +{ + if (current_inferior == NULL) + fatal ("Current inferior requested, but current_inferior is NULL\n"); + + return get_thread_process (current_inferior); +} + +void +initialize_inferiors (void) +{ + null_ptid = ptid_build (0, 0, 0); + minus_one_ptid = ptid_build (-1, 0, 0); }