2004-06-12 Michael Chastain <mec.gnu@mindspring.com>
[deliverable/binutils-gdb.git] / gdb / ada-tasks.c
CommitLineData
4c4b4cd2
PH
1/* File ada-tasks.c: Ada tasking control for GDB
2 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4 Contributed by Ada Core Technologies, Inc.
5
14f9c5c9
AS
6 This file is part of GDB.
7
14f9c5c9
AS
8 Authors: Roch-Alexandre Nomine Beguin, Arnaud Charlet <charlet@gnat.com>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15*/
16
d2e4a39e 17#include <ctype.h>
4c4b4cd2 18#include <gdb_string.h>
d2e4a39e
AS
19#include "defs.h"
20#include "command.h"
14f9c5c9
AS
21#include "value.h"
22#include "language.h"
23#include "inferior.h"
24#include "symtab.h"
25#include "target.h"
26#include "gdbcore.h"
4c4b4cd2
PH
27#include "gdbthread.h"
28#include "regcache.h" /* for registers_changed */
14f9c5c9 29
4c4b4cd2
PH
30#if defined (__fsu__) || defined (HAVE_SPYTHREAD) \
31 || (defined(__alpha__) && defined(__osf__) && !defined(__alpha_vxworks))
14f9c5c9
AS
32#include <sys/procfs.h>
33#endif
34
4c4b4cd2
PH
35#if defined (__fsu__) || defined (HAVE_SPYTHREAD) \
36 || (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET))
14f9c5c9 37#include "gregset.h"
d2e4a39e 38#endif
14f9c5c9 39
4c4b4cd2
PH
40#ifdef I386_GNULINUX_TARGET
41#include "gdb_thread_db.h"
42#endif
14f9c5c9 43
4c4b4cd2
PH
44#if defined (HAVE_SPYTHREAD)
45#include "irix6-spyThread.h"
46#endif
14f9c5c9 47
4c4b4cd2
PH
48#include "ada-lang.h"
49#include "observer.h"
14f9c5c9 50
4c4b4cd2
PH
51enum task_states
52{
53 Unactivated,
54 Runnable,
55 Terminated,
56 Activator_Sleep,
57 Acceptor_Sleep,
58 Entry_Caller_Sleep,
59 Async_Select_Sleep,
60 Delay_Sleep,
61 Master_Completion_Sleep,
62 Master_Phase_2_Sleep
63};
14f9c5c9 64
4c4b4cd2
PH
65struct task_control_block
66{
67 char state;
68 CORE_ADDR parent;
69 int priority;
70 char image [32];
71 int image_len; /* This field is not always present in the ATCB. */
72 CORE_ADDR call;
73 CORE_ADDR thread;
74 CORE_ADDR lwp; /* This field is not always present in the ATCB. */
75};
14f9c5c9 76
4c4b4cd2
PH
77/* The index of certain important fields in the Ada Task Control Block
78 record and sub-records. */
14f9c5c9 79
4c4b4cd2
PH
80struct tcb_fieldnos
81{
82 /* Fields in record Ada_Task_Control_Block. */
83 int common;
84
85 /* Fields in record Common_ATCB. */
86 int state;
87 int parent;
88 int priority;
89 int image;
90 int image_len; /* This field may be missing. */
91 int call;
92 int ll;
93
94 /* Fields in Task_Primitives.Private_Data. */
95 int ll_thread;
96 int ll_lwp; /* This field may be missing. */
97};
98
99#if defined (linux)
100#define TASK_LWP(atcb) 0L
14f9c5c9 101#else
4c4b4cd2 102#define TASK_LWP(atcb) extract_unsigned_integer (&(atcb).lwp, sizeof ((atcb).lwp))
14f9c5c9
AS
103#endif
104
4c4b4cd2
PH
105struct task_ptid
106{
107 int pid; /* The Process id */
108 long lwp; /* The Light Weight Process id */
109 long tid; /* The Thread id */
110};
111typedef struct task_ptid task_ptid_t;
112
113struct task_entry
114{
115 CORE_ADDR task_id;
116 struct task_control_block atcb;
117 int task_num;
118 int known_tasks_index;
119 struct task_entry *next_task;
120 task_ptid_t task_ptid;
121 int stack_per;
122};
123
124/* FIXME: move all this conditional compilation in description
125 files or in configure.in */
126
14f9c5c9 127#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
4c4b4cd2
PH
128#define SPECIAL_THREAD_SUPPORT_ACTIVE() thread_support
129#define SAVE_TASK_REGISTERS(task) \
130 do { fill_gregset (&gregset_saved, -1); \
131 fill_fpregset (&fpregset_saved, -1); \
132 } while (0)
133#define RESTORE_TASK_REGISTERS(task) \
134 do { supply_gregset (&gregset_saved); \
135 supply_fpregset (&fpregset_saved); \
136 } while (0)
137
14f9c5c9 138#define THREAD_FETCH_REGISTERS dec_thread_fetch_registers
4c4b4cd2
PH
139#define GET_CURRENT_THREAD(PTID) dec_thread_get_current_thread ()
140extern unsigned long dec_thread_get_current_thread (void);
14f9c5c9 141extern int dec_thread_get_registers (gdb_gregset_t *, gdb_fpregset_t *);
4c4b4cd2 142extern int dec_thread_fetch_registers (void);
14f9c5c9
AS
143#endif
144
4c4b4cd2
PH
145#ifdef __fsu__
146#define SPECIAL_THREAD_SUPPORT_ACTIVE() \
147 (thread_support && pthread_kern_addr != 0)
148#define SAVE_TASK_REGISTERS(task) \
149 do { \
150 if (pthread_kern_addr != 0) \
151 { \
152 fill_gregset (&gregset_saved, -1); \
153 fill_fpregset (&fpregset_saved, -1); \
154 } \
155 } while (0)
156#define RESTORE_TASK_REGISTERS(task) \
157 do { \
158 if (pthread_kern_addr != 0) \
159 { \
160 supply_gregset (&gregset_saved); \
161 supply_fpregset (&fpregset_saved); \
162 } \
163 } while (0)
164
165extern int fsu_thread_fetch_registers (void);
166extern unsigned long fsu_thread_get_current_thread (void);
167static int fsu_or_linux_thread_fetch_registers (void);
168static long fsu_or_linux_thread_get_current_thread (ptid_t);
169#define THREAD_FETCH_REGISTERS fsu_or_linux_thread_fetch_registers
170#define GET_CURRENT_THREAD(PTID) fsu_or_linux_thread_get_current_thread (PTID)
171#define PTHREAD_KERN "pthread_kern"
172#endif
173
174#ifdef I386_GNULINUX_TARGET
175extern td_thrinfo_t thread_db_pid_to_thread_info (int pid);
176extern int thread_db_tid_to_pid (void *tid);
14f9c5c9
AS
177#endif
178
179#if defined(VXWORKS_TARGET)
4c4b4cd2 180#define GET_CURRENT_THREAD(PTID) (unsigned long) ptid_get_pid (PTID)
14f9c5c9
AS
181#define THREAD_FETCH_REGISTERS() (-1)
182
4c4b4cd2
PH
183#elif defined (__WIN32__) || defined (__CYGWIN__) || defined (hpux)
184#define GET_CURRENT_THREAD(PTID) ptid_get_pid (PTID)
14f9c5c9 185#define THREAD_FETCH_REGISTERS() (-1)
4c4b4cd2 186#endif
14f9c5c9 187
4c4b4cd2
PH
188#if defined (HAVE_SPYTHREAD)
189#define GET_CURRENT_THREAD(PTID) (unsigned long) TIDGET (PTID)
190#endif
14f9c5c9 191
4c4b4cd2
PH
192#if !defined(GET_CURRENT_THREAD)
193#define GET_CURRENT_THREAD(PTID) (unsigned long) ptid_get_tid (PTID)
194#endif
14f9c5c9 195
4c4b4cd2
PH
196#if !defined(THREAD_FETCH_REGISTERS)
197#define THREAD_FETCH_REGISTERS() (target_fetch_registers (-1), 0)
198#endif
199
200#if !defined(SAVE_TASK_REGISTERS)
201#define SAVE_TASK_REGISTERS(task)
202#define RESTORE_TASK_REGISTERS(task)
203#endif
204
205#if !defined(SPECIAL_THREAD_SUPPORT_ACTIVE)
206#define SPECIAL_THREAD_SUPPORT_ACTIVE() 0
14f9c5c9
AS
207#endif
208
209#define KNOWN_TASKS_NAME "system__tasking__debug__known_tasks"
210
4c4b4cd2
PH
211#define READ_MEMORY(addr, var) read_memory (addr, (char *) &var, sizeof (var))
212
213/* If defined to 1, means that the thread ptids maintained by core GDB
214 follow this format : first field (pid) contains the tid
215 second field (lwp) contains 0
216 third field (tid) contains 0 */
217#ifndef THREAD_PTID_CONTAINS_TID_NULL_NULL
218#define THREAD_PTID_CONTAINS_TID_NULL_NULL (0)
219#endif
220
221/* If defined to 1, means that the thread ptids maintained by core GDB
222 follow this format: first field (pid) contains the LWP id
223 second field (lwp) contains 0
224 third field (tid) contains 0 */
225#ifndef THREAD_PTID_CONTAINS_LWP_NULL_NULL
226#define THREAD_PTID_CONTAINS_LWP_NULL_NULL (0)
227#endif
228
229/* If defined to 1, means that the thread ptids maintained by core GDB
230 follow this format: first field (pid) contains the PID
231 second field (lwp) contains 0
232 third field (tid) contains the TID */
233#ifndef THREAD_PTID_CONTAINS_PID_NULL_TID
234#define THREAD_PTID_CONTAINS_PID_NULL_TID (0)
235#endif
236
237/* If defined to 1, means that the thread ptids maintained by core GDB
238 follow this format: first field (pid) contains the PID
239 second field (lwp) contains the TID
240 third field (tid) contains the 0 */
241
242#ifndef THREAD_PTID_CONTAINS_PID_TID_NULL
243#define THREAD_PTID_CONTAINS_PID_TID_NULL (0)
244#endif
245
246/* If defined to 1, means that the thread id is not stored in the tid
247 field of the task_ptid, but rather in the lwp field. */
248#ifndef ADA_THREAD_ID_IN_LWP
249#define ADA_THREAD_ID_IN_LWP (0)
250#endif
251
252static int task_ptid_get_pid (task_ptid_t task_ptid);
253static long task_ptid_get_lwp (task_ptid_t task_ptid);
254static long task_ptid_get_tid (task_ptid_t task_ptid);
255static task_ptid_t task_ptid_build (int pid, long lwp, long tid);
256static ptid_t task_ptid_get_ptid (task_ptid_t task_ptid);
257static long task_ptid_get_thread_id (task_ptid_t task_ptid);
258
259static int task_is_alive (enum task_states state);
260static CORE_ADDR get_self_id (ptid_t);
261static int get_entry_number (CORE_ADDR);
262static void get_tcb_types_info (struct type **atcb_type,
263 struct type **atcb_common_type,
264 struct type **atcb_ll_type,
265 struct tcb_fieldnos *atcb_fieldnos);
266static void get_tcb_call_type_info (struct type **atcb_call_type,
267 int *atcb_call_self_fieldno);
268static CORE_ADDR get_known_tasks_addr (void);
269static int read_known_tasks_array (void);
270static int build_task_list (void);
271static void value_as_string (char *dest, struct value *val, int length);
272static struct task_control_block read_atcb (CORE_ADDR atcb_addr);
273static CORE_ADDR read_caller (const CORE_ADDR call);
274static void display_current_task_id (void);
275static void task_command_1 (char *tidstr, int from_tty);
276
277/* Ada-tasks observers. */
278
279static void normal_stop_notification (void);
280static void ada_tasks_attach_observers (void);
14f9c5c9 281
14f9c5c9
AS
282/* Global visible variables */
283
14f9c5c9 284int ada__tasks_check_symbol_table = 1;
4c4b4cd2
PH
285CORE_ADDR pthread_kern_addr = 0;
286
287/* Local global variables. */
288static struct task_entry *task_list = NULL;
14f9c5c9 289
4c4b4cd2
PH
290/* When non-zero, this flag indicates that the current task_list
291 is obsolete, and should be recomputed before it is accessed. */
292static int stale_task_list_p = 1;
293
294#if defined (__fsu__) || (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET))
14f9c5c9
AS
295gdb_gregset_t gregset_saved;
296gdb_fpregset_t fpregset_saved;
297#endif
298
299/* The maximum number of tasks known to the Ada runtime */
4c4b4cd2
PH
300static const int MAX_NUMBER_OF_KNOWN_TASKS = 1000;
301
302/* the current task, as seen by the user. Modified everytime the user
303 does a task switch. */
304static int current_task = -1;
14f9c5c9 305
4c4b4cd2 306unsigned long current_thread;
14f9c5c9 307
4c4b4cd2
PH
308/* The task where the debugger stopped, giving control back to the user.
309 Not affected by task switching. Used to restore the registers before
310 continuing the inferior. */
311int current_task_id = -1;
312
313static char *task_states[] = {
14f9c5c9
AS
314 "Unactivated",
315 "Runnable",
316 "Terminated",
317 "Child Activation Wait",
318 "Accept Statement",
319 "Waiting on entry call",
320 "Async Select Wait",
321 "Delay Sleep",
322 "Child Termination Wait",
323 "Wait Child in Term Alt",
324 "",
325 "",
326 "",
327 "",
328 "Asynchronous Hold"
329};
330
331/* Global internal types */
332
4c4b4cd2 333static char *long_task_states[] = {
14f9c5c9
AS
334 "Unactivated",
335 "Runnable",
336 "Terminated",
337 "Waiting for child activation",
338 "Blocked in accept statement",
339 "Waiting on entry call",
340 "Asynchronous Selective Wait",
341 "Delay Sleep",
342 "Waiting for children termination",
343 "Waiting for children in terminate alternative",
344 "",
345 "",
346 "",
347 "",
348 "Asynchronous Hold"
349};
350
351/* Global internal variables */
352
353static int highest_task_num = 0;
4c4b4cd2
PH
354static int thread_support = 0; /* 1 if the thread library in use is
355 supported. FIXME: Not reinitialized
356 properly when program reloaded.
357 */
358#ifdef __fsu__
359static int
360fsu_or_linux_thread_fetch_registers (void)
361{
362 if (pthread_kern_addr != 0)
363 return fsu_thread_fetch_registers ();
364
365 target_fetch_registers (-1);
366 return 0L;
367}
368
369static long
370fsu_or_linux_thread_get_current_thread (ptid_t ptid)
371{
372 if (pthread_kern_addr != 0)
373 return fsu_thread_get_current_thread ();
374
375 return ptid_get_tid (ptid);
376}
377
378#endif /* __fsu__ */
14f9c5c9 379
d2e4a39e 380static int
4c4b4cd2 381add_task_entry (CORE_ADDR p_task_id, int index)
14f9c5c9
AS
382{
383 struct task_entry *new_task_entry = NULL;
384 struct task_entry *pt;
385
386 highest_task_num++;
aacb1f0a 387 new_task_entry = xmalloc (sizeof (struct task_entry));
14f9c5c9
AS
388 new_task_entry->task_num = highest_task_num;
389 new_task_entry->task_id = p_task_id;
4c4b4cd2 390 new_task_entry->atcb = read_atcb (p_task_id);
14f9c5c9 391 new_task_entry->known_tasks_index = index;
4c4b4cd2
PH
392 new_task_entry->task_ptid =
393 task_ptid_build (ptid_get_pid (inferior_ptid), /* ? */
394 TASK_LWP (new_task_entry->atcb),
395 new_task_entry->atcb.thread);
14f9c5c9
AS
396 new_task_entry->next_task = NULL;
397 pt = task_list;
398 if (pt)
399 {
400 while (pt->next_task)
4c4b4cd2 401 pt = pt->next_task;
14f9c5c9
AS
402 pt->next_task = new_task_entry;
403 pt->stack_per = 0;
404 }
d2e4a39e
AS
405 else
406 task_list = new_task_entry;
14f9c5c9
AS
407 return new_task_entry->task_num;
408}
409
4c4b4cd2
PH
410static int
411get_entry_number (CORE_ADDR p_task_id)
14f9c5c9
AS
412{
413 struct task_entry *pt;
414
415 pt = task_list;
416 while (pt != NULL)
417 {
418 if (pt->task_id == p_task_id)
4c4b4cd2 419 return pt->task_num;
14f9c5c9
AS
420 pt = pt->next_task;
421 }
422 return 0;
423}
424
80ae6ee2 425static struct task_entry *
4c4b4cd2 426get_thread_entry_vptr (long thread)
14f9c5c9
AS
427{
428 struct task_entry *pt;
429
430 pt = task_list;
431 while (pt != NULL)
432 {
4c4b4cd2
PH
433 if (task_ptid_get_thread_id (pt->task_ptid) == thread)
434 return pt;
14f9c5c9
AS
435 pt = pt->next_task;
436 }
437 return 0;
438}
439
80ae6ee2
AS
440static struct task_entry *
441get_entry_vptr (int p_task_num)
14f9c5c9
AS
442{
443 struct task_entry *pt;
444
445 pt = task_list;
446 while (pt)
447 {
448 if (pt->task_num == p_task_num)
4c4b4cd2 449 return pt;
14f9c5c9
AS
450 pt = pt->next_task;
451 }
452 return NULL;
453}
454
80ae6ee2
AS
455void
456init_task_list (void)
14f9c5c9
AS
457{
458 struct task_entry *pt, *old_pt;
459
4c4b4cd2
PH
460 target_find_new_threads ();
461
14f9c5c9
AS
462 pt = task_list;
463 while (pt)
464 {
465 old_pt = pt;
466 pt = pt->next_task;
aacb1f0a 467 xfree (old_pt);
14f9c5c9
AS
468 };
469 task_list = NULL;
470 highest_task_num = 0;
471}
472
80ae6ee2
AS
473int
474valid_task_id (int task)
14f9c5c9
AS
475{
476 return get_entry_vptr (task) != NULL;
477}
478
4c4b4cd2
PH
479/* Return the pid of a given task ptid. */
480
481static int
482task_ptid_get_pid (task_ptid_t task_ptid)
14f9c5c9 483{
4c4b4cd2
PH
484 return task_ptid.pid;
485}
486
487/* Return the lwp of a given task ptid. */
488
489static long
490task_ptid_get_lwp (task_ptid_t task_ptid)
491{
492 return task_ptid.lwp;
493}
494
495/* Return the tid of a given task ptid. */
496
497static long
498task_ptid_get_tid (task_ptid_t task_ptid)
499{
500 return task_ptid.tid;
501}
502
503/* Build a task ptid from the associated pid, lwp, and tid. */
504
505static task_ptid_t
506task_ptid_build (int pid, long lwp, long tid)
507{
508 task_ptid_t task_ptid;
509
510 task_ptid.pid = pid;
511 task_ptid.lwp = lwp;
512 task_ptid.tid = tid;
513 return task_ptid;
514}
515
516/* Translate a task ptid into a ptid (the ptid maintained by core GDB).
517
518 On most platforms, they are equivalent, and this function can be
519 regarded as the identity. However, there are other platforms where
520 the task ptid and the ptid are not equivalent. For instance, the task
521 LWP value is sometimes stored by GDB-core as a pid! This translation
522 therefore becomes necessary before invoking the GDB thread services. */
523
524static ptid_t
525task_ptid_get_ptid (task_ptid_t task_ptid)
526{
527 ptid_t ptid;
528
529 if (THREAD_PTID_CONTAINS_TID_NULL_NULL)
530 ptid = ptid_build (task_ptid_get_tid (task_ptid), 0, 0);
531 else if (THREAD_PTID_CONTAINS_LWP_NULL_NULL)
532 ptid = ptid_build (task_ptid_get_lwp (task_ptid), 0, 0);
533 else if (THREAD_PTID_CONTAINS_PID_NULL_TID)
534 ptid = ptid_build (task_ptid_get_pid (task_ptid),
535 0, task_ptid_get_tid (task_ptid));
536 else if (THREAD_PTID_CONTAINS_PID_TID_NULL)
537 ptid = ptid_build (task_ptid_get_pid (task_ptid),
538 task_ptid_get_tid (task_ptid), 0);
539 else
540 ptid = ptid_build (task_ptid_get_pid (task_ptid),
541 task_ptid_get_lwp (task_ptid),
542 task_ptid_get_tid (task_ptid));
543
544 return ptid;
545}
546
547/* Extract and return the thread_id for the given TASK_PTID. */
548
549static long
550task_ptid_get_thread_id (task_ptid_t task_ptid)
551{
552 /* On most platforms, the thread_id is stored in task_ptid.tid.
553 Unfortunately, some other platforms store it as the task_ptid.lwp... */
554
555 if (ADA_THREAD_ID_IN_LWP)
556 return task_ptid_get_lwp (task_ptid);
557 else
558 return task_ptid_get_tid (task_ptid);
559}
560
561/* Return non-zero iff the task STATE corresponds to a non-terminated
562 task state. */
563
564static int
565task_is_alive (enum task_states state)
566{
567 return (state != Terminated);
568}
569
570static CORE_ADDR
571get_self_id (ptid_t ptid)
572{
573#ifdef GNAT_GDB
14f9c5c9 574 struct task_entry *ent;
14f9c5c9
AS
575
576#if !((defined(sun) && defined(__SVR4)) || defined(VXWORKS_TARGET) || defined(__WIN32__))
577 if (thread_support)
578#endif
579 {
4c4b4cd2 580 ent = get_thread_entry_vptr (GET_CURRENT_THREAD (ptid));
14f9c5c9
AS
581 return ent ? ent->task_id : 0;
582 }
4c4b4cd2 583#endif
14f9c5c9
AS
584
585 /* FIXME: calling a function in the inferior with a multithreaded application
4c4b4cd2
PH
586 is not reliable, so return a null address if there is no safe way to
587 get the current task */
588 return 0;
14f9c5c9
AS
589}
590
d2e4a39e 591int
4c4b4cd2 592ada_get_current_task (ptid_t ptid)
14f9c5c9
AS
593{
594 int result;
d2e4a39e 595
4c4b4cd2
PH
596 if (current_language->la_language != language_ada)
597 return -1;
14f9c5c9 598
4c4b4cd2 599 result = get_entry_number (get_self_id (ptid));
14f9c5c9
AS
600
601 /* return -1 if not found */
602 return result == 0 ? -1 : result;
603}
604
4c4b4cd2
PH
605/* Get from the debugging information the type description of all types
606 related to the Ada Task Control Block that will be needed in order to
607 read the list of known tasks in the Ada runtime. Also return the
608 associated ATCB_FIELDNOS.
609
610 Error handling: Any data missing from the debugging info will cause
611 an error to be raised, and none of the return values to be set.
612 Users of this function can depend on the fact that all or none of the
613 return values will be set. */
614
615static void
616get_tcb_types_info (struct type **atcb_type,
617 struct type **atcb_common_type,
618 struct type **atcb_ll_type,
619 struct tcb_fieldnos *atcb_fieldnos)
620{
621 struct type *type;
622 struct type *common_type;
623 struct type *ll_type;
624 struct tcb_fieldnos fieldnos;
625
626#ifndef ADA_RETAIN_DOTS
627 const char *atcb_name = "system__tasking__ada_task_control_block___XVE";
628 const char *common_atcb_name = "system__tasking__common_atcb";
629 const char *private_data_name = "system__task_primitives__private_data";
630#else
631 const char *atcb_name = "system.tasking.ada_task_control_block___XVE";
632 const char *common_atcb_name = "system.tasking.common_atcb";
633 const char *private_data_name = "system.task_primitives.private_data";
634#endif
635
636 const struct symbol *atcb_sym =
637 lookup_symbol (atcb_name, NULL, VAR_DOMAIN, NULL, NULL);
638 const struct symbol *common_atcb_sym =
639 lookup_symbol (common_atcb_name, NULL, VAR_DOMAIN, NULL, NULL);
640 const struct symbol *private_data_sym =
641 lookup_symbol (private_data_name, NULL, VAR_DOMAIN, NULL, NULL);
642
643 if (atcb_sym == NULL || atcb_sym->type == NULL)
644 error ("Can not find Ada_Task_Control_Block type. Aborting");
645 if (common_atcb_sym == NULL || common_atcb_sym->type == NULL)
646 error ("Can not find Common_ATCB type. Aborting");
647 if (private_data_sym == NULL || private_data_sym->type == NULL)
648 error ("Can not find Private_Data type. Aborting");
649
650 /* Get a static representation of the type record Ada_Task_Control_Block. */
651 type = atcb_sym->type;
652 type = ada_template_to_fixed_record_type_1 (type, NULL, 0, NULL, 0);
653
654 /* Get the type for Ada_Task_Control_Block.Common. */
655 common_type = common_atcb_sym->type;
656
657 /* Get the type for Ada_Task_Control_Bloc.Common.Call.LL. */
658 ll_type = private_data_sym->type;
659
660 /* Get the field indices. */
661 fieldnos.common = ada_get_field_index (type, "common", 0);
662 fieldnos.state = ada_get_field_index (common_type, "state", 0);
663 fieldnos.parent = ada_get_field_index (common_type, "parent", 0);
664 fieldnos.priority = ada_get_field_index (common_type, "base_priority", 0);
665 fieldnos.image = ada_get_field_index (common_type, "task_image", 0);
666 fieldnos.image_len = ada_get_field_index (common_type, "task_image_len", 1);
667 fieldnos.call = ada_get_field_index (common_type, "call", 0);
668 fieldnos.ll = ada_get_field_index (common_type, "ll", 0);
669 fieldnos.ll_thread = ada_get_field_index (ll_type, "thread", 0);
670 fieldnos.ll_lwp = ada_get_field_index (ll_type, "lwp", 1);
671
672 /* On certain platforms such as x86-windows, the "lwp" field has been
673 named "thread_id". This field will likely be renamed in the future,
674 but we need to support both possibilities to avoid an unnecessary
675 dependency on a recent compiler. We therefore try locating the
676 "thread_id" field in place of the "lwp" field if we did not find
677 the latter. */
678 if (fieldnos.ll_lwp < 0)
679 fieldnos.ll_lwp = ada_get_field_index (ll_type, "thread_id", 1);
680
681 /* Set all the out parameters all at once, now that we are certain
682 that there are no potential error() anymore. */
683 *atcb_type = type;
684 *atcb_common_type = common_type;
685 *atcb_ll_type = ll_type;
686 *atcb_fieldnos = fieldnos;
687}
688
689/* Get from the debugging information the type description of the
690 record type Entry_Call_Record (this is the type of the field
691 Call.all in the Common_ATCB record type). Also return the index
692 of the field "Self" in Entry_Call_Record.
693
694 Error handling: Any data missing from the debugging info will cause
695 an error to be raised, and none of the return values to be set.
696 Users of this function can depend on the fact that all or none of the
697 return values will be set. */
698
699static void
700get_tcb_call_type_info (struct type **atcb_call_type,
701 int *atcb_call_self_fieldno)
702{
703 struct type *call_type;
704 int call_self_fieldno;
705
706#ifndef ADA_RETAIN_DOTS
707 const char *entry_call_record_name = "system__tasking__entry_call_record";
708#else
709 const char *entry_call_record_name = "system.tasking.entry_call_record";
710#endif
711
712 const struct symbol *entry_call_record_sym =
713 lookup_symbol (entry_call_record_name, NULL, VAR_DOMAIN, NULL, NULL);
714
715 if (entry_call_record_sym == NULL || entry_call_record_sym->type == NULL)
716 error ("Can not find Entry_Call_Record type. Aborting");
717
718 call_type = entry_call_record_sym->type;
719 call_self_fieldno = ada_get_field_index (call_type, "self", 0);
720
721 /* Set all the out parameters all at once, now that we are certain
722 that there are no potential error() anymore. */
723 *atcb_call_type = call_type;
724 *atcb_call_self_fieldno = call_self_fieldno;
725}
726
727/* Return the address of the Known_Tasks array maintained in
728 the Ada Runtime. Return NULL if the array could not be found,
729 meaning that the inferior program probably does not use tasking.
730
731 In order to provide a fast response time, this function caches
732 the Known_Tasks array address after the lookup during the first
733 call. Subsequent calls will simply return this cached address. */
734
735static CORE_ADDR
736get_known_tasks_addr (void)
737{
738 static CORE_ADDR known_tasks_addr = 0;
739
740 if (ada__tasks_check_symbol_table)
741 {
742 struct symbol *sym;
743 struct minimal_symbol *msym;
744
745 thread_support = 0;
746#if (defined(__alpha__) && defined(__osf__) & !defined(VXWORKS_TARGET)) \
747 || defined (_AIX) || defined (__CYGWIN__)
748 thread_support = 1;
749#elif defined (__fsu__)
750 msym = lookup_minimal_symbol (PTHREAD_KERN, NULL, NULL);
751 if (msym != NULL)
752 {
753 pthread_kern_addr = SYMBOL_VALUE_ADDRESS (msym);
754 thread_support = 1;
755 }
756#elif defined (HAVE_SPYTHREAD)
757 thread_support = libspy_enabled;
758#endif
759
760#ifdef I386_GNULINUX_TARGET
761 /* We support threads via the Linux Threads... */
762 thread_support = 1;
763#endif
764
765 msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL);
766 if (msym != NULL)
767 known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
768 else
769#ifndef VXWORKS_TARGET
770 return 0;
771#else
772 {
773 if (target_lookup_symbol (KNOWN_TASKS_NAME, &known_tasks_addr) != 0)
774 return 0;
775 }
776#endif
777
778 /* FIXME: brobecker 2003-03-05: Here would be a much better place
779 to attach the ada-tasks observers, instead of doing this
780 unconditionaly in _initialize_tasks. This would avoid an
781 unecessary notification when the inferior does not use tasking
782 or as long as the user does not use the ada-tasks commands.
783 Unfortunately, this is not possible for the moment: the current
784 code resets ada__tasks_check_symbol_table back to 1 whenever
785 symbols for a new program are being loaded. If we place the
786 observers intialization here, we will end up adding new observers
787 everytime we do the check for Ada tasking-related symbols
788 above. This would currently have benign effects, but is still
789 undesirable. The cleanest approach is probably to create a new
790 observer to notify us when the user is debugging a new program.
791 We would then reset ada__tasks_check_symbol_table back to 1
792 during the notification, but also detach all observers.
793 BTW: observers are probably not reentrant, so detaching during
794 a notification may not be the safest thing to do... Sigh...
795 But creating the new observer would be a good idea in any case,
796 since this allow us to make ada__tasks_check_symbol_table
797 static, which is a good bonus. */
798 ada__tasks_check_symbol_table = 0;
799 }
800
801 return known_tasks_addr;
802}
803
804/* Read the Known_Tasks array from the inferior memory, and store
805 it in task_list. Return non-zero upon success. */
806
807static int
808read_known_tasks_array (void)
809{
810 const int target_ptr_byte = TARGET_PTR_BIT / TARGET_CHAR_BIT;
811 const int temp_tasks_size = target_ptr_byte * MAX_NUMBER_OF_KNOWN_TASKS;
812 const CORE_ADDR known_tasks_addr = get_known_tasks_addr ();
813 char *temp_tasks = (char *) alloca (temp_tasks_size);
814 CORE_ADDR temp_task;
815 int i;
816
817 /* Step 1: Clear the current list, if any. */
818 init_task_list ();
819
820 /* If the application does not use task, then no more needs to be done.
821 It is important to have the task list cleared (see above) before we
822 return, as we don't want a stale task list to be used... This can
823 happen for instance when debugging a non-multitasking program after
824 having debugged a multitasking one. */
825 if (known_tasks_addr == 0)
826 return 0;
827
828 /* Step 2: Build a new list by reading the ATCBs from the Known_Tasks
829 array in the Ada runtime. */
830 read_memory (known_tasks_addr, temp_tasks, temp_tasks_size);
831 for (i = 0; i < MAX_NUMBER_OF_KNOWN_TASKS; i++)
832 {
833 temp_task = extract_typed_address (temp_tasks + i * target_ptr_byte,
834 builtin_type_void_data_ptr);
835
836 if (temp_task != 0)
837 {
838 if (get_entry_number (temp_task) == 0)
839 add_task_entry (temp_task, i);
840 }
841 }
842
843 /* Step 3: Unset stale_task_list_p, to avoid re-reading the Known_Tasks
844 array unless needed. Then report a success. */
845 stale_task_list_p = 0;
846 return 1;
847}
848
849/* Builds the task_list by reading the Known_Tasks array from
850 the inferior. Prints an appropriate message and returns non-zero
851 if it failed to build this list. */
852
853static int
854build_task_list (void)
855{
856 if (!target_has_stack)
857 error ("No stack");
858
859 if (stale_task_list_p)
860 read_known_tasks_array ();
861
862 if (task_list == NULL)
863 {
864 printf_filtered ("Your application does not use any Ada task.\n");
865 return 0;
866 }
867
868 return 1;
869}
870
871/* Extract the contents of the value as a string whose length is LENGTH,
872 and store the result in DEST. */
873
874static void
875value_as_string (char *dest, struct value *val, int length)
876{
877 memcpy (dest, VALUE_CONTENTS (val), length);
878}
879
880/* Extract the string image from the fat string corresponding to VAL,
881 and store it in DEST. The length of the string is stored in LEN. If
882 the string length is greater than MAX_LEN, then truncate the result
883 to the first MAX_LEN characters of the fat string. */
884
885static void
886read_fat_string_value (char *dest, int *len, struct value *val, int max_len)
887{
888 struct value *array_val;
889 struct value *bounds_val;
890
891 /* The following variables are made static to avoid recomputing them
892 each time this function is called. */
893 static int initialize_fieldnos = 1;
894 static int array_fieldno;
895 static int bounds_fieldno;
896 static int upper_bound_fieldno;
897
898 /* Get the index of the fields that we will need to read in order
899 to extract the string from the fat string. */
900 if (initialize_fieldnos)
901 {
902 struct type *type = VALUE_TYPE (val);
903 struct type *bounds_type;
904
905 array_fieldno = ada_get_field_index (type, "P_ARRAY", 0);
906 bounds_fieldno = ada_get_field_index (type, "P_BOUNDS", 0);
907
908 bounds_type = TYPE_FIELD_TYPE (type, bounds_fieldno);
909 if (TYPE_CODE (bounds_type) == TYPE_CODE_PTR)
910 bounds_type = TYPE_TARGET_TYPE (bounds_type);
911 if (TYPE_CODE (bounds_type) != TYPE_CODE_STRUCT)
912 error ("Unknown task name format. Aborting");
913 upper_bound_fieldno = ada_get_field_index (bounds_type, "UB0", 0);
914
915 initialize_fieldnos = 0;
916 }
917
918 /* Get the size of the task image by checking the value of the bounds.
919 The lower bound is always 1, so we only need to read the upper bound. */
920 bounds_val = value_ind (value_field (val, bounds_fieldno));
921 *len = value_as_long (value_field (bounds_val, upper_bound_fieldno));
922
923 /* Make sure that we do not read more than max_len characters... */
924 if (*len > max_len)
925 *len = max_len;
926
927 /* Extract LEN characters from the fat string. */
928 array_val = value_ind (value_field (val, array_fieldno));
929 read_memory (VALUE_ADDRESS (array_val), dest, *len);
930}
931
932/* Read the ATCB stored at ATCB_ADDR from the inferior memory. */
933
934static struct task_control_block
935read_atcb (CORE_ADDR atcb_addr)
936{
937 /* The type description for the ATCB record and subrecords, and
938 the associated tcb_fieldnos. For efficiency reasons, these are made
939 static so that we can compute them only once the first time and
940 reuse them later. */
941 static struct type *atcb_type = NULL;
942 static struct type *atcb_common_type = NULL;
943 static struct type *atcb_ll_type = NULL;
944 static struct tcb_fieldnos fieldno;
945
946 struct task_control_block result;
947 struct value *tcb_value;
948 struct value *ll_value;
949
950 if (atcb_type == NULL)
951 get_tcb_types_info (&atcb_type, &atcb_common_type, &atcb_ll_type, &fieldno);
952
953 tcb_value = value_from_contents_and_address (atcb_type, NULL, atcb_addr);
954 tcb_value = value_field (tcb_value, fieldno.common);
955
956 result.state = value_as_long (value_field (tcb_value, fieldno.state));
957 result.parent = value_as_address (value_field (tcb_value, fieldno.parent));
958 result.priority = value_as_long (value_field (tcb_value, fieldno.priority));
959
960 /* Depending on the GNAT version used, the task image is either a fat
961 string, or a thin array of characters. Older versions of GNAT used
962 to use fat strings, and therefore did not need an extra field in
963 the ATCB to store the string length. For efficiency reasons, newer
964 versions of GNAT replaced the fat string by a static buffer, but this
965 also required the addition of a new field named "Image_Len" containing
966 the length of the task name. The method used to extract the task name
967 is selected depending on the existence of this field. */
968 if (fieldno.image_len == -1)
969 {
970 read_fat_string_value (result.image, &result.image_len,
971 value_field (tcb_value, fieldno.image),
972 sizeof (result.image));
973 }
974 else
975 {
976 value_as_string (result.image, value_field (tcb_value, fieldno.image),
977 sizeof (result.image));
978 result.image_len =
979 value_as_long (value_field (tcb_value, fieldno.image_len));
980 }
981
982 result.call = value_as_address (value_field (tcb_value, fieldno.call));
983
984 ll_value = value_field (tcb_value, fieldno.ll);
985 result.thread = value_as_address (value_field (ll_value, fieldno.ll_thread));
986 if (fieldno.ll_lwp >= 0)
987 result.lwp = value_as_address (value_field (ll_value, fieldno.ll_lwp));
988 else
989 result.lwp = 0;
990
991 return result;
992}
993
994/* Read the ID of the task with which a task is attempting a rendez-vous
995 from the address of its Entry_Call_Record in the Ada TCB.
996 If the address of the Entry_Call_Record is null, then return null. */
997
998static CORE_ADDR
999read_caller (const CORE_ADDR call)
1000{
1001 /* The type description for the Entry_Call_Record, and the index of
1002 the field "Self". For efficiency reasons, these are made static
1003 so that we can compute them only once the first time and reuse them
1004 later. */
1005 static struct type *atcb_call_type;
1006 static int self_fieldno = -1;
1007
1008 struct value *call_value;
1009
1010 if (call == 0)
1011 return 0;
1012
1013 if (atcb_call_type == NULL)
1014 get_tcb_call_type_info (&atcb_call_type, &self_fieldno);
1015
1016 call_value = value_from_contents_and_address (atcb_call_type, NULL, call);
1017 return value_as_address (value_field (call_value, self_fieldno));
1018}
1019
1020#if 0
1021/* FIXME: Now modified and back in breakpoint.c */
1022/* breakpoint_task_match (PC) returns true if the breakpoint at PC
1023 is valid for current task. */
1024
1025int
1026breakpoint_task_match (CORE_ADDR pc)
1027{
1028 const int this_task = get_current_task ();
1029 const struct breakpoint *breakpoints = get_breakpoint_chain ();
1030 const struct breakpoint *b;
1031
1032 for (b = breakpoints; b; b = b->next)
1033 {
1034 if (b->enable_state != bp_disabled
1035 && b->enable_state != bp_shlib_disabled
1036 && (b->address == 0 || b->address == pc)
1037 && (b->task == 0 || b->task == this_task))
1038 {
1039 return 1;
1040 }
1041 }
1042
1043 return 0;
1044}
1045#endif
1046
14f9c5c9
AS
1047/* Print detailed information about specified task */
1048
1049static void
80ae6ee2 1050info_task (char *arg, int from_tty)
14f9c5c9 1051{
4c4b4cd2 1052#ifdef GNAT_GDB
14f9c5c9 1053 struct task_entry *pt, *pt2;
4c4b4cd2 1054 CORE_ADDR caller;
14f9c5c9
AS
1055 int num;
1056
4c4b4cd2
PH
1057 if (current_language->la_language != language_ada)
1058 {
1059 printf_filtered ("The current language does not support tasks.\n");
1060 return;
1061 }
1062
1063 target_find_new_threads ();
1064
14f9c5c9
AS
1065 pt = get_entry_vptr (atoi (arg));
1066 if (pt == NULL)
1067 {
d2e4a39e
AS
1068 printf_filtered ("Task %s not found.\n", arg);
1069 return;
14f9c5c9
AS
1070 }
1071
14f9c5c9 1072 /* print the Ada task id */
4c4b4cd2 1073 printf_filtered ("Ada Task: %s\n", paddr_nz (pt->task_id));
14f9c5c9
AS
1074
1075 /* print the name of the task */
4c4b4cd2
PH
1076 if (pt->atcb.image_len != 0)
1077 printf_filtered ("Name: %.*s\n", pt->atcb.image_len, pt->atcb.image);
d2e4a39e
AS
1078 else
1079 printf_filtered ("<no name>\n");
14f9c5c9
AS
1080
1081 /* print the thread id */
1082
4c4b4cd2
PH
1083 if (task_ptid_get_tid (pt->task_ptid) < 65536)
1084 printf_filtered
1085 ("Thread: %ld\n", (long int) task_ptid_get_tid (pt->task_ptid));
14f9c5c9 1086 else
4c4b4cd2
PH
1087 printf_filtered
1088 ("Thread: %#lx\n", (long int) task_ptid_get_tid (pt->task_ptid));
14f9c5c9 1089
4c4b4cd2 1090 if (task_ptid_get_lwp (pt->task_ptid) != 0)
14f9c5c9 1091 {
4c4b4cd2
PH
1092 if ((long) task_ptid_get_lwp (pt->task_ptid) < 65536)
1093 printf_filtered
1094 ("LWP: %ld\n", (long int) task_ptid_get_lwp (pt->task_ptid));
14f9c5c9 1095 else
4c4b4cd2
PH
1096 printf_filtered
1097 ("LWP: %#lx\n", (long int) task_ptid_get_lwp (pt->task_ptid));
14f9c5c9
AS
1098 }
1099
1100 /* print the parent gdb task id */
4c4b4cd2 1101 num = get_entry_number (pt->atcb.parent);
14f9c5c9
AS
1102 if (num != 0)
1103 {
1104 printf_filtered ("Parent: %d", num);
1105 pt2 = get_entry_vptr (num);
14f9c5c9
AS
1106
1107 /* print the name of the task */
4c4b4cd2
PH
1108 if (pt2->atcb.image_len != 0)
1109 printf_filtered (" (%.*s)\n", pt2->atcb.image_len, pt2->atcb.image);
14f9c5c9 1110 else
d2e4a39e 1111 printf_filtered ("\n");
14f9c5c9
AS
1112 }
1113 else
1114 printf_filtered ("No parent\n");
1115
1116 /* print the base priority of the task */
4c4b4cd2 1117 printf_filtered ("Base Priority: %d\n", pt->atcb.priority);
14f9c5c9
AS
1118
1119 /* print the current state of the task */
1120
1121 /* check if this task is accepting a rendezvous */
4c4b4cd2
PH
1122 caller = read_caller (pt->atcb.call);
1123 if (caller != 0)
14f9c5c9
AS
1124 {
1125 num = get_entry_number (caller);
1126 printf_filtered ("Accepting rendezvous with %d", num);
1127
1128 if (num != 0)
1129 {
1130 pt2 = get_entry_vptr (num);
14f9c5c9
AS
1131
1132 /* print the name of the task */
4c4b4cd2
PH
1133 if (pt2->atcb.image_len != 0) {
1134 printf_filtered (" (%.*s)\n", pt2->atcb.image_len, pt2->atcb.image);
1135 }
14f9c5c9
AS
1136 else
1137 printf_filtered ("\n");
1138 }
1139 else
4c4b4cd2 1140 printf_filtered ("\n");
14f9c5c9
AS
1141 }
1142 else
4c4b4cd2 1143 printf_filtered ("State: %s\n", long_task_states[pt->atcb.state]);
14f9c5c9 1144#endif
4c4b4cd2 1145}
14f9c5c9
AS
1146
1147/* Print information about currently known tasks */
1148
1149static void
80ae6ee2 1150info_tasks (char *arg, int from_tty)
14f9c5c9 1151{
4c4b4cd2 1152#ifdef GNAT_GDB
14f9c5c9 1153 struct task_entry *pt;
4c4b4cd2
PH
1154 CORE_ADDR caller;
1155 long thread_id = 0L;
14f9c5c9
AS
1156 int size;
1157 char car;
4c4b4cd2 1158 ptid_t current_ptid;
14f9c5c9
AS
1159
1160#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
1161 pthreadTeb_t thr;
1162 gdb_gregset_t regs;
1163#endif
1164
4c4b4cd2 1165 current_ptid = inferior_ptid;
14f9c5c9
AS
1166
1167#if !((defined(sun) && defined(__SVR4)) || defined(VXWORKS_TARGET) || defined(__WIN32__) || defined (hpux))
1168 if (thread_support)
1169#endif
4c4b4cd2 1170 thread_id = GET_CURRENT_THREAD (inferior_ptid);
14f9c5c9
AS
1171
1172 /* print the header */
1173
1174#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
1175 printf_filtered
d2e4a39e 1176 (" ID TID P-ID Pri Stack %% State Name\n");
14f9c5c9
AS
1177#else
1178 printf_filtered (" ID TID P-ID Pri State Name\n");
1179#endif
1180
1181 /* Now that we have a list of task id's, we can print them */
1182 pt = task_list;
1183 while (pt)
1184 {
14f9c5c9
AS
1185 /* print a star if this task is the current one */
1186 if (thread_id)
1187#if defined (__WIN32__) || defined (SGI) || defined (hpux)
4c4b4cd2
PH
1188 printf_filtered
1189 (task_ptid_get_lwp (pt->task_ptid) == thread_id ? "*" : " ");
14f9c5c9 1190#else
4c4b4cd2
PH
1191 printf_filtered
1192 (task_ptid_get_thread_id (pt->task_ptid) == thread_id ? "*" : " ");
14f9c5c9
AS
1193#endif
1194
1195 /* print the gdb task id */
1196 printf_filtered ("%3d", pt->task_num);
1197
1198 /* print the Ada task id */
4c4b4cd2 1199 printf_filtered (" %9lx", (long) pt->task_id);
14f9c5c9
AS
1200
1201 /* print the parent gdb task id */
4c4b4cd2 1202 printf_filtered (" %4d", get_entry_number (pt->atcb.parent));
14f9c5c9
AS
1203
1204 /* print the base priority of the task */
4c4b4cd2 1205 printf_filtered (" %3d", pt->atcb.priority);
14f9c5c9
AS
1206
1207#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
4c4b4cd2
PH
1208 if (pt->task_num == 1 || pt->atcb.state == Terminated)
1209 {
1210 printf_filtered (" Unknown");
1211 goto next;
1212 }
1213
1214 READ_MEMORY (pt->atcb.thread, thr);
1215 switch_to_thread (task_ptid_get_ptid (pt->task_ptid));
1216 /* ??? Brobecker 2003-03-13: Not sure what the next line is used for.
1217 And even if useful, it should probably be replaced by call to
1218 task_ptid_get_thread_id. */
1219 current_thread = task_ptid_get_tid (pt->task_ptid);
d2e4a39e
AS
1220 regs.regs[SP_REGNUM] = 0;
1221 if (dec_thread_get_registers (&regs, NULL) == 0)
4c4b4cd2
PH
1222 {
1223 pt->stack_per = (100 * ((long) thr.__stack_base -
1224 regs.regs[SP_REGNUM])) / thr.__stack_size;
1225 /* if the thread is terminated but still there, the
1226 stack_base/size values are erroneous. Try to patch it */
1227 if (pt->stack_per < 0 || pt->stack_per > 100)
1228 pt->stack_per = 0;
1229 }
1230 else
1231 {
1232 /* Set stack_per to an invalid value to signal that we did not
1233 manage to compute its value. */
1234 pt->stack_per = -1;
1235 }
14f9c5c9
AS
1236
1237 /* print information about stack space used in the thread */
d2e4a39e 1238 if (thr.__stack_size < 1024 * 1024)
4c4b4cd2
PH
1239 {
1240 size = thr.__stack_size / 1024;
1241 car = 'K';
1242 }
d2e4a39e 1243 else if (thr.__stack_size < 1024 * 1024 * 1024)
4c4b4cd2
PH
1244 {
1245 size = thr.__stack_size / 1024 / 1024;
1246 car = 'M';
1247 }
1248 else /* Who knows... */
1249 {
1250 size = thr.__stack_size / 1024 / 1024 / 1024;
1251 car = 'G';
1252 }
1253
1254 /* print the stack usage in percent, if available. */
1255 if (pt->stack_per != -1)
1256 printf_filtered (" %4d%c %2d", size, car, pt->stack_per);
1257 else
1258 {
1259 /* This error is not serious enough that we should raise
1260 an internal error, but print '???' to make it unambiguous
1261 that we failed to compute this value. */
1262 printf_filtered (" ???");
1263 }
1264
d2e4a39e 1265 next:
14f9c5c9
AS
1266#endif
1267
1268 /* print the current state of the task */
1269
1270 /* check if this task is accepting a rendezvous */
4c4b4cd2
PH
1271 caller = read_caller (pt->atcb.call);
1272 if (caller != 0)
1273 printf_filtered (" Accepting RV with %-4d",
1274 get_entry_number (caller));
14f9c5c9 1275 else
4c4b4cd2 1276 {
14f9c5c9 1277#if defined (__WIN32__) || defined (SGI) || defined (hpux)
4c4b4cd2
PH
1278 if (pt->atcb.state == Runnable
1279 && (thread_id
1280 && task_ptid_get_lwp (pt->task_ptid) == thread_id))
14f9c5c9 1281#else
4c4b4cd2
PH
1282 if (pt->atcb.state == Runnable
1283 && (thread_id
1284 && task_ptid_get_thread_id (pt->task_ptid) == thread_id))
14f9c5c9 1285#endif
4c4b4cd2
PH
1286 /* Replace "Runnable" by "Running" if this is the current task */
1287 printf_filtered (" %-22s", "Running");
1288 else
1289 printf_filtered (" %-22s", task_states[pt->atcb.state]);
1290 }
14f9c5c9
AS
1291
1292 /* finally, print the name of the task */
4c4b4cd2
PH
1293 if (pt->atcb.image_len != 0) {
1294 printf_filtered (" %.*s\n", pt->atcb.image_len, pt->atcb.image);
1295 }
d2e4a39e
AS
1296 else
1297 printf_filtered (" <no name>\n");
14f9c5c9
AS
1298
1299 pt = pt->next_task;
1300 }
4c4b4cd2
PH
1301 if (!ptid_equal (inferior_ptid, current_ptid))
1302 switch_to_thread (current_ptid);
1303#endif
14f9c5c9
AS
1304}
1305
1306static void
80ae6ee2 1307info_tasks_command (char *arg, int from_tty)
14f9c5c9 1308{
4c4b4cd2
PH
1309 const int task_list_built = build_task_list ();
1310
1311 if (!task_list_built)
1312 return;
1313
d2e4a39e
AS
1314 if (arg == NULL || *arg == '\000')
1315 info_tasks (arg, from_tty);
1316 else
1317 info_task (arg, from_tty);
14f9c5c9
AS
1318}
1319
4c4b4cd2 1320/* Switch to task indicated by NEW_TASK. Return 0 iff successful. */
14f9c5c9 1321
4c4b4cd2
PH
1322static int
1323switch_to_task (struct task_entry *new_task)
14f9c5c9 1324{
4c4b4cd2
PH
1325#ifdef GNAT_GDB
1326 /* Raise an error if task-switching is currently not allowed. */
1327 if (!THREAD_SWITCH_ALLOWED ())
1328 error ("Task switching is currently not allowed.");
14f9c5c9 1329
4c4b4cd2
PH
1330 if (!task_is_alive (new_task->atcb.state))
1331 error ("Can not switch to task %d: Task is no longer running",
1332 new_task->task_num);
14f9c5c9 1333
4c4b4cd2
PH
1334 current_task = new_task->task_num;
1335 current_thread = task_ptid_get_thread_id (new_task->task_ptid);
14f9c5c9 1336
4c4b4cd2
PH
1337 if (current_task_id == -1)
1338 {
1339 SAVE_TASK_REGISTERS (new_task);
1340 current_task_id = ada_get_current_task (inferior_ptid);
1341 }
14f9c5c9 1342
4c4b4cd2 1343 if (SPECIAL_THREAD_SUPPORT_ACTIVE ())
14f9c5c9 1344 {
4c4b4cd2
PH
1345 /* FIXME: Integrate with switch_to_thread */
1346 int ret_code;
14f9c5c9 1347 flush_cached_frames ();
4c4b4cd2
PH
1348 registers_changed ();
1349 if (current_task == current_task_id)
1350 {
1351 RESTORE_TASK_REGISTERS (new_task);
1352 ret_code = 0;
1353 }
14f9c5c9 1354 else
4c4b4cd2
PH
1355 ret_code = THREAD_FETCH_REGISTERS ();
1356 if (ret_code == 0)
1357 stop_pc = read_pc ();
14f9c5c9 1358 select_frame (get_current_frame ());
4c4b4cd2 1359 return ret_code;
14f9c5c9 1360 }
4c4b4cd2
PH
1361 else if (task_ptid_get_pid (new_task->task_ptid) != 0) /* ?? */
1362 {
1363 switch_to_thread (task_ptid_get_ptid (new_task->task_ptid));
1364 return 0;
1365 }
1366#endif
14f9c5c9
AS
1367 return -1;
1368}
1369
4c4b4cd2
PH
1370/* Print a message telling the user id of the current task.
1371 Print an error message if the application does not appear to
1372 be using any Ada task. */
1373
80ae6ee2 1374static void
4c4b4cd2 1375display_current_task_id (void)
14f9c5c9 1376{
4c4b4cd2 1377 const int current_task = ada_get_current_task (inferior_ptid);
14f9c5c9 1378
4c4b4cd2
PH
1379 if (current_task == -1)
1380 printf_filtered ("[Current task is unknown]\n");
1381 else
1382 printf_filtered ("[Current task is %d]\n", current_task);
1383}
1384
1385/* Parse and evaluate TIDSTR into a task id, and try to switch to
1386 that task. Print an error message if the task switch failed. */
14f9c5c9 1387
4c4b4cd2
PH
1388static void
1389task_command_1 (char *tidstr, int from_tty)
1390{
1391 const int num = value_as_long (parse_and_eval (tidstr));
1392 struct task_entry *e = get_entry_vptr (num);
14f9c5c9
AS
1393
1394 if (e == NULL)
1395 error ("Task ID %d not known. Use the \"info tasks\" command to\n"
4c4b4cd2 1396 "see the IDs of currently known tasks", num);
14f9c5c9 1397
4c4b4cd2 1398 if (switch_to_task (e) == 0)
14f9c5c9 1399 {
4c4b4cd2 1400 ada_find_printable_frame (get_selected_frame ());
14f9c5c9 1401 printf_filtered ("[Switching to task %d]\n", num);
4c4b4cd2
PH
1402 print_stack_frame (get_selected_frame (),
1403 frame_relative_level (get_selected_frame ()), 1);
14f9c5c9
AS
1404 }
1405 else
1406 printf_filtered ("Unable to switch to task %d\n", num);
1407}
1408
4c4b4cd2
PH
1409/* Switch to task indicated in TIDSTR. Simply print the current task
1410 if TIDSTR is empty or NULL. */
1411
1412static void
1413task_command (char *tidstr, int from_tty)
1414{
1415 const int task_list_built = build_task_list ();
1416
1417 if (!task_list_built)
1418 return;
1419
1420 if (tidstr == NULL || tidstr[0] == '\0')
1421 display_current_task_id ();
1422 else
1423 task_command_1 (tidstr, from_tty);
1424}
1425
1426#if defined (__fsu__) || (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET))
1427/* Restore saved registers if there was a task switch. */
1428void
1429ada_reset_thread_registers (void)
1430{
1431 if (current_task_id != -1 && SPECIAL_THREAD_SUPPORT_ACTIVE ())
1432 {
1433 supply_gregset (&gregset_saved);
1434 supply_fpregset (&fpregset_saved);
1435 reinit_frame_cache ();
1436 stop_pc = read_pc ();
1437 }
1438 current_task_id = -1;
1439}
1440#else
1441void
1442ada_reset_thread_registers (void)
1443{
1444}
1445#endif
1446
1447/* The 'normal_stop' observer notification callback. */
1448
1449static void
1450normal_stop_notification (void)
1451{
1452 /* The inferior has been resumed, and just stopped. This means that
1453 our task_list needs to be recomputed before it can be used again. */
1454 stale_task_list_p = 1;
1455}
1456
1457/* Attach all the observers needed by the ada-tasks module. */
1458
1459static void
1460ada_tasks_attach_observers (void)
1461{
1462 observer_attach_normal_stop (&normal_stop_notification);
1463}
1464
14f9c5c9 1465void
80ae6ee2 1466_initialize_tasks (void)
14f9c5c9 1467{
4c4b4cd2 1468#ifdef GNAT_GDB
14f9c5c9
AS
1469 extern struct cmd_list_element *cmdlist;
1470
4c4b4cd2
PH
1471 ada_tasks_attach_observers ();
1472
d2e4a39e 1473 add_info ("tasks", info_tasks_command,
4c4b4cd2
PH
1474 "Without argument: list all known Ada tasks, with status information.\n"
1475 "info tasks n: print detailed information of task n.");
14f9c5c9 1476
4c4b4cd2
PH
1477 add_cmd ("task", class_run, task_command,
1478 "Without argument: print the current task ID.\n"
1479 "task n: Use this command to switch to task n.",
1480 &cmdlist);
1481#endif
14f9c5c9 1482}
This page took 0.262196 seconds and 4 git commands to generate.