Remove some cleanups from search_minsyms_for_name
[deliverable/binutils-gdb.git] / gdb / ada-tasks.c
index 1d5542d5d641e46921098aeae0b3ac2c288b19bc..bbc0375571d8c5a33842fc0ffa82eff09fbec774 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -16,7 +16,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "observer.h"
+#include "observable.h"
 #include "gdbcmd.h"
 #include "target.h"
 #include "ada-lang.h"
@@ -123,6 +123,7 @@ struct atcb_fieldnos
   int activation_link;
   int call;
   int ll;
+  int base_cpu;
 
   /* Fields in Task_Primitives.Private_Data.  */
   int ll_thread;
@@ -352,6 +353,30 @@ ada_task_is_alive (struct ada_task_info *task_info)
   return (task_info->state != Terminated);
 }
 
+/* Search through the list of known tasks for the one whose ptid is
+   PTID, and return it.  Return NULL if the task was not found.  */
+
+struct ada_task_info *
+ada_get_task_info_from_ptid (ptid_t ptid)
+{
+  int i, nb_tasks;
+  struct ada_task_info *task;
+  struct ada_tasks_inferior_data *data;
+
+  ada_build_task_list ();
+  data = get_ada_tasks_inferior_data (current_inferior ());
+  nb_tasks = VEC_length (ada_task_info_s, data->task_list);
+
+  for (i = 0; i < nb_tasks; i++)
+    {
+      task = VEC_index (ada_task_info_s, data->task_list, i);
+      if (ptid_equal (task->ptid, ptid))
+       return task;
+    }
+
+  return NULL;
+}
+
 /* Call the ITERATOR function once for each Ada task that hasn't been
    terminated yet.  */
 
@@ -441,18 +466,17 @@ read_fat_string_value (char *dest, struct value *val, int max_len)
   dest[len] = '\0';
 }
 
-/* Get from the debugging information the type description of all types
-   related to the Ada Task Control Block that will be needed in order to
-   read the list of known tasks in the Ada runtime.  Also return the
-   associated ATCB_FIELDNOS.
-
-   Error handling:  Any data missing from the debugging info will cause
-   an error to be raised, and none of the return values to be set.
-   Users of this function can depend on the fact that all or none of the
-   return values will be set.  */
-
-static void
-get_tcb_types_info (void)
+/* Get, from the debugging information, the type description of all types
+   related to the Ada Task Control Block that are needed in order to
+   read the list of known tasks in the Ada runtime.  If all of the info
+   needed to do so is found, then save that info in the module's per-
+   program-space data, and return NULL.  Otherwise, if any information
+   cannot be found, leave the per-program-space data untouched, and
+   return an error message explaining what was missing (that error
+   message does NOT need to be deallocated).  */
+
+const char *
+ada_get_tcb_types_info (void)
 {
   struct type *type;
   struct type *common_type;
@@ -493,7 +517,7 @@ get_tcb_types_info (void)
                                            NULL).symbol;
 
       if (atcb_sym == NULL || atcb_sym->type == NULL)
-        error (_("Cannot find Ada_Task_Control_Block type. Aborting"));
+        return _("Cannot find Ada_Task_Control_Block type");
 
       type = atcb_sym->type;
     }
@@ -506,11 +530,11 @@ get_tcb_types_info (void)
     }
 
   if (common_atcb_sym == NULL || common_atcb_sym->type == NULL)
-    error (_("Cannot find Common_ATCB type. Aborting"));
+    return _("Cannot find Common_ATCB type");
   if (private_data_sym == NULL || private_data_sym->type == NULL)
-    error (_("Cannot find Private_Data type. Aborting"));
+    return _("Cannot find Private_Data type");
   if (entry_call_record_sym == NULL || entry_call_record_sym->type == NULL)
-    error (_("Cannot find Entry_Call_Record type. Aborting"));
+    return _("Cannot find Entry_Call_Record type");
 
   /* Get the type for Ada_Task_Control_Block.Common.  */
   common_type = common_atcb_sym->type;
@@ -535,6 +559,7 @@ get_tcb_types_info (void)
                                                   "activation_link", 1);
   fieldnos.call = ada_get_field_index (common_type, "call", 1);
   fieldnos.ll = ada_get_field_index (common_type, "ll", 0);
+  fieldnos.base_cpu = ada_get_field_index (common_type, "base_cpu", 0);
   fieldnos.ll_thread = ada_get_field_index (ll_type, "thread", 0);
   fieldnos.ll_lwp = ada_get_field_index (ll_type, "lwp", 1);
   fieldnos.call_self = ada_get_field_index (call_type, "self", 0);
@@ -557,6 +582,7 @@ get_tcb_types_info (void)
   pspace_data->atcb_ll_type = ll_type;
   pspace_data->atcb_call_type = call_type;
   pspace_data->atcb_fieldno = fieldnos;
+  return NULL;
 }
 
 /* Build the PTID of the task from its COMMON_VALUE, which is the "Common"
@@ -604,7 +630,12 @@ read_atcb (CORE_ADDR task_id, struct ada_task_info *task_info)
     = get_ada_tasks_pspace_data (current_program_space);
 
   if (!pspace_data->initialized_p)
-    get_tcb_types_info ();
+    {
+      const char *err_msg = ada_get_tcb_types_info ();
+
+      if (err_msg != NULL)
+       error (_("%s. Aborting"), err_msg);
+    }
 
   tcb_value = value_from_contents_and_address (pspace_data->atcb_type,
                                               NULL, task_id);
@@ -748,18 +779,14 @@ read_atcb (CORE_ADDR task_id, struct ada_task_info *task_info)
         }
     }
 
-  /* And finally, compute the task ptid.  Note that there are situations
-     where this cannot be determined:
-       - The task is no longer alive - the ptid is irrelevant;
-       - We are debugging a core file - the thread is not always
-         completely preserved for us to link back a task to its
-         underlying thread.  Since we do not support task switching
-         when debugging core files anyway, we don't need to compute
-         that task ptid.
-     In either case, we don't need that ptid, and it is just good enough
-     to set it to null_ptid.  */
-
-  if (target_has_execution && ada_task_is_alive (task_info))
+  task_info->base_cpu
+    = value_as_long (value_field (common_value,
+                                 pspace_data->atcb_fieldno.base_cpu));
+
+  /* And finally, compute the task ptid.  Note that there is not point
+     in computing it if the task is no longer alive, in which case
+     it is good enough to set its ptid to the null_ptid.  */
+  if (ada_task_is_alive (task_info))
     task_info->ptid = ptid_from_atcb_common (common_value);
   else
     task_info->ptid = null_ptid;
@@ -1179,6 +1206,10 @@ info_task (struct ui_out *uiout, const char *taskno_str, struct inferior *inf)
   printf_filtered (_("Thread: %#lx\n"), ptid_get_tid (task_info->ptid));
   printf_filtered (_("LWP: %#lx\n"), ptid_get_lwp (task_info->ptid));
 
+  /* If set, print the base CPU.  */
+  if (task_info->base_cpu != 0)
+    printf_filtered (_("Base CPU: %d\n"), task_info->base_cpu);
+
   /* Print who is the parent (if any).  */
   if (task_info->parent != 0)
     parent_taskno = get_task_number_from_id (task_info->parent, inf);
@@ -1327,23 +1358,7 @@ task_command (const char *taskno_str, int from_tty)
   if (taskno_str == NULL || taskno_str[0] == '\0')
     display_current_task_id ();
   else
-    {
-      /* Task switching in core files doesn't work, either because:
-           1. Thread support is not implemented with core files
-           2. Thread support is implemented, but the thread IDs created
-              after having read the core file are not the same as the ones
-              that were used during the program life, before the crash.
-              As a consequence, there is no longer a way for the debugger
-              to find the associated thead ID of any given Ada task.
-         So, instead of attempting a task switch without giving the user
-         any clue as to what might have happened, just error-out with
-         a message explaining that this feature is not supported.  */
-      if (!target_has_execution)
-        error (_("\
-Task switching not supported when debugging from core files\n\
-(use thread support instead)"));
-      task_command_1 (taskno_str, from_tty, current_inferior ());
-    }
+    task_command_1 (taskno_str, from_tty, current_inferior ());
 }
 
 /* Indicate that the given inferior's task list may have changed,
@@ -1429,8 +1444,8 @@ _initialize_tasks (void)
   ada_tasks_inferior_data_handle = register_inferior_data ();
 
   /* Attach various observers.  */
-  observer_attach_normal_stop (ada_tasks_normal_stop_observer);
-  observer_attach_new_objfile (ada_tasks_new_objfile_observer);
+  gdb::observers::normal_stop.attach (ada_tasks_normal_stop_observer);
+  gdb::observers::new_objfile.attach (ada_tasks_new_objfile_observer);
 
   /* Some new commands provided by this module.  */
   add_info ("tasks", info_tasks_command,
This page took 0.039476 seconds and 4 git commands to generate.