-/* Copyright (C) 1992, 1993, 1994, 1997, 1998, 1999, 2000, 2003, 2004,
- 2005, 2007, 2008 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1993, 1994, 1997, 1998, 1999, 2000, 2003, 2004, 2005,
+ 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GDB.
Timer_Server_Sleep,
AST_Server_Sleep,
Asynchronous_Hold,
- Interrupt_Server_Blocked_On_Event_Flag
+ Interrupt_Server_Blocked_On_Event_Flag,
+ Activating,
+ Acceptor_Delay_Sleep
};
/* A short description corresponding to each possible task state. */
-static char *task_states[] = {
- _("Unactivated"),
- _("Runnable"),
- _("Terminated"),
- _("Child Activation Wait"),
- _("Accept Statement"),
- _("Waiting on entry call"),
- _("Async Select Wait"),
- _("Delay Sleep"),
- _("Child Termination Wait"),
- _("Wait Child in Term Alt"),
+static const char *task_states[] = {
+ N_("Unactivated"),
+ N_("Runnable"),
+ N_("Terminated"),
+ N_("Child Activation Wait"),
+ N_("Accept or Select Term"),
+ N_("Waiting on entry call"),
+ N_("Async Select Wait"),
+ N_("Delay Sleep"),
+ N_("Child Termination Wait"),
+ N_("Wait Child in Term Alt"),
"",
"",
"",
"",
- _("Asynchronous Hold"),
- ""
+ N_("Asynchronous Hold"),
+ "",
+ N_("Activating"),
+ N_("Selective Wait")
};
/* A longer description corresponding to each possible task state. */
-static char *long_task_states[] = {
- _("Unactivated"),
- _("Runnable"),
- _("Terminated"),
- _("Waiting for child activation"),
- _("Blocked in accept statement"),
- _("Waiting on entry call"),
- _("Asynchronous Selective Wait"),
- _("Delay Sleep"),
- _("Waiting for children termination"),
- _("Waiting for children in terminate alternative"),
+static const char *long_task_states[] = {
+ N_("Unactivated"),
+ N_("Runnable"),
+ N_("Terminated"),
+ N_("Waiting for child activation"),
+ N_("Blocked in accept or select with terminate"),
+ N_("Waiting on entry call"),
+ N_("Asynchronous Selective Wait"),
+ N_("Delay Sleep"),
+ N_("Waiting for children termination"),
+ N_("Waiting for children in terminate alternative"),
+ "",
"",
"",
"",
+ N_("Asynchronous Hold"),
"",
- _("Asynchronous Hold"),
- ""
+ N_("Activating"),
+ N_("Blocked in selective wait statement")
};
/* The index of certain important fields in the Ada Task Control Block
int
valid_task_id (int task_num)
{
+ ada_build_task_list (0);
return (task_num > 0
&& task_num <= VEC_length (ada_task_info_s, task_list));
}
-/* Return the task info associated to the Environment Task.
- This function assumes that the inferior does in fact use tasking. */
-
-struct ada_task_info *
-ada_get_environment_task (void)
-{
- ada_build_task_list (0);
- gdb_assert (VEC_length (ada_task_info_s, task_list) > 0);
-
- /* We use a little bit of insider knowledge to determine which task
- is the Environment Task: We know that this task is created first,
- and thus should always be task #1, which is at index 0 of the
- TASK_LIST. */
- return (VEC_index (ada_task_info_s, task_list, 0));
-}
-
-/* Call the ITERATOR function once for each Ada task that hasn't been
- terminated yet. */
+/* Return non-zero iff the task STATE corresponds to a non-terminated
+ task state. */
-void
-iterate_over_live_ada_tasks (ada_task_list_iterator_ftype *iterator)
+static int
+ada_task_is_alive (struct ada_task_info *task_info)
{
- int i, nb_tasks;
- struct ada_task_info *task;
-
- ada_build_task_list (0);
- nb_tasks = VEC_length (ada_task_info_s, task_list);
-
- for (i = 0; i < nb_tasks; i++)
- {
- task = VEC_index (ada_task_info_s, task_list, i);
- if (!ada_task_is_alive (task))
- continue;
- iterator (task);
- }
+ return (task_info->state != Terminated);
}
/* Extract the contents of the value as a string whose length is LENGTH,
/* Extract LEN characters from the fat string. */
array_val = value_ind (value_field (val, array_fieldno));
- read_memory (VALUE_ADDRESS (array_val), dest, len);
+ read_memory (value_address (array_val), dest, len);
/* Add the NUL character to close the string. */
dest[len] = '\0';
if (ada_tasks_check_symbol_table)
{
- struct symbol *sym;
struct minimal_symbol *msym;
msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL);
ada_coerce_to_simple_array_ptr (value_field (tcb_value,
fieldno.entry_calls));
entry_calls_value_element =
- value_subscript (entry_calls_value, atc_nesting_level_value);
+ value_subscript (entry_calls_value,
+ value_as_long (atc_nesting_level_value));
called_task_fieldno =
ada_get_field_index (value_type (entry_calls_value_element),
"called_task", 0);
read_known_tasks_array (void)
{
const int target_ptr_byte =
- gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT;
+ gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
const CORE_ADDR known_tasks_addr = get_known_tasks_addr ();
const int known_tasks_size = target_ptr_byte * MAX_NUMBER_OF_KNOWN_TASKS;
gdb_byte *known_tasks = alloca (known_tasks_size);
for (i = 0; i < MAX_NUMBER_OF_KNOWN_TASKS; i++)
{
struct type *data_ptr_type =
- builtin_type (current_gdbarch)->builtin_data_ptr;
+ builtin_type (target_gdbarch)->builtin_data_ptr;
CORE_ADDR task_id =
extract_typed_address (known_tasks + i * target_ptr_byte,
data_ptr_type);
return 1;
}
-/* Return non-zero iff the task STATE corresponds to a non-terminated
- task state. */
-
-int
-ada_task_is_alive (struct ada_task_info *task_info)
-{
- return (task_info->state != Terminated);
-}
-
/* Print a one-line description of the task whose number is TASKNO.
The formatting should fit the "info tasks" array. */
else if (task_info->state == Entry_Caller_Sleep && task_info->called_task)
printf_filtered (_(" Waiting on RV with %-3d"),
get_task_number_from_id (task_info->called_task));
- else if (task_info->state == Runnable && active_task_p)
- /* Replace "Runnable" by "Running" since this is the active task. */
- printf_filtered (" %-22s", "Running");
else
- printf_filtered (" %-22s", task_states[task_info->state]);
+ printf_filtered (" %-22s", _(task_states[task_info->state]));
/* Finally, print the task name. */
if (task_info->name[0] != '\0')
task_info = VEC_index (ada_task_info_s, task_list, taskno - 1);
/* Print the Ada task ID. */
- printf_filtered (_("Ada Task: %s\n"), paddr_nz (task_info->task_id));
+ printf_filtered (_("Ada Task: %s\n"),
+ paddress (target_gdbarch, task_info->task_id));
/* Print the name of the task. */
if (task_info->name[0] != '\0')
target_taskno);
}
else
- printf_filtered ("State: %s", long_task_states[task_info->state]);
+ printf_filtered (_("State: %s"), _(long_task_states[task_info->state]));
if (target_taskno)
{
if (!ada_task_is_alive (task_info))
error (_("Cannot switch to task %d: Task is no longer running"), taskno);
+ /* On some platforms, the thread list is not updated until the user
+ performs a thread-related operation (by using the "info threads"
+ command, for instance). So this thread list may not be up to date
+ when the user attempts this task switch. Since we cannot switch
+ to the thread associated to our task if GDB does not know about
+ that thread, we need to make sure that any new threads gets added
+ to the thread list. */
+ target_find_new_threads ();
+
+ /* Verify that the ptid of the task we want to switch to is valid
+ (in other words, a ptid that GDB knows about). Otherwise, we will
+ cause an assertion failure later on, when we try to determine
+ the ptid associated thread_info data. We should normally never
+ encounter such an error, but the wrong ptid can actually easily be
+ computed if target_get_ada_task_ptid has not been implemented for
+ our target (yet). Rather than cause an assertion error in that case,
+ it's nicer for the user to just refuse to perform the task switch. */
+ if (!find_thread_ptid (task_info->ptid))
+ error (_("Unable to compute thread ID for task %d.\n"
+ "Cannot switch to this task."),
+ taskno);
+
switch_to_thread (task_info->ptid);
ada_find_printable_frame (get_selected_frame (NULL));
printf_filtered (_("[Switching to task %d]\n"), taskno);
/* Indicate that the task list may have changed, so invalidate the cache. */
-void
+static void
ada_task_list_changed (void)
{
stale_task_list_p = 1;
/* The 'normal_stop' observer notification callback. */
static void
-ada_normal_stop_observer (struct bpstats *unused_args)
+ada_normal_stop_observer (struct bpstats *unused_args, int unused_args2)
{
/* The inferior has been resumed, and just stopped. This means that
our task_list needs to be recomputed before it can be used again. */
/* A routine to be called when the objfiles have changed. */
-void
+static void
ada_new_objfile_observer (struct objfile *objfile)
{
/* Invalidate all cached data that were extracted from an objfile. */
ada_tasks_check_symbol_table = 1;
}
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_tasks;
+
void
_initialize_tasks (void)
{