-/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
This file is part of GDB.
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"
int activation_link;
int call;
int ll;
+ int base_cpu;
/* Fields in Task_Primitives.Private_Data. */
int ll_thread;
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. */
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;
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;
}
}
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;
"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);
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"
= 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);
}
}
- /* 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;
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);
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,
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,