Fix a build failure on Darwin following some changes in
[deliverable/binutils-gdb.git] / gdb / ada-tasks.c
CommitLineData
0fb0cc75
JB
1/* Copyright (C) 1992, 1993, 1994, 1997, 1998, 1999, 2000, 2003, 2004, 2005,
2 2007, 2008, 2009 Free Software Foundation, Inc.
0ef643c8
JB
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#include "defs.h"
20#include "observer.h"
21#include "gdbcmd.h"
22#include "target.h"
23#include "ada-lang.h"
24#include "gdbcore.h"
25#include "inferior.h"
26#include "gdbthread.h"
27
28/* The name of the array in the GNAT runtime where the Ada Task Control
29 Block of each task is stored. */
30#define KNOWN_TASKS_NAME "system__tasking__debug__known_tasks"
31
32/* The maximum number of tasks known to the Ada runtime */
33static const int MAX_NUMBER_OF_KNOWN_TASKS = 1000;
34
35enum task_states
36{
37 Unactivated,
38 Runnable,
39 Terminated,
40 Activator_Sleep,
41 Acceptor_Sleep,
42 Entry_Caller_Sleep,
43 Async_Select_Sleep,
44 Delay_Sleep,
45 Master_Completion_Sleep,
46 Master_Phase_2_Sleep,
47 Interrupt_Server_Idle_Sleep,
48 Interrupt_Server_Blocked_Interrupt_Sleep,
49 Timer_Server_Sleep,
50 AST_Server_Sleep,
51 Asynchronous_Hold,
52 Interrupt_Server_Blocked_On_Event_Flag
53};
54
55/* A short description corresponding to each possible task state. */
d6b67a5e
JK
56static const char *task_states[] = {
57 N_("Unactivated"),
58 N_("Runnable"),
59 N_("Terminated"),
60 N_("Child Activation Wait"),
61 N_("Accept Statement"),
62 N_("Waiting on entry call"),
63 N_("Async Select Wait"),
64 N_("Delay Sleep"),
65 N_("Child Termination Wait"),
66 N_("Wait Child in Term Alt"),
0ef643c8
JB
67 "",
68 "",
69 "",
70 "",
d6b67a5e 71 N_("Asynchronous Hold"),
0ef643c8
JB
72 ""
73};
74
75/* A longer description corresponding to each possible task state. */
d6b67a5e
JK
76static const char *long_task_states[] = {
77 N_("Unactivated"),
78 N_("Runnable"),
79 N_("Terminated"),
80 N_("Waiting for child activation"),
81 N_("Blocked in accept statement"),
82 N_("Waiting on entry call"),
83 N_("Asynchronous Selective Wait"),
84 N_("Delay Sleep"),
85 N_("Waiting for children termination"),
86 N_("Waiting for children in terminate alternative"),
0ef643c8
JB
87 "",
88 "",
89 "",
90 "",
d6b67a5e 91 N_("Asynchronous Hold"),
0ef643c8
JB
92 ""
93};
94
95/* The index of certain important fields in the Ada Task Control Block
96 record and sub-records. */
97
98struct tcb_fieldnos
99{
100 /* Fields in record Ada_Task_Control_Block. */
101 int common;
102 int entry_calls;
103 int atc_nesting_level;
104
105 /* Fields in record Common_ATCB. */
106 int state;
107 int parent;
108 int priority;
109 int image;
110 int image_len; /* This field may be missing. */
111 int call;
112 int ll;
113
114 /* Fields in Task_Primitives.Private_Data. */
115 int ll_thread;
116 int ll_lwp; /* This field may be missing. */
117
118 /* Fields in Common_ATCB.Call.all. */
119 int call_self;
120};
121
122/* The type description for the ATCB record and subrecords, and
123 the associated tcb_fieldnos. For efficiency reasons, these are made
124 static globals so that we can compute them only once the first time
125 and reuse them later. Set to NULL if the types haven't been computed
126 yet, or if they may be obsolete (for instance after having loaded
127 a new binary). */
128
129static struct type *atcb_type = NULL;
130static struct type *atcb_common_type = NULL;
131static struct type *atcb_ll_type = NULL;
132static struct type *atcb_call_type = NULL;
133static struct tcb_fieldnos fieldno;
134
135/* Set to 1 when the cached address of System.Tasking.Debug.Known_Tasks
136 might be stale and so needs to be recomputed. */
137static int ada_tasks_check_symbol_table = 1;
138
139/* The list of Ada tasks.
140
141 Note: To each task we associate a number that the user can use to
142 reference it - this number is printed beside each task in the tasks
143 info listing displayed by "info tasks". This number is equal to
144 its index in the vector + 1. Reciprocally, to compute the index
145 of a task in the vector, we need to substract 1 from its number. */
146typedef struct ada_task_info ada_task_info_s;
147DEF_VEC_O(ada_task_info_s);
148static VEC(ada_task_info_s) *task_list = NULL;
149
150/* When non-zero, this flag indicates that the current task_list
151 is obsolete, and should be recomputed before it is accessed. */
152static int stale_task_list_p = 1;
153
154/* Return the task number of the task whose ptid is PTID, or zero
155 if the task could not be found. */
156
2c0b251b 157static int
0ef643c8
JB
158ada_get_task_number (ptid_t ptid)
159{
160 int i;
161
162 for (i=0; i < VEC_length (ada_task_info_s, task_list); i++)
163 if (ptid_equal (VEC_index (ada_task_info_s, task_list, i)->ptid, ptid))
164 return i + 1;
165
166 return 0; /* No matching task found. */
167}
168
169/* Return the task number of the task that matches TASK_ID, or zero
170 if the task could not be found. */
171
172static int
173get_task_number_from_id (CORE_ADDR task_id)
174{
175 int i;
176
177 for (i = 0; i < VEC_length (ada_task_info_s, task_list); i++)
178 {
179 struct ada_task_info *task_info =
180 VEC_index (ada_task_info_s, task_list, i);
181
182 if (task_info->task_id == task_id)
183 return i + 1;
184 }
185
186 /* Task not found. Return 0. */
187 return 0;
188}
189
190/* Return non-zero if TASK_NUM is a valid task number. */
191
192int
193valid_task_id (int task_num)
194{
195 return (task_num > 0
196 && task_num <= VEC_length (ada_task_info_s, task_list));
197}
198
0ef643c8
JB
199/* Extract the contents of the value as a string whose length is LENGTH,
200 and store the result in DEST. */
201
202static void
203value_as_string (char *dest, struct value *val, int length)
204{
205 memcpy (dest, value_contents (val), length);
206 dest[length] = '\0';
207}
208
209/* Extract the string image from the fat string corresponding to VAL,
210 and store it in DEST. If the string length is greater than MAX_LEN,
211 then truncate the result to the first MAX_LEN characters of the fat
212 string. */
213
214static void
215read_fat_string_value (char *dest, struct value *val, int max_len)
216{
217 struct value *array_val;
218 struct value *bounds_val;
219 int len;
220
221 /* The following variables are made static to avoid recomputing them
222 each time this function is called. */
223 static int initialize_fieldnos = 1;
224 static int array_fieldno;
225 static int bounds_fieldno;
226 static int upper_bound_fieldno;
227
228 /* Get the index of the fields that we will need to read in order
229 to extract the string from the fat string. */
230 if (initialize_fieldnos)
231 {
232 struct type *type = value_type (val);
233 struct type *bounds_type;
234
235 array_fieldno = ada_get_field_index (type, "P_ARRAY", 0);
236 bounds_fieldno = ada_get_field_index (type, "P_BOUNDS", 0);
237
238 bounds_type = TYPE_FIELD_TYPE (type, bounds_fieldno);
239 if (TYPE_CODE (bounds_type) == TYPE_CODE_PTR)
240 bounds_type = TYPE_TARGET_TYPE (bounds_type);
241 if (TYPE_CODE (bounds_type) != TYPE_CODE_STRUCT)
242 error (_("Unknown task name format. Aborting"));
243 upper_bound_fieldno = ada_get_field_index (bounds_type, "UB0", 0);
244
245 initialize_fieldnos = 0;
246 }
247
248 /* Get the size of the task image by checking the value of the bounds.
249 The lower bound is always 1, so we only need to read the upper bound. */
250 bounds_val = value_ind (value_field (val, bounds_fieldno));
251 len = value_as_long (value_field (bounds_val, upper_bound_fieldno));
252
253 /* Make sure that we do not read more than max_len characters... */
254 if (len > max_len)
255 len = max_len;
256
257 /* Extract LEN characters from the fat string. */
258 array_val = value_ind (value_field (val, array_fieldno));
259 read_memory (VALUE_ADDRESS (array_val), dest, len);
260
261 /* Add the NUL character to close the string. */
262 dest[len] = '\0';
263}
264
265/* Return the address of the Known_Tasks array maintained in
266 the Ada Runtime. Return NULL if the array could not be found,
267 meaning that the inferior program probably does not use tasking.
268
269 In order to provide a fast response time, this function caches
270 the Known_Tasks array address after the lookup during the first
271 call. Subsequent calls will simply return this cached address. */
272
273static CORE_ADDR
274get_known_tasks_addr (void)
275{
276 static CORE_ADDR known_tasks_addr = 0;
277
278 if (ada_tasks_check_symbol_table)
279 {
280 struct symbol *sym;
281 struct minimal_symbol *msym;
282
283 msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL);
284 if (msym != NULL)
285 known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
286 else
287 {
288 if (target_lookup_symbol (KNOWN_TASKS_NAME, &known_tasks_addr) != 0)
289 return 0;
290 }
291
292 /* FIXME: brobecker 2003-03-05: Here would be a much better place
293 to attach the ada-tasks observers, instead of doing this
294 unconditionaly in _initialize_tasks. This would avoid an
295 unecessary notification when the inferior does not use tasking
296 or as long as the user does not use the ada-tasks commands.
297 Unfortunately, this is not possible for the moment: the current
298 code resets ada__tasks_check_symbol_table back to 1 whenever
299 symbols for a new program are being loaded. If we place the
300 observers intialization here, we will end up adding new observers
301 everytime we do the check for Ada tasking-related symbols
302 above. This would currently have benign effects, but is still
303 undesirable. The cleanest approach is probably to create a new
304 observer to notify us when the user is debugging a new program.
305 We would then reset ada__tasks_check_symbol_table back to 1
306 during the notification, but also detach all observers.
307 BTW: observers are probably not reentrant, so detaching during
308 a notification may not be the safest thing to do... Sigh...
309 But creating the new observer would be a good idea in any case,
310 since this allow us to make ada__tasks_check_symbol_table
311 static, which is a good bonus. */
312 ada_tasks_check_symbol_table = 0;
313 }
314
315 return known_tasks_addr;
316}
317
318/* Get from the debugging information the type description of all types
319 related to the Ada Task Control Block that will be needed in order to
320 read the list of known tasks in the Ada runtime. Also return the
321 associated ATCB_FIELDNOS.
322
323 Error handling: Any data missing from the debugging info will cause
324 an error to be raised, and none of the return values to be set.
325 Users of this function can depend on the fact that all or none of the
326 return values will be set. */
327
328static void
329get_tcb_types_info (struct type **atcb_type,
330 struct type **atcb_common_type,
331 struct type **atcb_ll_type,
332 struct type **atcb_call_type,
333 struct tcb_fieldnos *atcb_fieldnos)
334{
335 struct type *type;
336 struct type *common_type;
337 struct type *ll_type;
338 struct type *call_type;
339 struct tcb_fieldnos fieldnos;
340
341 const char *atcb_name = "system__tasking__ada_task_control_block___XVE";
342 const char *atcb_name_fixed = "system__tasking__ada_task_control_block";
343 const char *common_atcb_name = "system__tasking__common_atcb";
344 const char *private_data_name = "system__task_primitives__private_data";
345 const char *entry_call_record_name = "system__tasking__entry_call_record";
346
347 struct symbol *atcb_sym =
348 lookup_symbol (atcb_name, NULL, VAR_DOMAIN, NULL);
349 const struct symbol *common_atcb_sym =
350 lookup_symbol (common_atcb_name, NULL, VAR_DOMAIN, NULL);
351 const struct symbol *private_data_sym =
352 lookup_symbol (private_data_name, NULL, VAR_DOMAIN, NULL);
353 const struct symbol *entry_call_record_sym =
354 lookup_symbol (entry_call_record_name, NULL, VAR_DOMAIN, NULL);
355
356 if (atcb_sym == NULL || atcb_sym->type == NULL)
357 {
358 /* In Ravenscar run-time libs, the ATCB does not have a dynamic
359 size, so the symbol name differs. */
360 atcb_sym = lookup_symbol (atcb_name_fixed, NULL, VAR_DOMAIN, NULL);
361
362 if (atcb_sym == NULL || atcb_sym->type == NULL)
363 error (_("Cannot find Ada_Task_Control_Block type. Aborting"));
364
365 type = atcb_sym->type;
366 }
367 else
368 {
369 /* Get a static representation of the type record
370 Ada_Task_Control_Block. */
371 type = atcb_sym->type;
372 type = ada_template_to_fixed_record_type_1 (type, NULL, 0, NULL, 0);
373 }
374
375 if (common_atcb_sym == NULL || common_atcb_sym->type == NULL)
376 error (_("Cannot find Common_ATCB type. Aborting"));
377 if (private_data_sym == NULL || private_data_sym->type == NULL)
378 error (_("Cannot find Private_Data type. Aborting"));
379 if (entry_call_record_sym == NULL || entry_call_record_sym->type == NULL)
380 error (_("Cannot find Entry_Call_Record type. Aborting"));
381
382 /* Get the type for Ada_Task_Control_Block.Common. */
383 common_type = common_atcb_sym->type;
384
385 /* Get the type for Ada_Task_Control_Bloc.Common.Call.LL. */
386 ll_type = private_data_sym->type;
387
388 /* Get the type for Common_ATCB.Call.all. */
389 call_type = entry_call_record_sym->type;
390
391 /* Get the field indices. */
392 fieldnos.common = ada_get_field_index (type, "common", 0);
393 fieldnos.entry_calls = ada_get_field_index (type, "entry_calls", 1);
394 fieldnos.atc_nesting_level =
395 ada_get_field_index (type, "atc_nesting_level", 1);
396 fieldnos.state = ada_get_field_index (common_type, "state", 0);
397 fieldnos.parent = ada_get_field_index (common_type, "parent", 1);
398 fieldnos.priority = ada_get_field_index (common_type, "base_priority", 0);
399 fieldnos.image = ada_get_field_index (common_type, "task_image", 1);
400 fieldnos.image_len = ada_get_field_index (common_type, "task_image_len", 1);
401 fieldnos.call = ada_get_field_index (common_type, "call", 1);
402 fieldnos.ll = ada_get_field_index (common_type, "ll", 0);
403 fieldnos.ll_thread = ada_get_field_index (ll_type, "thread", 0);
404 fieldnos.ll_lwp = ada_get_field_index (ll_type, "lwp", 1);
405 fieldnos.call_self = ada_get_field_index (call_type, "self", 0);
406
407 /* On certain platforms such as x86-windows, the "lwp" field has been
408 named "thread_id". This field will likely be renamed in the future,
409 but we need to support both possibilities to avoid an unnecessary
410 dependency on a recent compiler. We therefore try locating the
411 "thread_id" field in place of the "lwp" field if we did not find
412 the latter. */
413 if (fieldnos.ll_lwp < 0)
414 fieldnos.ll_lwp = ada_get_field_index (ll_type, "thread_id", 1);
415
416 /* Set all the out parameters all at once, now that we are certain
417 that there are no potential error() anymore. */
418 *atcb_type = type;
419 *atcb_common_type = common_type;
420 *atcb_ll_type = ll_type;
421 *atcb_call_type = call_type;
422 *atcb_fieldnos = fieldnos;
423}
424
425/* Build the PTID of the task from its COMMON_VALUE, which is the "Common"
426 component of its ATCB record. This PTID needs to match the PTID used
427 by the thread layer. */
428
429static ptid_t
430ptid_from_atcb_common (struct value *common_value)
431{
432 long thread = 0;
433 CORE_ADDR lwp = 0;
434 struct value *ll_value;
435 ptid_t ptid;
436
437 ll_value = value_field (common_value, fieldno.ll);
438
439 if (fieldno.ll_lwp >= 0)
440 lwp = value_as_address (value_field (ll_value, fieldno.ll_lwp));
441 thread = value_as_long (value_field (ll_value, fieldno.ll_thread));
442
443 ptid = target_get_ada_task_ptid (lwp, thread);
444
445 return ptid;
446}
447
448/* Read the ATCB data of a given task given its TASK_ID (which is in practice
449 the address of its assocated ATCB record), and store the result inside
450 TASK_INFO. */
451
452static void
453read_atcb (CORE_ADDR task_id, struct ada_task_info *task_info)
454{
455 struct value *tcb_value;
456 struct value *common_value;
457 struct value *atc_nesting_level_value;
458 struct value *entry_calls_value;
459 struct value *entry_calls_value_element;
460 int called_task_fieldno = -1;
461 const char ravenscar_task_name[] = "Ravenscar task";
462
463 if (atcb_type == NULL)
464 get_tcb_types_info (&atcb_type, &atcb_common_type, &atcb_ll_type,
465 &atcb_call_type, &fieldno);
466
467 tcb_value = value_from_contents_and_address (atcb_type, NULL, task_id);
468 common_value = value_field (tcb_value, fieldno.common);
469
470 /* Fill in the task_id. */
471
472 task_info->task_id = task_id;
473
474 /* Compute the name of the task.
475
476 Depending on the GNAT version used, the task image is either a fat
477 string, or a thin array of characters. Older versions of GNAT used
478 to use fat strings, and therefore did not need an extra field in
479 the ATCB to store the string length. For efficiency reasons, newer
480 versions of GNAT replaced the fat string by a static buffer, but this
481 also required the addition of a new field named "Image_Len" containing
482 the length of the task name. The method used to extract the task name
483 is selected depending on the existence of this field.
484
485 In some run-time libs (e.g. Ravenscar), the name is not in the ATCB;
486 we may want to get it from the first user frame of the stack. For now,
487 we just give a dummy name. */
488
489 if (fieldno.image_len == -1)
490 {
491 if (fieldno.image >= 0)
492 read_fat_string_value (task_info->name,
493 value_field (common_value, fieldno.image),
494 sizeof (task_info->name) - 1);
495 else
496 strcpy (task_info->name, ravenscar_task_name);
497 }
498 else
499 {
500 int len = value_as_long (value_field (common_value, fieldno.image_len));
501
502 value_as_string (task_info->name,
503 value_field (common_value, fieldno.image), len);
504 }
505
506 /* Compute the task state and priority. */
507
508 task_info->state = value_as_long (value_field (common_value, fieldno.state));
509 task_info->priority =
510 value_as_long (value_field (common_value, fieldno.priority));
511
512 /* If the ATCB contains some information about the parent task,
513 then compute it as well. Otherwise, zero. */
514
515 if (fieldno.parent >= 0)
516 task_info->parent =
517 value_as_address (value_field (common_value, fieldno.parent));
518 else
519 task_info->parent = 0;
520
521
522 /* If the ATCB contains some information about entry calls, then
523 compute the "called_task" as well. Otherwise, zero. */
524
525 if (fieldno.atc_nesting_level > 0 && fieldno.entry_calls > 0)
526 {
527 /* Let My_ATCB be the Ada task control block of a task calling the
528 entry of another task; then the Task_Id of the called task is
529 in My_ATCB.Entry_Calls (My_ATCB.ATC_Nesting_Level).Called_Task. */
530 atc_nesting_level_value = value_field (tcb_value,
531 fieldno.atc_nesting_level);
532 entry_calls_value =
533 ada_coerce_to_simple_array_ptr (value_field (tcb_value,
534 fieldno.entry_calls));
535 entry_calls_value_element =
536 value_subscript (entry_calls_value, atc_nesting_level_value);
537 called_task_fieldno =
538 ada_get_field_index (value_type (entry_calls_value_element),
539 "called_task", 0);
540 task_info->called_task =
541 value_as_address (value_field (entry_calls_value_element,
542 called_task_fieldno));
543 }
544 else
545 {
546 task_info->called_task = 0;
547 }
548
549 /* If the ATCB cotnains some information about RV callers,
550 then compute the "caller_task". Otherwise, zero. */
551
552 task_info->caller_task = 0;
553 if (fieldno.call >= 0)
554 {
555 /* Get the ID of the caller task from Common_ATCB.Call.all.Self.
556 If Common_ATCB.Call is null, then there is no caller. */
557 const CORE_ADDR call =
558 value_as_address (value_field (common_value, fieldno.call));
559 struct value *call_val;
560
561 if (call != 0)
562 {
563 call_val =
564 value_from_contents_and_address (atcb_call_type, NULL, call);
565 task_info->caller_task =
566 value_as_address (value_field (call_val, fieldno.call_self));
567 }
568 }
569
570 /* And finally, compute the task ptid. */
571
572 if (ada_task_is_alive (task_info))
573 task_info->ptid = ptid_from_atcb_common (common_value);
574 else
575 task_info->ptid = null_ptid;
576}
577
578/* Read the ATCB info of the given task (identified by TASK_ID), and
579 add the result to the TASK_LIST. */
580
581static void
582add_ada_task (CORE_ADDR task_id)
583{
584 struct ada_task_info task_info;
585
586 read_atcb (task_id, &task_info);
587 VEC_safe_push (ada_task_info_s, task_list, &task_info);
588}
589
590/* Read the Known_Tasks array from the inferior memory, and store
591 it in TASK_LIST. Return non-zero upon success. */
592
593static int
594read_known_tasks_array (void)
595{
596 const int target_ptr_byte =
597 gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT;
598 const CORE_ADDR known_tasks_addr = get_known_tasks_addr ();
599 const int known_tasks_size = target_ptr_byte * MAX_NUMBER_OF_KNOWN_TASKS;
600 gdb_byte *known_tasks = alloca (known_tasks_size);
601 int i;
602
603 /* Step 1: Clear the current list, if necessary. */
604 VEC_truncate (ada_task_info_s, task_list, 0);
605
606 /* If the application does not use task, then no more needs to be done.
607 It is important to have the task list cleared (see above) before we
608 return, as we don't want a stale task list to be used... This can
609 happen for instance when debugging a non-multitasking program after
610 having debugged a multitasking one. */
611 if (known_tasks_addr == 0)
612 return 0;
613
614 /* Step 2: Build a new list by reading the ATCBs from the Known_Tasks
615 array in the Ada runtime. */
616 read_memory (known_tasks_addr, known_tasks, known_tasks_size);
617 for (i = 0; i < MAX_NUMBER_OF_KNOWN_TASKS; i++)
618 {
619 struct type *data_ptr_type =
620 builtin_type (current_gdbarch)->builtin_data_ptr;
621 CORE_ADDR task_id =
622 extract_typed_address (known_tasks + i * target_ptr_byte,
623 data_ptr_type);
624
625 if (task_id != 0)
626 add_ada_task (task_id);
627 }
628
629 /* Step 3: Unset stale_task_list_p, to avoid re-reading the Known_Tasks
630 array unless needed. Then report a success. */
631 stale_task_list_p = 0;
632
633 return 1;
634}
635
636/* Builds the task_list by reading the Known_Tasks array from
637 the inferior. Prints an appropriate message and returns non-zero
638 if it failed to build this list. */
639
640int
641ada_build_task_list (int warn_if_null)
642{
643 if (!target_has_stack)
644 error (_("Cannot inspect Ada tasks when program is not running"));
645
646 if (stale_task_list_p)
647 read_known_tasks_array ();
648
649 if (task_list == NULL)
650 {
651 if (warn_if_null)
652 printf_filtered (_("Your application does not use any Ada tasks.\n"));
653 return 0;
654 }
655
656 return 1;
657}
658
659/* Return non-zero iff the task STATE corresponds to a non-terminated
660 task state. */
661
662int
663ada_task_is_alive (struct ada_task_info *task_info)
664{
665 return (task_info->state != Terminated);
666}
667
668/* Print a one-line description of the task whose number is TASKNO.
669 The formatting should fit the "info tasks" array. */
670
671static void
672short_task_info (int taskno)
673{
674 const struct ada_task_info *const task_info =
675 VEC_index (ada_task_info_s, task_list, taskno - 1);
676 int active_task_p;
677
678 gdb_assert (task_info != NULL);
679
680 /* Print a star if this task is the current task (or the task currently
681 selected). */
682
683 active_task_p = ptid_equal (task_info->ptid, inferior_ptid);
684 if (active_task_p)
685 printf_filtered ("*");
686 else
687 printf_filtered (" ");
688
689 /* Print the task number. */
690 printf_filtered ("%3d", taskno);
691
692 /* Print the Task ID. */
693 printf_filtered (" %9lx", (long) task_info->task_id);
694
695 /* Print the Task ID of the task parent. */
696 printf_filtered (" %4d", get_task_number_from_id (task_info->parent));
697
698 /* Print the base priority of the task. */
699 printf_filtered (" %3d", task_info->priority);
700
701 /* Print the task current state. */
702 if (task_info->caller_task)
703 printf_filtered (_(" Accepting RV with %-4d"),
704 get_task_number_from_id (task_info->caller_task));
705 else if (task_info->state == Entry_Caller_Sleep && task_info->called_task)
706 printf_filtered (_(" Waiting on RV with %-3d"),
707 get_task_number_from_id (task_info->called_task));
708 else if (task_info->state == Runnable && active_task_p)
709 /* Replace "Runnable" by "Running" since this is the active task. */
d6b67a5e 710 printf_filtered (" %-22s", _("Running"));
0ef643c8 711 else
d6b67a5e 712 printf_filtered (" %-22s", _(task_states[task_info->state]));
0ef643c8
JB
713
714 /* Finally, print the task name. */
715 if (task_info->name[0] != '\0')
716 printf_filtered (" %s\n", task_info->name);
717 else
718 printf_filtered (_(" <no name>\n"));
719}
720
721/* Print a list containing a short description of all Ada tasks. */
722/* FIXME: Shouldn't we be using ui_out??? */
723
724static void
725info_tasks (int from_tty)
726{
727 int taskno;
728 const int nb_tasks = VEC_length (ada_task_info_s, task_list);
729
730 printf_filtered (_(" ID TID P-ID Pri State Name\n"));
731
732 for (taskno = 1; taskno <= nb_tasks; taskno++)
733 short_task_info (taskno);
734}
735
736/* Print a detailed description of the Ada task whose ID is TASKNO_STR. */
737
738static void
739info_task (char *taskno_str, int from_tty)
740{
741 const int taskno = value_as_long (parse_and_eval (taskno_str));
742 struct ada_task_info *task_info;
743 int parent_taskno = 0;
744
745 if (taskno <= 0 || taskno > VEC_length (ada_task_info_s, task_list))
746 error (_("Task ID %d not known. Use the \"info tasks\" command to\n"
747 "see the IDs of currently known tasks"), taskno);
748 task_info = VEC_index (ada_task_info_s, task_list, taskno - 1);
749
750 /* Print the Ada task ID. */
751 printf_filtered (_("Ada Task: %s\n"), paddr_nz (task_info->task_id));
752
753 /* Print the name of the task. */
754 if (task_info->name[0] != '\0')
755 printf_filtered (_("Name: %s\n"), task_info->name);
756 else
757 printf_filtered (_("<no name>\n"));
758
759 /* Print the TID and LWP. */
760 printf_filtered (_("Thread: %#lx\n"), ptid_get_tid (task_info->ptid));
761 printf_filtered (_("LWP: %#lx\n"), ptid_get_lwp (task_info->ptid));
762
763 /* Print who is the parent (if any). */
764 if (task_info->parent != 0)
765 parent_taskno = get_task_number_from_id (task_info->parent);
766 if (parent_taskno)
767 {
768 struct ada_task_info *parent =
769 VEC_index (ada_task_info_s, task_list, parent_taskno - 1);
770
771 printf_filtered (_("Parent: %d"), parent_taskno);
772 if (parent->name[0] != '\0')
773 printf_filtered (" (%s)", parent->name);
774 printf_filtered ("\n");
775 }
776 else
777 printf_filtered (_("No parent\n"));
778
779 /* Print the base priority. */
780 printf_filtered (_("Base Priority: %d\n"), task_info->priority);
781
782 /* print the task current state. */
783 {
784 int target_taskno = 0;
785
786 if (task_info->caller_task)
787 {
788 target_taskno = get_task_number_from_id (task_info->caller_task);
789 printf_filtered (_("State: Accepting rendezvous with %d"),
790 target_taskno);
791 }
792 else if (task_info->state == Entry_Caller_Sleep && task_info->called_task)
793 {
794 target_taskno = get_task_number_from_id (task_info->called_task);
795 printf_filtered (_("State: Waiting on task %d's entry"),
796 target_taskno);
797 }
798 else
d6b67a5e 799 printf_filtered (_("State: %s"), _(long_task_states[task_info->state]));
0ef643c8
JB
800
801 if (target_taskno)
802 {
803 struct ada_task_info *target_task_info =
804 VEC_index (ada_task_info_s, task_list, target_taskno - 1);
805
806 if (target_task_info->name[0] != '\0')
807 printf_filtered (" (%s)", target_task_info->name);
808 }
809
810 printf_filtered ("\n");
811 }
812}
813
814/* If ARG is empty or null, then print a list of all Ada tasks.
815 Otherwise, print detailed information about the task whose ID
816 is ARG.
817
818 Does nothing if the program doesn't use Ada tasking. */
819
820static void
821info_tasks_command (char *arg, int from_tty)
822{
823 const int task_list_built = ada_build_task_list (1);
824
825 if (!task_list_built)
826 return;
827
828 if (arg == NULL || *arg == '\0')
829 info_tasks (from_tty);
830 else
831 info_task (arg, from_tty);
832}
833
834/* Print a message telling the user id of the current task.
835 This function assumes that tasking is in use in the inferior. */
836
837static void
838display_current_task_id (void)
839{
840 const int current_task = ada_get_task_number (inferior_ptid);
841
842 if (current_task == 0)
843 printf_filtered (_("[Current task is unknown]\n"));
844 else
845 printf_filtered (_("[Current task is %d]\n"), current_task);
846}
847
848/* Parse and evaluate TIDSTR into a task id, and try to switch to
849 that task. Print an error message if the task switch failed. */
850
851static void
852task_command_1 (char *taskno_str, int from_tty)
853{
854 const int taskno = value_as_long (parse_and_eval (taskno_str));
855 struct ada_task_info *task_info;
856
857 if (taskno <= 0 || taskno > VEC_length (ada_task_info_s, task_list))
858 error (_("Task ID %d not known. Use the \"info tasks\" command to\n"
859 "see the IDs of currently known tasks"), taskno);
860 task_info = VEC_index (ada_task_info_s, task_list, taskno - 1);
861
862 if (!ada_task_is_alive (task_info))
863 error (_("Cannot switch to task %d: Task is no longer running"), taskno);
864
865 switch_to_thread (task_info->ptid);
866 ada_find_printable_frame (get_selected_frame (NULL));
867 printf_filtered (_("[Switching to task %d]\n"), taskno);
868 print_stack_frame (get_selected_frame (NULL),
869 frame_relative_level (get_selected_frame (NULL)), 1);
870}
871
872
873/* Print the ID of the current task if TASKNO_STR is empty or NULL.
874 Otherwise, switch to the task indicated by TASKNO_STR. */
875
876static void
877task_command (char *taskno_str, int from_tty)
878{
879 const int task_list_built = ada_build_task_list (1);
880
881 if (!task_list_built)
882 return;
883
884 if (taskno_str == NULL || taskno_str[0] == '\0')
885 display_current_task_id ();
886 else
887 {
888 /* Task switching in core files doesn't work, either because:
889 1. Thread support is not implemented with core files
890 2. Thread support is implemented, but the thread IDs created
891 after having read the core file are not the same as the ones
892 that were used during the program life, before the crash.
893 As a consequence, there is no longer a way for the debugger
894 to find the associated thead ID of any given Ada task.
895 So, instead of attempting a task switch without giving the user
896 any clue as to what might have happened, just error-out with
897 a message explaining that this feature is not supported. */
898 if (!target_has_execution)
899 error (_("\
900Task switching not supported when debugging from core files\n\
901(use thread support instead)"));
902 task_command_1 (taskno_str, from_tty);
903 }
904}
905
906/* Indicate that the task list may have changed, so invalidate the cache. */
907
2c0b251b 908static void
0ef643c8
JB
909ada_task_list_changed (void)
910{
911 stale_task_list_p = 1;
912}
913
914/* The 'normal_stop' observer notification callback. */
915
916static void
1d33d6ba 917ada_normal_stop_observer (struct bpstats *unused_args, int unused_args2)
0ef643c8
JB
918{
919 /* The inferior has been resumed, and just stopped. This means that
920 our task_list needs to be recomputed before it can be used again. */
921 ada_task_list_changed ();
922}
923
924/* A routine to be called when the objfiles have changed. */
925
2c0b251b 926static void
0ef643c8
JB
927ada_new_objfile_observer (struct objfile *objfile)
928{
929 /* Invalidate all cached data that were extracted from an objfile. */
930
931 atcb_type = NULL;
932 atcb_common_type = NULL;
933 atcb_ll_type = NULL;
934 atcb_call_type = NULL;
935
936 ada_tasks_check_symbol_table = 1;
937}
938
2c0b251b
PA
939/* Provide a prototype to silence -Wmissing-prototypes. */
940extern initialize_file_ftype _initialize_tasks;
941
0ef643c8
JB
942void
943_initialize_tasks (void)
944{
945 /* Attach various observers. */
946 observer_attach_normal_stop (ada_normal_stop_observer);
947 observer_attach_new_objfile (ada_new_objfile_observer);
948
949 /* Some new commands provided by this module. */
950 add_info ("tasks", info_tasks_command,
951 _("Provide information about all known Ada tasks"));
952 add_cmd ("task", class_run, task_command,
953 _("Use this command to switch between Ada tasks.\n\
954Without argument, this command simply prints the current task ID"),
955 &cmdlist);
956}
957
This page took 0.079727 seconds and 4 git commands to generate.