GDB (API)
/home/stan/gdb/src/gdb/ada-tasks.c
Go to the documentation of this file.
00001 /* Copyright (C) 1992-2013 Free Software Foundation, Inc.
00002 
00003    This file is part of GDB.
00004 
00005    This program is free software; you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; either version 3 of the License, or
00008    (at your option) any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00017 
00018 #include "defs.h"
00019 #include "observer.h"
00020 #include "gdbcmd.h"
00021 #include "target.h"
00022 #include "ada-lang.h"
00023 #include "gdbcore.h"
00024 #include "inferior.h"
00025 #include "gdbthread.h"
00026 #include "progspace.h"
00027 #include "objfiles.h"
00028 
00029 /* The name of the array in the GNAT runtime where the Ada Task Control
00030    Block of each task is stored.  */
00031 #define KNOWN_TASKS_NAME "system__tasking__debug__known_tasks"
00032 
00033 /* The maximum number of tasks known to the Ada runtime.  */
00034 static const int MAX_NUMBER_OF_KNOWN_TASKS = 1000;
00035 
00036 /* The name of the variable in the GNAT runtime where the head of a task
00037    chain is saved.  This is an alternate mechanism to find the list of known
00038    tasks.  */
00039 #define KNOWN_TASKS_LIST "system__tasking__debug__first_task"
00040 
00041 enum task_states
00042 {
00043   Unactivated,
00044   Runnable,
00045   Terminated,
00046   Activator_Sleep,
00047   Acceptor_Sleep,
00048   Entry_Caller_Sleep,
00049   Async_Select_Sleep,
00050   Delay_Sleep,
00051   Master_Completion_Sleep,
00052   Master_Phase_2_Sleep,
00053   Interrupt_Server_Idle_Sleep,
00054   Interrupt_Server_Blocked_Interrupt_Sleep,
00055   Timer_Server_Sleep,
00056   AST_Server_Sleep,
00057   Asynchronous_Hold,
00058   Interrupt_Server_Blocked_On_Event_Flag,
00059   Activating,
00060   Acceptor_Delay_Sleep
00061 };
00062 
00063 /* A short description corresponding to each possible task state.  */
00064 static const char *task_states[] = {
00065   N_("Unactivated"),
00066   N_("Runnable"),
00067   N_("Terminated"),
00068   N_("Child Activation Wait"),
00069   N_("Accept or Select Term"),
00070   N_("Waiting on entry call"),
00071   N_("Async Select Wait"),
00072   N_("Delay Sleep"),
00073   N_("Child Termination Wait"),
00074   N_("Wait Child in Term Alt"),
00075   "",
00076   "",
00077   "",
00078   "",
00079   N_("Asynchronous Hold"),
00080   "",
00081   N_("Activating"),
00082   N_("Selective Wait")
00083 };
00084 
00085 /* A longer description corresponding to each possible task state.  */
00086 static const char *long_task_states[] = {
00087   N_("Unactivated"),
00088   N_("Runnable"),
00089   N_("Terminated"),
00090   N_("Waiting for child activation"),
00091   N_("Blocked in accept or select with terminate"),
00092   N_("Waiting on entry call"),
00093   N_("Asynchronous Selective Wait"),
00094   N_("Delay Sleep"),
00095   N_("Waiting for children termination"),
00096   N_("Waiting for children in terminate alternative"),
00097   "",
00098   "",
00099   "",
00100   "",
00101   N_("Asynchronous Hold"),
00102   "",
00103   N_("Activating"),
00104   N_("Blocked in selective wait statement")
00105 };
00106 
00107 /* The index of certain important fields in the Ada Task Control Block
00108    record and sub-records.  */
00109 
00110 struct atcb_fieldnos
00111 {
00112   /* Fields in record Ada_Task_Control_Block.  */
00113   int common;
00114   int entry_calls;
00115   int atc_nesting_level;
00116 
00117   /* Fields in record Common_ATCB.  */
00118   int state;
00119   int parent;
00120   int priority;
00121   int image;
00122   int image_len;     /* This field may be missing.  */
00123   int activation_link;
00124   int call;
00125   int ll;
00126 
00127   /* Fields in Task_Primitives.Private_Data.  */
00128   int ll_thread;
00129   int ll_lwp;        /* This field may be missing.  */
00130 
00131   /* Fields in Common_ATCB.Call.all.  */
00132   int call_self;
00133 };
00134 
00135 /* This module's per-program-space data.  */
00136 
00137 struct ada_tasks_pspace_data
00138 {
00139   /* Nonzero if the data has been initialized.  If set to zero,
00140      it means that the data has either not been initialized, or
00141      has potentially become stale.  */
00142   int initialized_p;
00143 
00144   /* The ATCB record type.  */
00145   struct type *atcb_type;
00146 
00147   /* The ATCB "Common" component type.  */
00148   struct type *atcb_common_type;
00149 
00150   /* The type of the "ll" field, from the atcb_common_type.  */
00151   struct type *atcb_ll_type;
00152 
00153   /* The type of the "call" field, from the atcb_common_type.  */
00154   struct type *atcb_call_type;
00155 
00156   /* The index of various fields in the ATCB record and sub-records.  */
00157   struct atcb_fieldnos atcb_fieldno;
00158 };
00159 
00160 /* Key to our per-program-space data.  */
00161 static const struct program_space_data *ada_tasks_pspace_data_handle;
00162 
00163 typedef struct ada_task_info ada_task_info_s;
00164 DEF_VEC_O(ada_task_info_s);
00165 
00166 /* The kind of data structure used by the runtime to store the list
00167    of Ada tasks.  */
00168 
00169 enum ada_known_tasks_kind
00170 {
00171   /* Use this value when we haven't determined which kind of structure
00172      is being used, or when we need to recompute it.
00173 
00174      We set the value of this enumerate to zero on purpose: This allows
00175      us to use this enumerate in a structure where setting all fields
00176      to zero will result in this kind being set to unknown.  */
00177   ADA_TASKS_UNKNOWN = 0,
00178 
00179   /* This value means that we did not find any task list.  Unless
00180      there is a bug somewhere, this means that the inferior does not
00181      use tasking.  */
00182   ADA_TASKS_NOT_FOUND,
00183 
00184   /* This value means that the task list is stored as an array.
00185      This is the usual method, as it causes very little overhead.
00186      But this method is not always used, as it does use a certain
00187      amount of memory, which might be scarse in certain environments.  */
00188   ADA_TASKS_ARRAY,
00189 
00190   /* This value means that the task list is stored as a linked list.
00191      This has more runtime overhead than the array approach, but
00192      also require less memory when the number of tasks is small.  */
00193   ADA_TASKS_LIST,
00194 };
00195 
00196 /* This module's per-inferior data.  */
00197 
00198 struct ada_tasks_inferior_data
00199 {
00200   /* The type of data structure used by the runtime to store
00201      the list of Ada tasks.  The value of this field influences
00202      the interpretation of the known_tasks_addr field below:
00203        - ADA_TASKS_UNKNOWN: The value of known_tasks_addr hasn't
00204          been determined yet;
00205        - ADA_TASKS_NOT_FOUND: The program probably does not use tasking
00206          and the known_tasks_addr is irrelevant;
00207        - ADA_TASKS_ARRAY: The known_tasks is an array;
00208        - ADA_TASKS_LIST: The known_tasks is a list.  */
00209   enum ada_known_tasks_kind known_tasks_kind;
00210 
00211   /* The address of the known_tasks structure.  This is where
00212      the runtime stores the information for all Ada tasks.
00213      The interpretation of this field depends on KNOWN_TASKS_KIND
00214      above.  */
00215   CORE_ADDR known_tasks_addr;
00216 
00217   /* Type of elements of the known task.  Usually a pointer.  */
00218   struct type *known_tasks_element;
00219 
00220   /* Number of elements in the known tasks array.  */
00221   unsigned int known_tasks_length;
00222 
00223   /* When nonzero, this flag indicates that the task_list field
00224      below is up to date.  When set to zero, the list has either
00225      not been initialized, or has potentially become stale.  */
00226   int task_list_valid_p;
00227 
00228   /* The list of Ada tasks.
00229 
00230      Note: To each task we associate a number that the user can use to
00231      reference it - this number is printed beside each task in the tasks
00232      info listing displayed by "info tasks".  This number is equal to
00233      its index in the vector + 1.  Reciprocally, to compute the index
00234      of a task in the vector, we need to substract 1 from its number.  */
00235   VEC(ada_task_info_s) *task_list;
00236 };
00237 
00238 /* Key to our per-inferior data.  */
00239 static const struct inferior_data *ada_tasks_inferior_data_handle;
00240 
00241 /* Return the ada-tasks module's data for the given program space (PSPACE).
00242    If none is found, add a zero'ed one now.
00243 
00244    This function always returns a valid object.  */
00245 
00246 static struct ada_tasks_pspace_data *
00247 get_ada_tasks_pspace_data (struct program_space *pspace)
00248 {
00249   struct ada_tasks_pspace_data *data;
00250 
00251   data = program_space_data (pspace, ada_tasks_pspace_data_handle);
00252   if (data == NULL)
00253     {
00254       data = XZALLOC (struct ada_tasks_pspace_data);
00255       set_program_space_data (pspace, ada_tasks_pspace_data_handle, data);
00256     }
00257 
00258   return data;
00259 }
00260 
00261 /* Return the ada-tasks module's data for the given inferior (INF).
00262    If none is found, add a zero'ed one now.
00263 
00264    This function always returns a valid object.
00265 
00266    Note that we could use an observer of the inferior-created event
00267    to make sure that the ada-tasks per-inferior data always exists.
00268    But we prefered this approach, as it avoids this entirely as long
00269    as the user does not use any of the tasking features.  This is
00270    quite possible, particularly in the case where the inferior does
00271    not use tasking.  */
00272 
00273 static struct ada_tasks_inferior_data *
00274 get_ada_tasks_inferior_data (struct inferior *inf)
00275 {
00276   struct ada_tasks_inferior_data *data;
00277 
00278   data = inferior_data (inf, ada_tasks_inferior_data_handle);
00279   if (data == NULL)
00280     {
00281       data = XZALLOC (struct ada_tasks_inferior_data);
00282       set_inferior_data (inf, ada_tasks_inferior_data_handle, data);
00283     }
00284 
00285   return data;
00286 }
00287 
00288 /* Return the task number of the task whose ptid is PTID, or zero
00289    if the task could not be found.  */
00290 
00291 int
00292 ada_get_task_number (ptid_t ptid)
00293 {
00294   int i;
00295   struct inferior *inf = find_inferior_pid (ptid_get_pid (ptid));
00296   struct ada_tasks_inferior_data *data;
00297 
00298   gdb_assert (inf != NULL);
00299   data = get_ada_tasks_inferior_data (inf);
00300 
00301   for (i = 0; i < VEC_length (ada_task_info_s, data->task_list); i++)
00302     if (ptid_equal (VEC_index (ada_task_info_s, data->task_list, i)->ptid,
00303                     ptid))
00304       return i + 1;
00305 
00306   return 0;  /* No matching task found.  */
00307 }
00308 
00309 /* Return the task number of the task running in inferior INF which
00310    matches TASK_ID , or zero if the task could not be found.  */
00311  
00312 static int
00313 get_task_number_from_id (CORE_ADDR task_id, struct inferior *inf)
00314 {
00315   struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);
00316   int i;
00317 
00318   for (i = 0; i < VEC_length (ada_task_info_s, data->task_list); i++)
00319     {
00320       struct ada_task_info *task_info =
00321         VEC_index (ada_task_info_s, data->task_list, i);
00322 
00323       if (task_info->task_id == task_id)
00324         return i + 1;
00325     }
00326 
00327   /* Task not found.  Return 0.  */
00328   return 0;
00329 }
00330 
00331 /* Return non-zero if TASK_NUM is a valid task number.  */
00332 
00333 int
00334 valid_task_id (int task_num)
00335 {
00336   struct ada_tasks_inferior_data *data;
00337 
00338   ada_build_task_list ();
00339   data = get_ada_tasks_inferior_data (current_inferior ());
00340   return (task_num > 0
00341           && task_num <= VEC_length (ada_task_info_s, data->task_list));
00342 }
00343 
00344 /* Return non-zero iff the task STATE corresponds to a non-terminated
00345    task state.  */
00346 
00347 static int
00348 ada_task_is_alive (struct ada_task_info *task_info)
00349 {
00350   return (task_info->state != Terminated);
00351 }
00352 
00353 /* Call the ITERATOR function once for each Ada task that hasn't been
00354    terminated yet.  */
00355 
00356 void
00357 iterate_over_live_ada_tasks (ada_task_list_iterator_ftype *iterator)
00358 {
00359   int i, nb_tasks;
00360   struct ada_task_info *task;
00361   struct ada_tasks_inferior_data *data;
00362 
00363   ada_build_task_list ();
00364   data = get_ada_tasks_inferior_data (current_inferior ());
00365   nb_tasks = VEC_length (ada_task_info_s, data->task_list);
00366 
00367   for (i = 0; i < nb_tasks; i++)
00368     {
00369       task = VEC_index (ada_task_info_s, data->task_list, i);
00370       if (!ada_task_is_alive (task))
00371         continue;
00372       iterator (task);
00373     }
00374 }
00375 
00376 /* Extract the contents of the value as a string whose length is LENGTH,
00377    and store the result in DEST.  */
00378 
00379 static void
00380 value_as_string (char *dest, struct value *val, int length)
00381 {
00382   memcpy (dest, value_contents (val), length);
00383   dest[length] = '\0';
00384 }
00385 
00386 /* Extract the string image from the fat string corresponding to VAL,
00387    and store it in DEST.  If the string length is greater than MAX_LEN,
00388    then truncate the result to the first MAX_LEN characters of the fat
00389    string.  */
00390 
00391 static void
00392 read_fat_string_value (char *dest, struct value *val, int max_len)
00393 {
00394   struct value *array_val;
00395   struct value *bounds_val;
00396   int len;
00397 
00398   /* The following variables are made static to avoid recomputing them
00399      each time this function is called.  */
00400   static int initialize_fieldnos = 1;
00401   static int array_fieldno;
00402   static int bounds_fieldno;
00403   static int upper_bound_fieldno;
00404 
00405   /* Get the index of the fields that we will need to read in order
00406      to extract the string from the fat string.  */
00407   if (initialize_fieldnos)
00408     {
00409       struct type *type = value_type (val);
00410       struct type *bounds_type;
00411 
00412       array_fieldno = ada_get_field_index (type, "P_ARRAY", 0);
00413       bounds_fieldno = ada_get_field_index (type, "P_BOUNDS", 0);
00414 
00415       bounds_type = TYPE_FIELD_TYPE (type, bounds_fieldno);
00416       if (TYPE_CODE (bounds_type) == TYPE_CODE_PTR)
00417         bounds_type = TYPE_TARGET_TYPE (bounds_type);
00418       if (TYPE_CODE (bounds_type) != TYPE_CODE_STRUCT)
00419         error (_("Unknown task name format. Aborting"));
00420       upper_bound_fieldno = ada_get_field_index (bounds_type, "UB0", 0);
00421 
00422       initialize_fieldnos = 0;
00423     }
00424 
00425   /* Get the size of the task image by checking the value of the bounds.
00426      The lower bound is always 1, so we only need to read the upper bound.  */
00427   bounds_val = value_ind (value_field (val, bounds_fieldno));
00428   len = value_as_long (value_field (bounds_val, upper_bound_fieldno));
00429 
00430   /* Make sure that we do not read more than max_len characters...  */
00431   if (len > max_len)
00432     len = max_len;
00433 
00434   /* Extract LEN characters from the fat string.  */
00435   array_val = value_ind (value_field (val, array_fieldno));
00436   read_memory (value_address (array_val), (gdb_byte *) dest, len);
00437 
00438   /* Add the NUL character to close the string.  */
00439   dest[len] = '\0';
00440 }
00441 
00442 /* Get from the debugging information the type description of all types
00443    related to the Ada Task Control Block that will be needed in order to
00444    read the list of known tasks in the Ada runtime.  Also return the
00445    associated ATCB_FIELDNOS.
00446 
00447    Error handling:  Any data missing from the debugging info will cause
00448    an error to be raised, and none of the return values to be set.
00449    Users of this function can depend on the fact that all or none of the
00450    return values will be set.  */
00451 
00452 static void
00453 get_tcb_types_info (void)
00454 {
00455   struct type *type;
00456   struct type *common_type;
00457   struct type *ll_type;
00458   struct type *call_type;
00459   struct atcb_fieldnos fieldnos;
00460   struct ada_tasks_pspace_data *pspace_data;
00461 
00462   const char *atcb_name = "system__tasking__ada_task_control_block___XVE";
00463   const char *atcb_name_fixed = "system__tasking__ada_task_control_block";
00464   const char *common_atcb_name = "system__tasking__common_atcb";
00465   const char *private_data_name = "system__task_primitives__private_data";
00466   const char *entry_call_record_name = "system__tasking__entry_call_record";
00467 
00468   /* ATCB symbols may be found in several compilation units.  As we
00469      are only interested in one instance, use standard (literal,
00470      C-like) lookups to get the first match.  */
00471 
00472   struct symbol *atcb_sym =
00473     lookup_symbol_in_language (atcb_name, NULL, VAR_DOMAIN,
00474                                language_c, NULL);
00475   const struct symbol *common_atcb_sym =
00476     lookup_symbol_in_language (common_atcb_name, NULL, VAR_DOMAIN,
00477                                language_c, NULL);
00478   const struct symbol *private_data_sym =
00479     lookup_symbol_in_language (private_data_name, NULL, VAR_DOMAIN,
00480                                language_c, NULL);
00481   const struct symbol *entry_call_record_sym =
00482     lookup_symbol_in_language (entry_call_record_name, NULL, VAR_DOMAIN,
00483                                language_c, NULL);
00484 
00485   if (atcb_sym == NULL || atcb_sym->type == NULL)
00486     {
00487       /* In Ravenscar run-time libs, the  ATCB does not have a dynamic
00488          size, so the symbol name differs.  */
00489       atcb_sym = lookup_symbol_in_language (atcb_name_fixed, NULL, VAR_DOMAIN,
00490                                             language_c, NULL);
00491 
00492       if (atcb_sym == NULL || atcb_sym->type == NULL)
00493         error (_("Cannot find Ada_Task_Control_Block type. Aborting"));
00494 
00495       type = atcb_sym->type;
00496     }
00497   else
00498     {
00499       /* Get a static representation of the type record
00500          Ada_Task_Control_Block.  */
00501       type = atcb_sym->type;
00502       type = ada_template_to_fixed_record_type_1 (type, NULL, 0, NULL, 0);
00503     }
00504 
00505   if (common_atcb_sym == NULL || common_atcb_sym->type == NULL)
00506     error (_("Cannot find Common_ATCB type. Aborting"));
00507   if (private_data_sym == NULL || private_data_sym->type == NULL)
00508     error (_("Cannot find Private_Data type. Aborting"));
00509   if (entry_call_record_sym == NULL || entry_call_record_sym->type == NULL)
00510     error (_("Cannot find Entry_Call_Record type. Aborting"));
00511 
00512   /* Get the type for Ada_Task_Control_Block.Common.  */
00513   common_type = common_atcb_sym->type;
00514 
00515   /* Get the type for Ada_Task_Control_Bloc.Common.Call.LL.  */
00516   ll_type = private_data_sym->type;
00517 
00518   /* Get the type for Common_ATCB.Call.all.  */
00519   call_type = entry_call_record_sym->type;
00520 
00521   /* Get the field indices.  */
00522   fieldnos.common = ada_get_field_index (type, "common", 0);
00523   fieldnos.entry_calls = ada_get_field_index (type, "entry_calls", 1);
00524   fieldnos.atc_nesting_level =
00525     ada_get_field_index (type, "atc_nesting_level", 1);
00526   fieldnos.state = ada_get_field_index (common_type, "state", 0);
00527   fieldnos.parent = ada_get_field_index (common_type, "parent", 1);
00528   fieldnos.priority = ada_get_field_index (common_type, "base_priority", 0);
00529   fieldnos.image = ada_get_field_index (common_type, "task_image", 1);
00530   fieldnos.image_len = ada_get_field_index (common_type, "task_image_len", 1);
00531   fieldnos.activation_link = ada_get_field_index (common_type,
00532                                                   "activation_link", 1);
00533   fieldnos.call = ada_get_field_index (common_type, "call", 1);
00534   fieldnos.ll = ada_get_field_index (common_type, "ll", 0);
00535   fieldnos.ll_thread = ada_get_field_index (ll_type, "thread", 0);
00536   fieldnos.ll_lwp = ada_get_field_index (ll_type, "lwp", 1);
00537   fieldnos.call_self = ada_get_field_index (call_type, "self", 0);
00538 
00539   /* On certain platforms such as x86-windows, the "lwp" field has been
00540      named "thread_id".  This field will likely be renamed in the future,
00541      but we need to support both possibilities to avoid an unnecessary
00542      dependency on a recent compiler.  We therefore try locating the
00543      "thread_id" field in place of the "lwp" field if we did not find
00544      the latter.  */
00545   if (fieldnos.ll_lwp < 0)
00546     fieldnos.ll_lwp = ada_get_field_index (ll_type, "thread_id", 1);
00547 
00548   /* Set all the out parameters all at once, now that we are certain
00549      that there are no potential error() anymore.  */
00550   pspace_data = get_ada_tasks_pspace_data (current_program_space);
00551   pspace_data->initialized_p = 1;
00552   pspace_data->atcb_type = type;
00553   pspace_data->atcb_common_type = common_type;
00554   pspace_data->atcb_ll_type = ll_type;
00555   pspace_data->atcb_call_type = call_type;
00556   pspace_data->atcb_fieldno = fieldnos;
00557 }
00558 
00559 /* Build the PTID of the task from its COMMON_VALUE, which is the "Common"
00560    component of its ATCB record.  This PTID needs to match the PTID used
00561    by the thread layer.  */
00562 
00563 static ptid_t
00564 ptid_from_atcb_common (struct value *common_value)
00565 {
00566   long thread = 0;
00567   CORE_ADDR lwp = 0;
00568   struct value *ll_value;
00569   ptid_t ptid;
00570   const struct ada_tasks_pspace_data *pspace_data
00571     = get_ada_tasks_pspace_data (current_program_space);
00572 
00573   ll_value = value_field (common_value, pspace_data->atcb_fieldno.ll);
00574 
00575   if (pspace_data->atcb_fieldno.ll_lwp >= 0)
00576     lwp = value_as_address (value_field (ll_value,
00577                                          pspace_data->atcb_fieldno.ll_lwp));
00578   thread = value_as_long (value_field (ll_value,
00579                                        pspace_data->atcb_fieldno.ll_thread));
00580 
00581   ptid = target_get_ada_task_ptid (lwp, thread);
00582 
00583   return ptid;
00584 }
00585 
00586 /* Read the ATCB data of a given task given its TASK_ID (which is in practice
00587    the address of its assocated ATCB record), and store the result inside
00588    TASK_INFO.  */
00589 
00590 static void
00591 read_atcb (CORE_ADDR task_id, struct ada_task_info *task_info)
00592 {
00593   struct value *tcb_value;
00594   struct value *common_value;
00595   struct value *atc_nesting_level_value;
00596   struct value *entry_calls_value;
00597   struct value *entry_calls_value_element;
00598   int called_task_fieldno = -1;
00599   static const char ravenscar_task_name[] = "Ravenscar task";
00600   const struct ada_tasks_pspace_data *pspace_data
00601     = get_ada_tasks_pspace_data (current_program_space);
00602 
00603   if (!pspace_data->initialized_p)
00604     get_tcb_types_info ();
00605 
00606   tcb_value = value_from_contents_and_address (pspace_data->atcb_type,
00607                                                NULL, task_id);
00608   common_value = value_field (tcb_value, pspace_data->atcb_fieldno.common);
00609 
00610   /* Fill in the task_id.  */
00611 
00612   task_info->task_id = task_id;
00613 
00614   /* Compute the name of the task.
00615 
00616      Depending on the GNAT version used, the task image is either a fat
00617      string, or a thin array of characters.  Older versions of GNAT used
00618      to use fat strings, and therefore did not need an extra field in
00619      the ATCB to store the string length.  For efficiency reasons, newer
00620      versions of GNAT replaced the fat string by a static buffer, but this
00621      also required the addition of a new field named "Image_Len" containing
00622      the length of the task name.  The method used to extract the task name
00623      is selected depending on the existence of this field.
00624 
00625      In some run-time libs (e.g. Ravenscar), the name is not in the ATCB;
00626      we may want to get it from the first user frame of the stack.  For now,
00627      we just give a dummy name.  */
00628 
00629   if (pspace_data->atcb_fieldno.image_len == -1)
00630     {
00631       if (pspace_data->atcb_fieldno.image >= 0)
00632         read_fat_string_value (task_info->name,
00633                                value_field (common_value,
00634                                             pspace_data->atcb_fieldno.image),
00635                                sizeof (task_info->name) - 1);
00636       else
00637         {
00638           struct bound_minimal_symbol msym;
00639 
00640           msym = lookup_minimal_symbol_by_pc (task_id);
00641           if (msym.minsym)
00642             {
00643               const char *full_name = SYMBOL_LINKAGE_NAME (msym.minsym);
00644               const char *task_name = full_name;
00645               const char *p;
00646 
00647               /* Strip the prefix.  */
00648               for (p = full_name; *p; p++)
00649                 if (p[0] == '_' && p[1] == '_')
00650                   task_name = p + 2;
00651 
00652               /* Copy the task name.  */
00653               strncpy (task_info->name, task_name, sizeof (task_info->name));
00654               task_info->name[sizeof (task_info->name) - 1] = 0;
00655             }
00656           else
00657             {
00658               /* No symbol found.  Use a default name.  */
00659               strcpy (task_info->name, ravenscar_task_name);
00660             }
00661         }
00662     }
00663   else
00664     {
00665       int len = value_as_long
00666                   (value_field (common_value,
00667                                 pspace_data->atcb_fieldno.image_len));
00668 
00669       value_as_string (task_info->name,
00670                        value_field (common_value,
00671                                     pspace_data->atcb_fieldno.image),
00672                        len);
00673     }
00674 
00675   /* Compute the task state and priority.  */
00676 
00677   task_info->state =
00678     value_as_long (value_field (common_value,
00679                                 pspace_data->atcb_fieldno.state));
00680   task_info->priority =
00681     value_as_long (value_field (common_value,
00682                                 pspace_data->atcb_fieldno.priority));
00683 
00684   /* If the ATCB contains some information about the parent task,
00685      then compute it as well.  Otherwise, zero.  */
00686 
00687   if (pspace_data->atcb_fieldno.parent >= 0)
00688     task_info->parent =
00689       value_as_address (value_field (common_value,
00690                                      pspace_data->atcb_fieldno.parent));
00691   else
00692     task_info->parent = 0;
00693   
00694 
00695   /* If the ATCB contains some information about entry calls, then
00696      compute the "called_task" as well.  Otherwise, zero.  */
00697 
00698   if (pspace_data->atcb_fieldno.atc_nesting_level > 0
00699       && pspace_data->atcb_fieldno.entry_calls > 0)
00700     {
00701       /* Let My_ATCB be the Ada task control block of a task calling the
00702          entry of another task; then the Task_Id of the called task is
00703          in My_ATCB.Entry_Calls (My_ATCB.ATC_Nesting_Level).Called_Task.  */
00704       atc_nesting_level_value =
00705         value_field (tcb_value, pspace_data->atcb_fieldno.atc_nesting_level);
00706       entry_calls_value =
00707         ada_coerce_to_simple_array_ptr
00708           (value_field (tcb_value, pspace_data->atcb_fieldno.entry_calls));
00709       entry_calls_value_element =
00710         value_subscript (entry_calls_value,
00711                          value_as_long (atc_nesting_level_value));
00712       called_task_fieldno =
00713         ada_get_field_index (value_type (entry_calls_value_element),
00714                              "called_task", 0);
00715       task_info->called_task =
00716         value_as_address (value_field (entry_calls_value_element,
00717                                        called_task_fieldno));
00718     }
00719   else
00720     {
00721       task_info->called_task = 0;
00722     }
00723 
00724   /* If the ATCB cotnains some information about RV callers,
00725      then compute the "caller_task".  Otherwise, zero.  */
00726 
00727   task_info->caller_task = 0;
00728   if (pspace_data->atcb_fieldno.call >= 0)
00729     {
00730       /* Get the ID of the caller task from Common_ATCB.Call.all.Self.
00731          If Common_ATCB.Call is null, then there is no caller.  */
00732       const CORE_ADDR call =
00733         value_as_address (value_field (common_value,
00734                                        pspace_data->atcb_fieldno.call));
00735       struct value *call_val;
00736 
00737       if (call != 0)
00738         {
00739           call_val =
00740             value_from_contents_and_address (pspace_data->atcb_call_type,
00741                                              NULL, call);
00742           task_info->caller_task =
00743             value_as_address
00744               (value_field (call_val, pspace_data->atcb_fieldno.call_self));
00745         }
00746     }
00747 
00748   /* And finally, compute the task ptid.  Note that there are situations
00749      where this cannot be determined:
00750        - The task is no longer alive - the ptid is irrelevant;
00751        - We are debugging a core file - the thread is not always
00752          completely preserved for us to link back a task to its
00753          underlying thread.  Since we do not support task switching
00754          when debugging core files anyway, we don't need to compute
00755          that task ptid.
00756      In either case, we don't need that ptid, and it is just good enough
00757      to set it to null_ptid.  */
00758 
00759   if (target_has_execution && ada_task_is_alive (task_info))
00760     task_info->ptid = ptid_from_atcb_common (common_value);
00761   else
00762     task_info->ptid = null_ptid;
00763 }
00764 
00765 /* Read the ATCB info of the given task (identified by TASK_ID), and
00766    add the result to the given inferior's TASK_LIST.  */
00767 
00768 static void
00769 add_ada_task (CORE_ADDR task_id, struct inferior *inf)
00770 {
00771   struct ada_task_info task_info;
00772   struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);
00773 
00774   read_atcb (task_id, &task_info);
00775   VEC_safe_push (ada_task_info_s, data->task_list, &task_info);
00776 }
00777 
00778 /* Read the Known_Tasks array from the inferior memory, and store
00779    it in the current inferior's TASK_LIST.  Return non-zero upon success.  */
00780 
00781 static int
00782 read_known_tasks_array (struct ada_tasks_inferior_data *data)
00783 {
00784   const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
00785   const int known_tasks_size = target_ptr_byte * data->known_tasks_length;
00786   gdb_byte *known_tasks = alloca (known_tasks_size);
00787   int i;
00788 
00789   /* Build a new list by reading the ATCBs from the Known_Tasks array
00790      in the Ada runtime.  */
00791   read_memory (data->known_tasks_addr, known_tasks, known_tasks_size);
00792   for (i = 0; i < data->known_tasks_length; i++)
00793     {
00794       CORE_ADDR task_id =
00795         extract_typed_address (known_tasks + i * target_ptr_byte,
00796                                data->known_tasks_element);
00797 
00798       if (task_id != 0)
00799         add_ada_task (task_id, current_inferior ());
00800     }
00801 
00802   return 1;
00803 }
00804 
00805 /* Read the known tasks from the inferior memory, and store it in
00806    the current inferior's TASK_LIST.  Return non-zero upon success.  */
00807 
00808 static int
00809 read_known_tasks_list (struct ada_tasks_inferior_data *data)
00810 {
00811   const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
00812   gdb_byte *known_tasks = alloca (target_ptr_byte);
00813   CORE_ADDR task_id;
00814   const struct ada_tasks_pspace_data *pspace_data
00815     = get_ada_tasks_pspace_data (current_program_space);
00816 
00817   /* Sanity check.  */
00818   if (pspace_data->atcb_fieldno.activation_link < 0)
00819     return 0;
00820 
00821   /* Build a new list by reading the ATCBs.  Read head of the list.  */
00822   read_memory (data->known_tasks_addr, known_tasks, target_ptr_byte);
00823   task_id = extract_typed_address (known_tasks, data->known_tasks_element);
00824   while (task_id != 0)
00825     {
00826       struct value *tcb_value;
00827       struct value *common_value;
00828 
00829       add_ada_task (task_id, current_inferior ());
00830 
00831       /* Read the chain.  */
00832       tcb_value = value_from_contents_and_address (pspace_data->atcb_type,
00833                                                    NULL, task_id);
00834       common_value = value_field (tcb_value, pspace_data->atcb_fieldno.common);
00835       task_id = value_as_address
00836                   (value_field (common_value,
00837                                 pspace_data->atcb_fieldno.activation_link));
00838     }
00839 
00840   return 1;
00841 }
00842 
00843 /* Set all fields of the current inferior ada-tasks data pointed by DATA.
00844    Do nothing if those fields are already set and still up to date.  */
00845 
00846 static void
00847 ada_tasks_inferior_data_sniffer (struct ada_tasks_inferior_data *data)
00848 {
00849   struct minimal_symbol *msym;
00850   struct symbol *sym;
00851 
00852   /* Return now if already set.  */
00853   if (data->known_tasks_kind != ADA_TASKS_UNKNOWN)
00854     return;
00855 
00856   /* Try array.  */
00857 
00858   msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL);
00859   if (msym != NULL)
00860     {
00861       data->known_tasks_kind = ADA_TASKS_ARRAY;
00862       data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
00863 
00864       /* Try to get pointer type and array length from the symtab.  */
00865       sym = lookup_symbol_in_language (KNOWN_TASKS_NAME, NULL, VAR_DOMAIN,
00866                                        language_c, NULL);
00867       if (sym != NULL)
00868         {
00869           /* Validate.  */
00870           struct type *type = check_typedef (SYMBOL_TYPE (sym));
00871           struct type *eltype = NULL;
00872           struct type *idxtype = NULL;
00873 
00874           if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
00875             eltype = check_typedef (TYPE_TARGET_TYPE (type));
00876           if (eltype != NULL
00877               && TYPE_CODE (eltype) == TYPE_CODE_PTR)
00878             idxtype = check_typedef (TYPE_INDEX_TYPE (type));
00879           if (idxtype != NULL
00880               && !TYPE_LOW_BOUND_UNDEFINED (idxtype)
00881               && !TYPE_HIGH_BOUND_UNDEFINED (idxtype))
00882             {
00883               data->known_tasks_element = eltype;
00884               data->known_tasks_length =
00885                 TYPE_HIGH_BOUND (idxtype) - TYPE_LOW_BOUND (idxtype) + 1;
00886               return;
00887             }
00888         }
00889 
00890       /* Fallback to default values.  The runtime may have been stripped (as
00891          in some distributions), but it is likely that the executable still
00892          contains debug information on the task type (due to implicit with of
00893          Ada.Tasking).  */
00894       data->known_tasks_element =
00895         builtin_type (target_gdbarch ())->builtin_data_ptr;
00896       data->known_tasks_length = MAX_NUMBER_OF_KNOWN_TASKS;
00897       return;
00898     }
00899 
00900 
00901   /* Try list.  */
00902 
00903   msym = lookup_minimal_symbol (KNOWN_TASKS_LIST, NULL, NULL);
00904   if (msym != NULL)
00905     {
00906       data->known_tasks_kind = ADA_TASKS_LIST;
00907       data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
00908       data->known_tasks_length = 1;
00909 
00910       sym = lookup_symbol_in_language (KNOWN_TASKS_LIST, NULL, VAR_DOMAIN,
00911                                        language_c, NULL);
00912       if (sym != NULL && SYMBOL_VALUE_ADDRESS (sym) != 0)
00913         {
00914           /* Validate.  */
00915           struct type *type = check_typedef (SYMBOL_TYPE (sym));
00916 
00917           if (TYPE_CODE (type) == TYPE_CODE_PTR)
00918             {
00919               data->known_tasks_element = type;
00920               return;
00921             }
00922         }
00923 
00924       /* Fallback to default values.  */
00925       data->known_tasks_element =
00926         builtin_type (target_gdbarch ())->builtin_data_ptr;
00927       data->known_tasks_length = 1;
00928       return;
00929     }
00930 
00931   /* Can't find tasks.  */
00932 
00933   data->known_tasks_kind = ADA_TASKS_NOT_FOUND;
00934   data->known_tasks_addr = 0;
00935 }
00936 
00937 /* Read the known tasks from the current inferior's memory, and store it
00938    in the current inferior's data TASK_LIST.
00939    Return non-zero upon success.  */
00940 
00941 static int
00942 read_known_tasks (void)
00943 {
00944   struct ada_tasks_inferior_data *data =
00945     get_ada_tasks_inferior_data (current_inferior ());
00946 
00947   /* Step 1: Clear the current list, if necessary.  */
00948   VEC_truncate (ada_task_info_s, data->task_list, 0);
00949 
00950   /* Step 2: do the real work.
00951      If the application does not use task, then no more needs to be done.
00952      It is important to have the task list cleared (see above) before we
00953      return, as we don't want a stale task list to be used...  This can
00954      happen for instance when debugging a non-multitasking program after
00955      having debugged a multitasking one.  */
00956   ada_tasks_inferior_data_sniffer (data);
00957   gdb_assert (data->known_tasks_kind != ADA_TASKS_UNKNOWN);
00958 
00959   switch (data->known_tasks_kind)
00960     {
00961       case ADA_TASKS_NOT_FOUND: /* Tasking not in use in inferior.  */
00962         return 0;
00963       case ADA_TASKS_ARRAY:
00964         return read_known_tasks_array (data);
00965       case ADA_TASKS_LIST:
00966         return read_known_tasks_list (data);
00967     }
00968 
00969   /* Step 3: Set task_list_valid_p, to avoid re-reading the Known_Tasks
00970      array unless needed.  Then report a success.  */
00971   data->task_list_valid_p = 1;
00972 
00973   return 1;
00974 }
00975 
00976 /* Build the task_list by reading the Known_Tasks array from
00977    the inferior, and return the number of tasks in that list
00978    (zero means that the program is not using tasking at all).  */
00979 
00980 int
00981 ada_build_task_list (void)
00982 {
00983   struct ada_tasks_inferior_data *data;
00984 
00985   if (!target_has_stack)
00986     error (_("Cannot inspect Ada tasks when program is not running"));
00987 
00988   data = get_ada_tasks_inferior_data (current_inferior ());
00989   if (!data->task_list_valid_p)
00990     read_known_tasks ();
00991 
00992   return VEC_length (ada_task_info_s, data->task_list);
00993 }
00994 
00995 /* Print a table providing a short description of all Ada tasks
00996    running inside inferior INF.  If ARG_STR is set, it will be
00997    interpreted as a task number, and the table will be limited to
00998    that task only.  */
00999 
01000 void
01001 print_ada_task_info (struct ui_out *uiout,
01002                      char *arg_str,
01003                      struct inferior *inf)
01004 {
01005   struct ada_tasks_inferior_data *data;
01006   int taskno, nb_tasks;
01007   int taskno_arg = 0;
01008   struct cleanup *old_chain;
01009   int nb_columns;
01010 
01011   if (ada_build_task_list () == 0)
01012     {
01013       ui_out_message (uiout, 0,
01014                       _("Your application does not use any Ada tasks.\n"));
01015       return;
01016     }
01017 
01018   if (arg_str != NULL && arg_str[0] != '\0')
01019     taskno_arg = value_as_long (parse_and_eval (arg_str));
01020 
01021   if (ui_out_is_mi_like_p (uiout))
01022     /* In GDB/MI mode, we want to provide the thread ID corresponding
01023        to each task.  This allows clients to quickly find the thread
01024        associated to any task, which is helpful for commands that
01025        take a --thread argument.  However, in order to be able to
01026        provide that thread ID, the thread list must be up to date
01027        first.  */
01028     target_find_new_threads ();
01029 
01030   data = get_ada_tasks_inferior_data (inf);
01031 
01032   /* Compute the number of tasks that are going to be displayed
01033      in the output.  If an argument was given, there will be
01034      at most 1 entry.  Otherwise, there will be as many entries
01035      as we have tasks.  */
01036   if (taskno_arg)
01037     {
01038       if (taskno_arg > 0
01039           && taskno_arg <= VEC_length (ada_task_info_s, data->task_list))
01040         nb_tasks = 1;
01041       else
01042         nb_tasks = 0;
01043     }
01044   else
01045     nb_tasks = VEC_length (ada_task_info_s, data->task_list);
01046 
01047   nb_columns = ui_out_is_mi_like_p (uiout) ? 8 : 7;
01048   old_chain = make_cleanup_ui_out_table_begin_end (uiout, nb_columns,
01049                                                    nb_tasks, "tasks");
01050   ui_out_table_header (uiout, 1, ui_left, "current", "");
01051   ui_out_table_header (uiout, 3, ui_right, "id", "ID");
01052   ui_out_table_header (uiout, 9, ui_right, "task-id", "TID");
01053   /* The following column is provided in GDB/MI mode only because
01054      it is only really useful in that mode, and also because it
01055      allows us to keep the CLI output shorter and more compact.  */
01056   if (ui_out_is_mi_like_p (uiout))
01057     ui_out_table_header (uiout, 4, ui_right, "thread-id", "");
01058   ui_out_table_header (uiout, 4, ui_right, "parent-id", "P-ID");
01059   ui_out_table_header (uiout, 3, ui_right, "priority", "Pri");
01060   ui_out_table_header (uiout, 22, ui_left, "state", "State");
01061   /* Use ui_noalign for the last column, to prevent the CLI uiout
01062      from printing an extra space at the end of each row.  This
01063      is a bit of a hack, but does get the job done.  */
01064   ui_out_table_header (uiout, 1, ui_noalign, "name", "Name");
01065   ui_out_table_body (uiout);
01066 
01067   for (taskno = 1;
01068        taskno <= VEC_length (ada_task_info_s, data->task_list);
01069        taskno++)
01070     {
01071       const struct ada_task_info *const task_info =
01072         VEC_index (ada_task_info_s, data->task_list, taskno - 1);
01073       int parent_id;
01074       struct cleanup *chain2;
01075 
01076       gdb_assert (task_info != NULL);
01077 
01078       /* If the user asked for the output to be restricted
01079          to one task only, and this is not the task, skip
01080          to the next one.  */
01081       if (taskno_arg && taskno != taskno_arg)
01082         continue;
01083 
01084       chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
01085 
01086       /* Print a star if this task is the current task (or the task
01087          currently selected).  */
01088       if (ptid_equal (task_info->ptid, inferior_ptid))
01089         ui_out_field_string (uiout, "current", "*");
01090       else
01091         ui_out_field_skip (uiout, "current");
01092 
01093       /* Print the task number.  */
01094       ui_out_field_int (uiout, "id", taskno);
01095 
01096       /* Print the Task ID.  */
01097       ui_out_field_fmt (uiout, "task-id", "%9lx", (long) task_info->task_id);
01098 
01099       /* Print the associated Thread ID.  */
01100       if (ui_out_is_mi_like_p (uiout))
01101         {
01102           const int thread_id = pid_to_thread_id (task_info->ptid);
01103 
01104           if (thread_id != 0)
01105             ui_out_field_int (uiout, "thread-id", thread_id);
01106           else
01107             /* This should never happen unless there is a bug somewhere,
01108                but be resilient when that happens.  */
01109             ui_out_field_skip (uiout, "thread-id");
01110         }
01111 
01112       /* Print the ID of the parent task.  */
01113       parent_id = get_task_number_from_id (task_info->parent, inf);
01114       if (parent_id)
01115         ui_out_field_int (uiout, "parent-id", parent_id);
01116       else
01117         ui_out_field_skip (uiout, "parent-id");
01118 
01119       /* Print the base priority of the task.  */
01120       ui_out_field_int (uiout, "priority", task_info->priority);
01121 
01122       /* Print the task current state.  */
01123       if (task_info->caller_task)
01124         ui_out_field_fmt (uiout, "state",
01125                           _("Accepting RV with %-4d"),
01126                           get_task_number_from_id (task_info->caller_task,
01127                                                    inf));
01128       else if (task_info->state == Entry_Caller_Sleep
01129                && task_info->called_task)
01130         ui_out_field_fmt (uiout, "state",
01131                           _("Waiting on RV with %-3d"),
01132                           get_task_number_from_id (task_info->called_task,
01133                                                    inf));
01134       else
01135         ui_out_field_string (uiout, "state", task_states[task_info->state]);
01136 
01137       /* Finally, print the task name.  */
01138       ui_out_field_fmt (uiout, "name",
01139                         "%s",
01140                         task_info->name[0] != '\0' ? task_info->name
01141                                                    : _("<no name>"));
01142 
01143       ui_out_text (uiout, "\n");
01144       do_cleanups (chain2);
01145     }
01146 
01147   do_cleanups (old_chain);
01148 }
01149 
01150 /* Print a detailed description of the Ada task whose ID is TASKNO_STR
01151    for the given inferior (INF).  */
01152 
01153 static void
01154 info_task (struct ui_out *uiout, char *taskno_str, struct inferior *inf)
01155 {
01156   const int taskno = value_as_long (parse_and_eval (taskno_str));
01157   struct ada_task_info *task_info;
01158   int parent_taskno = 0;
01159   struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);
01160 
01161   if (ada_build_task_list () == 0)
01162     {
01163       ui_out_message (uiout, 0,
01164                       _("Your application does not use any Ada tasks.\n"));
01165       return;
01166     }
01167 
01168   if (taskno <= 0 || taskno > VEC_length (ada_task_info_s, data->task_list))
01169     error (_("Task ID %d not known.  Use the \"info tasks\" command to\n"
01170              "see the IDs of currently known tasks"), taskno);
01171   task_info = VEC_index (ada_task_info_s, data->task_list, taskno - 1);
01172 
01173   /* Print the Ada task ID.  */
01174   printf_filtered (_("Ada Task: %s\n"),
01175                    paddress (target_gdbarch (), task_info->task_id));
01176 
01177   /* Print the name of the task.  */
01178   if (task_info->name[0] != '\0')
01179     printf_filtered (_("Name: %s\n"), task_info->name);
01180   else
01181     printf_filtered (_("<no name>\n"));
01182 
01183   /* Print the TID and LWP.  */
01184   printf_filtered (_("Thread: %#lx\n"), ptid_get_tid (task_info->ptid));
01185   printf_filtered (_("LWP: %#lx\n"), ptid_get_lwp (task_info->ptid));
01186 
01187   /* Print who is the parent (if any).  */
01188   if (task_info->parent != 0)
01189     parent_taskno = get_task_number_from_id (task_info->parent, inf);
01190   if (parent_taskno)
01191     {
01192       struct ada_task_info *parent =
01193         VEC_index (ada_task_info_s, data->task_list, parent_taskno - 1);
01194 
01195       printf_filtered (_("Parent: %d"), parent_taskno);
01196       if (parent->name[0] != '\0')
01197         printf_filtered (" (%s)", parent->name);
01198       printf_filtered ("\n");
01199     }
01200   else
01201     printf_filtered (_("No parent\n"));
01202 
01203   /* Print the base priority.  */
01204   printf_filtered (_("Base Priority: %d\n"), task_info->priority);
01205 
01206   /* print the task current state.  */
01207   {
01208     int target_taskno = 0;
01209 
01210     if (task_info->caller_task)
01211       {
01212         target_taskno = get_task_number_from_id (task_info->caller_task, inf);
01213         printf_filtered (_("State: Accepting rendezvous with %d"),
01214                          target_taskno);
01215       }
01216     else if (task_info->state == Entry_Caller_Sleep && task_info->called_task)
01217       {
01218         target_taskno = get_task_number_from_id (task_info->called_task, inf);
01219         printf_filtered (_("State: Waiting on task %d's entry"),
01220                          target_taskno);
01221       }
01222     else
01223       printf_filtered (_("State: %s"), _(long_task_states[task_info->state]));
01224 
01225     if (target_taskno)
01226       {
01227         struct ada_task_info *target_task_info =
01228           VEC_index (ada_task_info_s, data->task_list, target_taskno - 1);
01229 
01230         if (target_task_info->name[0] != '\0')
01231           printf_filtered (" (%s)", target_task_info->name);
01232       }
01233 
01234     printf_filtered ("\n");
01235   }
01236 }
01237 
01238 /* If ARG is empty or null, then print a list of all Ada tasks.
01239    Otherwise, print detailed information about the task whose ID
01240    is ARG.
01241    
01242    Does nothing if the program doesn't use Ada tasking.  */
01243 
01244 static void
01245 info_tasks_command (char *arg, int from_tty)
01246 {
01247   struct ui_out *uiout = current_uiout;
01248 
01249   if (arg == NULL || *arg == '\0')
01250     print_ada_task_info (uiout, NULL, current_inferior ());
01251   else
01252     info_task (uiout, arg, current_inferior ());
01253 }
01254 
01255 /* Print a message telling the user id of the current task.
01256    This function assumes that tasking is in use in the inferior.  */
01257 
01258 static void
01259 display_current_task_id (void)
01260 {
01261   const int current_task = ada_get_task_number (inferior_ptid);
01262 
01263   if (current_task == 0)
01264     printf_filtered (_("[Current task is unknown]\n"));
01265   else
01266     printf_filtered (_("[Current task is %d]\n"), current_task);
01267 }
01268 
01269 /* Parse and evaluate TIDSTR into a task id, and try to switch to
01270    that task.  Print an error message if the task switch failed.  */
01271 
01272 static void
01273 task_command_1 (char *taskno_str, int from_tty, struct inferior *inf)
01274 {
01275   const int taskno = value_as_long (parse_and_eval (taskno_str));
01276   struct ada_task_info *task_info;
01277   struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);
01278 
01279   if (taskno <= 0 || taskno > VEC_length (ada_task_info_s, data->task_list))
01280     error (_("Task ID %d not known.  Use the \"info tasks\" command to\n"
01281              "see the IDs of currently known tasks"), taskno);
01282   task_info = VEC_index (ada_task_info_s, data->task_list, taskno - 1);
01283 
01284   if (!ada_task_is_alive (task_info))
01285     error (_("Cannot switch to task %d: Task is no longer running"), taskno);
01286    
01287   /* On some platforms, the thread list is not updated until the user
01288      performs a thread-related operation (by using the "info threads"
01289      command, for instance).  So this thread list may not be up to date
01290      when the user attempts this task switch.  Since we cannot switch
01291      to the thread associated to our task if GDB does not know about
01292      that thread, we need to make sure that any new threads gets added
01293      to the thread list.  */
01294   target_find_new_threads ();
01295 
01296   /* Verify that the ptid of the task we want to switch to is valid
01297      (in other words, a ptid that GDB knows about).  Otherwise, we will
01298      cause an assertion failure later on, when we try to determine
01299      the ptid associated thread_info data.  We should normally never
01300      encounter such an error, but the wrong ptid can actually easily be
01301      computed if target_get_ada_task_ptid has not been implemented for
01302      our target (yet).  Rather than cause an assertion error in that case,
01303      it's nicer for the user to just refuse to perform the task switch.  */
01304   if (!find_thread_ptid (task_info->ptid))
01305     error (_("Unable to compute thread ID for task %d.\n"
01306              "Cannot switch to this task."),
01307            taskno);
01308 
01309   switch_to_thread (task_info->ptid);
01310   ada_find_printable_frame (get_selected_frame (NULL));
01311   printf_filtered (_("[Switching to task %d]\n"), taskno);
01312   print_stack_frame (get_selected_frame (NULL),
01313                      frame_relative_level (get_selected_frame (NULL)),
01314                      SRC_AND_LOC, 1);
01315 }
01316 
01317 
01318 /* Print the ID of the current task if TASKNO_STR is empty or NULL.
01319    Otherwise, switch to the task indicated by TASKNO_STR.  */
01320 
01321 static void
01322 task_command (char *taskno_str, int from_tty)
01323 {
01324   struct ui_out *uiout = current_uiout;
01325 
01326   if (ada_build_task_list () == 0)
01327     {
01328       ui_out_message (uiout, 0,
01329                       _("Your application does not use any Ada tasks.\n"));
01330       return;
01331     }
01332 
01333   if (taskno_str == NULL || taskno_str[0] == '\0')
01334     display_current_task_id ();
01335   else
01336     {
01337       /* Task switching in core files doesn't work, either because:
01338            1. Thread support is not implemented with core files
01339            2. Thread support is implemented, but the thread IDs created
01340               after having read the core file are not the same as the ones
01341               that were used during the program life, before the crash.
01342               As a consequence, there is no longer a way for the debugger
01343               to find the associated thead ID of any given Ada task.
01344          So, instead of attempting a task switch without giving the user
01345          any clue as to what might have happened, just error-out with
01346          a message explaining that this feature is not supported.  */
01347       if (!target_has_execution)
01348         error (_("\
01349 Task switching not supported when debugging from core files\n\
01350 (use thread support instead)"));
01351       task_command_1 (taskno_str, from_tty, current_inferior ());
01352     }
01353 }
01354 
01355 /* Indicate that the given inferior's task list may have changed,
01356    so invalidate the cache.  */
01357 
01358 static void
01359 ada_task_list_changed (struct inferior *inf)
01360 {
01361   struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);
01362 
01363   data->task_list_valid_p = 0;
01364 }
01365 
01366 /* Invalidate the per-program-space data.  */
01367 
01368 static void
01369 ada_tasks_invalidate_pspace_data (struct program_space *pspace)
01370 {
01371   get_ada_tasks_pspace_data (pspace)->initialized_p = 0;
01372 }
01373 
01374 /* Invalidate the per-inferior data.  */
01375 
01376 static void
01377 ada_tasks_invalidate_inferior_data (struct inferior *inf)
01378 {
01379   struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);
01380 
01381   data->known_tasks_kind = ADA_TASKS_UNKNOWN;
01382   data->task_list_valid_p = 0;
01383 }
01384 
01385 /* The 'normal_stop' observer notification callback.  */
01386 
01387 static void
01388 ada_normal_stop_observer (struct bpstats *unused_args, int unused_args2)
01389 {
01390   /* The inferior has been resumed, and just stopped. This means that
01391      our task_list needs to be recomputed before it can be used again.  */
01392   ada_task_list_changed (current_inferior ());
01393 }
01394 
01395 /* A routine to be called when the objfiles have changed.  */
01396 
01397 static void
01398 ada_new_objfile_observer (struct objfile *objfile)
01399 {
01400   struct inferior *inf;
01401 
01402   /* Invalidate the relevant data in our program-space data.  */
01403 
01404   if (objfile == NULL)
01405     {
01406       /* All objfiles are being cleared, so we should clear all
01407          our caches for all program spaces.  */
01408       struct program_space *pspace;
01409 
01410       for (pspace = program_spaces; pspace != NULL; pspace = pspace->next)
01411         ada_tasks_invalidate_pspace_data (pspace);
01412     }
01413   else
01414     {
01415       /* The associated program-space data might have changed after
01416          this objfile was added.  Invalidate all cached data.  */
01417       ada_tasks_invalidate_pspace_data (objfile->pspace);
01418     }
01419 
01420   /* Invalidate the per-inferior cache for all inferiors using
01421      this objfile (or, in other words, for all inferiors who have
01422      the same program-space as the objfile's program space).
01423      If all objfiles are being cleared (OBJFILE is NULL), then
01424      clear the caches for all inferiors.  */
01425 
01426   for (inf = inferior_list; inf != NULL; inf = inf->next)
01427     if (objfile == NULL || inf->pspace == objfile->pspace)
01428       ada_tasks_invalidate_inferior_data (inf);
01429 }
01430 
01431 /* Provide a prototype to silence -Wmissing-prototypes.  */
01432 extern initialize_file_ftype _initialize_tasks;
01433 
01434 void
01435 _initialize_tasks (void)
01436 {
01437   ada_tasks_pspace_data_handle = register_program_space_data ();
01438   ada_tasks_inferior_data_handle = register_inferior_data ();
01439 
01440   /* Attach various observers.  */
01441   observer_attach_normal_stop (ada_normal_stop_observer);
01442   observer_attach_new_objfile (ada_new_objfile_observer);
01443 
01444   /* Some new commands provided by this module.  */
01445   add_info ("tasks", info_tasks_command,
01446             _("Provide information about all known Ada tasks"));
01447   add_cmd ("task", class_run, task_command,
01448            _("Use this command to switch between Ada tasks.\n\
01449 Without argument, this command simply prints the current task ID"),
01450            &cmdlist);
01451 }
01452 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines