gdb/gdbserver/inferiors.c - gdb

Global variables defined

Functions defined

Macros defined

Source code

  1. /* Inferior process information for the remote server for GDB.
  2.    Copyright (C) 2002-2015 Free Software Foundation, Inc.

  3.    Contributed by MontaVista Software.

  4.    This file is part of GDB.

  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 3 of the License, or
  8.    (at your option) any later version.

  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.

  13.    You should have received a copy of the GNU General Public License
  14.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  15. #include "server.h"
  16. #include "gdbthread.h"
  17. #include "dll.h"

  18. struct inferior_list all_processes;
  19. struct inferior_list all_threads;

  20. struct thread_info *current_thread;

  21. #define get_thread(inf) ((struct thread_info *)(inf))

  22. void
  23. add_inferior_to_list (struct inferior_list *list,
  24.                       struct inferior_list_entry *new_inferior)
  25. {
  26.   new_inferior->next = NULL;
  27.   if (list->tail != NULL)
  28.     list->tail->next = new_inferior;
  29.   else
  30.     list->head = new_inferior;
  31.   list->tail = new_inferior;
  32. }

  33. /* Invoke ACTION for each inferior in LIST.  */

  34. void
  35. for_each_inferior (struct inferior_list *list,
  36.                    void (*action) (struct inferior_list_entry *))
  37. {
  38.   struct inferior_list_entry *cur = list->head, *next;

  39.   while (cur != NULL)
  40.     {
  41.       next = cur->next;
  42.       (*action) (cur);
  43.       cur = next;
  44.     }
  45. }

  46. /* Invoke ACTION for each inferior in LIST, passing DATA to ACTION.  */

  47. void
  48. for_each_inferior_with_data (struct inferior_list *list,
  49.                              void (*action) (struct inferior_list_entry *,
  50.                                              void *),
  51.                              void *data)
  52. {
  53.   struct inferior_list_entry *cur = list->head, *next;

  54.   while (cur != NULL)
  55.     {
  56.       next = cur->next;
  57.       (*action) (cur, data);
  58.       cur = next;
  59.     }
  60. }

  61. void
  62. remove_inferior (struct inferior_list *list,
  63.                  struct inferior_list_entry *entry)
  64. {
  65.   struct inferior_list_entry **cur;

  66.   if (list->head == entry)
  67.     {
  68.       list->head = entry->next;
  69.       if (list->tail == entry)
  70.         list->tail = list->head;
  71.       return;
  72.     }

  73.   cur = &list->head;
  74.   while (*cur && (*cur)->next != entry)
  75.     cur = &(*cur)->next;

  76.   if (*cur == NULL)
  77.     return;

  78.   (*cur)->next = entry->next;

  79.   if (list->tail == entry)
  80.     list->tail = *cur;
  81. }

  82. struct thread_info *
  83. add_thread (ptid_t thread_id, void *target_data)
  84. {
  85.   struct thread_info *new_thread = xmalloc (sizeof (*new_thread));

  86.   memset (new_thread, 0, sizeof (*new_thread));

  87.   new_thread->entry.id = thread_id;
  88.   new_thread->last_resume_kind = resume_continue;
  89.   new_thread->last_status.kind = TARGET_WAITKIND_IGNORE;

  90.   add_inferior_to_list (&all_threads, &new_thread->entry);

  91.   if (current_thread == NULL)
  92.     current_thread = new_thread;

  93.   new_thread->target_data = target_data;

  94.   return new_thread;
  95. }

  96. ptid_t
  97. thread_to_gdb_id (struct thread_info *thread)
  98. {
  99.   return thread->entry.id;
  100. }

  101. /* Wrapper around get_first_inferior to return a struct thread_info *.  */

  102. struct thread_info *
  103. get_first_thread (void)
  104. {
  105.   return (struct thread_info *) get_first_inferior (&all_threads);
  106. }

  107. struct thread_info *
  108. find_thread_ptid (ptid_t ptid)
  109. {
  110.   return (struct thread_info *) find_inferior_id (&all_threads, ptid);
  111. }

  112. ptid_t
  113. gdb_id_to_thread_id (ptid_t gdb_id)
  114. {
  115.   struct thread_info *thread = find_thread_ptid (gdb_id);

  116.   return thread ? thread->entry.id : null_ptid;
  117. }

  118. static void
  119. free_one_thread (struct inferior_list_entry *inf)
  120. {
  121.   struct thread_info *thread = get_thread (inf);
  122.   free_register_cache (inferior_regcache_data (thread));
  123.   free (thread);
  124. }

  125. void
  126. remove_thread (struct thread_info *thread)
  127. {
  128.   if (thread->btrace != NULL)
  129.     target_disable_btrace (thread->btrace);

  130.   remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
  131.   free_one_thread (&thread->entry);
  132. }

  133. /* Return a pointer to the first inferior in LIST, or NULL if there isn't one.
  134.    This is for cases where the caller needs a thread, but doesn't care
  135.    which one.  */

  136. struct inferior_list_entry *
  137. get_first_inferior (struct inferior_list *list)
  138. {
  139.   if (list->head != NULL)
  140.     return list->head;
  141.   return NULL;
  142. }

  143. /* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
  144.    returns non-zero.  If no entry is found then return NULL.  */

  145. struct inferior_list_entry *
  146. find_inferior (struct inferior_list *list,
  147.                int (*func) (struct inferior_list_entry *, void *), void *arg)
  148. {
  149.   struct inferior_list_entry *inf = list->head;

  150.   while (inf != NULL)
  151.     {
  152.       struct inferior_list_entry *next;

  153.       next = inf->next;
  154.       if ((*func) (inf, arg))
  155.         return inf;
  156.       inf = next;
  157.     }

  158.   return NULL;
  159. }

  160. struct inferior_list_entry *
  161. find_inferior_id (struct inferior_list *list, ptid_t id)
  162. {
  163.   struct inferior_list_entry *inf = list->head;

  164.   while (inf != NULL)
  165.     {
  166.       if (ptid_equal (inf->id, id))
  167.         return inf;
  168.       inf = inf->next;
  169.     }

  170.   return NULL;
  171. }

  172. void *
  173. inferior_target_data (struct thread_info *inferior)
  174. {
  175.   return inferior->target_data;
  176. }

  177. void
  178. set_inferior_target_data (struct thread_info *inferior, void *data)
  179. {
  180.   inferior->target_data = data;
  181. }

  182. void *
  183. inferior_regcache_data (struct thread_info *inferior)
  184. {
  185.   return inferior->regcache_data;
  186. }

  187. void
  188. set_inferior_regcache_data (struct thread_info *inferior, void *data)
  189. {
  190.   inferior->regcache_data = data;
  191. }

  192. /* Return true if LIST has exactly one entry.  */

  193. int
  194. one_inferior_p (struct inferior_list *list)
  195. {
  196.   return list->head != NULL && list->head == list->tail;
  197. }

  198. /* Reset head,tail of LIST, assuming all entries have already been freed.  */

  199. void
  200. clear_inferior_list (struct inferior_list *list)
  201. {
  202.   list->head = NULL;
  203.   list->tail = NULL;
  204. }

  205. void
  206. clear_inferiors (void)
  207. {
  208.   for_each_inferior (&all_threads, free_one_thread);
  209.   clear_inferior_list (&all_threads);

  210.   clear_dlls ();

  211.   current_thread = NULL;
  212. }

  213. struct process_info *
  214. add_process (int pid, int attached)
  215. {
  216.   struct process_info *process;

  217.   process = xcalloc (1, sizeof (*process));

  218.   process->entry.id = pid_to_ptid (pid);
  219.   process->attached = attached;

  220.   add_inferior_to_list (&all_processes, &process->entry);

  221.   return process;
  222. }

  223. /* Remove a process from the common process list and free the memory
  224.    allocated for it.
  225.    The caller is responsible for freeing private data first.  */

  226. void
  227. remove_process (struct process_info *process)
  228. {
  229.   clear_symbol_cache (&process->symbol_cache);
  230.   free_all_breakpoints (process);
  231.   remove_inferior (&all_processes, &process->entry);
  232.   free (process);
  233. }

  234. struct process_info *
  235. find_process_pid (int pid)
  236. {
  237.   return (struct process_info *)
  238.     find_inferior_id (&all_processes, pid_to_ptid (pid));
  239. }

  240. /* Return non-zero if INF, a struct process_info, was started by us,
  241.    i.e. not attached to.  */

  242. static int
  243. started_inferior_callback (struct inferior_list_entry *entry, void *args)
  244. {
  245.   struct process_info *process = (struct process_info *) entry;

  246.   return ! process->attached;
  247. }

  248. /* Return non-zero if there are any inferiors that we have created
  249.    (as opposed to attached-to).  */

  250. int
  251. have_started_inferiors_p (void)
  252. {
  253.   return (find_inferior (&all_processes, started_inferior_callback, NULL)
  254.           != NULL);
  255. }

  256. /* Return non-zero if INF, a struct process_info, was attached to.  */

  257. static int
  258. attached_inferior_callback (struct inferior_list_entry *entry, void *args)
  259. {
  260.   struct process_info *process = (struct process_info *) entry;

  261.   return process->attached;
  262. }

  263. /* Return non-zero if there are any inferiors that we have attached to.  */

  264. int
  265. have_attached_inferiors_p (void)
  266. {
  267.   return (find_inferior (&all_processes, attached_inferior_callback, NULL)
  268.           != NULL);
  269. }

  270. struct process_info *
  271. get_thread_process (struct thread_info *thread)
  272. {
  273.   int pid = ptid_get_pid (thread->entry.id);
  274.   return find_process_pid (pid);
  275. }

  276. struct process_info *
  277. current_process (void)
  278. {
  279.   gdb_assert (current_thread != NULL);
  280.   return get_thread_process (current_thread);
  281. }