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