OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [ada-tasks.c] - Blame information for rev 1181

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* file ada-tasks.c: Ada tasking control for GDB
2
   Copyright 1997 Free Software Foundation, Inc.
3
   Contributed by Ada Core Technologies, Inc
4
.
5
   This file is part of GDB.
6
 
7
   [$Id: ada-tasks.c,v 1.1.1.1 2003-08-14 22:50:20 sfurman Exp $]
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
 
17
#include <ctype.h>
18
#include "defs.h"
19
#include "command.h"
20
#include "value.h"
21
#include "language.h"
22
#include "inferior.h"
23
#include "symtab.h"
24
#include "target.h"
25
#include "gdbcore.h"
26
 
27
#if (defined(__alpha__) && defined(__osf__) && !defined(__alpha_vxworks))
28
#include <sys/procfs.h>
29
#endif
30
 
31
#if (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET))
32
#include "gregset.h"
33
#endif
34
 
35
#include "ada-lang.h"
36
 
37
/* FIXME: move all this conditional compilation in description
38
   files or in configure.in */
39
 
40
#if defined (VXWORKS_TARGET)
41
#define THREAD_TO_PID(tid,lwpid) (tid)
42
 
43
#elif defined (linux)
44
#define THREAD_TO_PID(tid,lwpid) (0)
45
 
46
#elif (defined (sun) && defined (__SVR4))
47
#define THREAD_TO_PID thread_to_pid
48
 
49
#elif defined (sgi) || defined (__WIN32__) || defined (hpux)
50
#define THREAD_TO_PID(tid,lwpid) ((int)lwpid)
51
 
52
#else
53
#define THREAD_TO_PID(tid,lwpid) (0)
54
#endif
55
 
56
#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
57
#define THREAD_FETCH_REGISTERS dec_thread_fetch_registers
58
#define GET_CURRENT_THREAD dec_thread_get_current_thread
59
extern int dec_thread_get_registers (gdb_gregset_t *, gdb_fpregset_t *);
60
#endif
61
 
62
#if defined (_AIX)
63
#define THREAD_FETCH_REGISTERS aix_thread_fetch_registers
64
#define GET_CURRENT_THREAD aix_thread_get_current_thread
65
#endif
66
 
67
#if defined(VXWORKS_TARGET)
68
#define GET_CURRENT_THREAD() ((void*)inferior_pid)
69
#define THREAD_FETCH_REGISTERS() (-1)
70
 
71
#elif defined (sun) && defined (__SVR4)
72
#define GET_CURRENT_THREAD solaris_thread_get_current_thread
73
#define THREAD_FETCH_REGISTERS() (-1)
74
extern void *GET_CURRENT_THREAD ();
75
 
76
#elif defined (_AIX) || (defined(__alpha__) && defined(__osf__))
77
extern void *GET_CURRENT_THREAD ();
78
 
79
#elif defined (__WIN32__) || defined (hpux)
80
#define GET_CURRENT_THREAD() (inferior_pid)
81
#define THREAD_FETCH_REGISTERS() (-1)
82
 
83
#else
84
#define GET_CURRENT_THREAD() (NULL)
85
#define THREAD_FETCH_REGISTERS() (-1)
86
#endif
87
 
88
#define KNOWN_TASKS_NAME "system__tasking__debug__known_tasks"
89
 
90
#define READ_MEMORY(addr, var) read_memory (addr, (char*) &var, sizeof (var))
91
/* external declarations */
92
 
93
extern struct value *find_function_in_inferior (char *);
94
 
95
/* Global visible variables */
96
 
97
struct task_entry *task_list = NULL;
98
int ada__tasks_check_symbol_table = 1;
99
void *pthread_kern_addr = NULL;
100
 
101
#if (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET))
102
gdb_gregset_t gregset_saved;
103
gdb_fpregset_t fpregset_saved;
104
#endif
105
 
106
/* The maximum number of tasks known to the Ada runtime */
107
const int MAX_NUMBER_OF_KNOWN_TASKS = 1000;
108
 
109
/* the current task */
110
int current_task = -1, current_task_id = -1, current_task_index;
111
void *current_thread, *current_lwp;
112
 
113
char *ada_task_states[] = {
114
  "Unactivated",
115
  "Runnable",
116
  "Terminated",
117
  "Child Activation Wait",
118
  "Accept Statement",
119
  "Waiting on entry call",
120
  "Async Select Wait",
121
  "Delay Sleep",
122
  "Child Termination Wait",
123
  "Wait Child in Term Alt",
124
  "",
125
  "",
126
  "",
127
  "",
128
  "Asynchronous Hold"
129
};
130
 
131
/* Global internal types */
132
 
133
static char *ada_long_task_states[] = {
134
  "Unactivated",
135
  "Runnable",
136
  "Terminated",
137
  "Waiting for child activation",
138
  "Blocked in accept statement",
139
  "Waiting on entry call",
140
  "Asynchronous Selective Wait",
141
  "Delay Sleep",
142
  "Waiting for children termination",
143
  "Waiting for children in terminate alternative",
144
  "",
145
  "",
146
  "",
147
  "",
148
  "Asynchronous Hold"
149
};
150
 
151
/* Global internal variables */
152
 
153
static int highest_task_num = 0;
154
int thread_support = 0;          /* 1 if the thread library in use is supported */
155
static int gdbtk_task_initialization = 0;
156
 
157
static int
158
add_task_entry (void *p_task_id, int index)
159
{
160
  struct task_entry *new_task_entry = NULL;
161
  struct task_entry *pt;
162
 
163
  highest_task_num++;
164
  new_task_entry = xmalloc (sizeof (struct task_entry));
165
  new_task_entry->task_num = highest_task_num;
166
  new_task_entry->task_id = p_task_id;
167
  new_task_entry->known_tasks_index = index;
168
  new_task_entry->next_task = NULL;
169
  pt = task_list;
170
  if (pt)
171
    {
172
      while (pt->next_task)
173
        pt = pt->next_task;
174
      pt->next_task = new_task_entry;
175
      pt->stack_per = 0;
176
    }
177
  else
178
    task_list = new_task_entry;
179
  return new_task_entry->task_num;
180
}
181
 
182
int
183
get_entry_number (void *p_task_id)
184
{
185
  struct task_entry *pt;
186
 
187
  pt = task_list;
188
  while (pt != NULL)
189
    {
190
      if (pt->task_id == p_task_id)
191
        return pt->task_num;
192
      pt = pt->next_task;
193
    }
194
  return 0;
195
}
196
 
197
static struct task_entry *
198
get_thread_entry_vptr (void *thread)
199
{
200
  struct task_entry *pt;
201
 
202
  pt = task_list;
203
  while (pt != NULL)
204
    {
205
      if (pt->thread == thread)
206
        return pt;
207
      pt = pt->next_task;
208
    }
209
  return 0;
210
}
211
 
212
static struct task_entry *
213
get_entry_vptr (int p_task_num)
214
{
215
  struct task_entry *pt;
216
 
217
  pt = task_list;
218
  while (pt)
219
    {
220
      if (pt->task_num == p_task_num)
221
        return pt;
222
      pt = pt->next_task;
223
    }
224
  return NULL;
225
}
226
 
227
void
228
init_task_list (void)
229
{
230
  struct task_entry *pt, *old_pt;
231
 
232
  pt = task_list;
233
  while (pt)
234
    {
235
      old_pt = pt;
236
      pt = pt->next_task;
237
      xfree (old_pt);
238
    };
239
  task_list = NULL;
240
  highest_task_num = 0;
241
}
242
 
243
int
244
valid_task_id (int task)
245
{
246
  return get_entry_vptr (task) != NULL;
247
}
248
 
249
void *
250
get_self_id (void)
251
{
252
  struct value *val;
253
  void *self_id;
254
  int result;
255
  struct task_entry *ent;
256
  extern int do_not_insert_breakpoints;
257
 
258
#if !((defined(sun) && defined(__SVR4)) || defined(VXWORKS_TARGET) || defined(__WIN32__))
259
  if (thread_support)
260
#endif
261
    {
262
      ent = get_thread_entry_vptr (GET_CURRENT_THREAD ());
263
      return ent ? ent->task_id : 0;
264
    }
265
 
266
  /* FIXME: calling a function in the inferior with a multithreaded application
267
     is not reliable, so return NULL if there is no safe way to get the current
268
     task */
269
  return NULL;
270
}
271
 
272
int
273
get_current_task (void)
274
{
275
  int result;
276
 
277
  /* FIXME: language_ada should be defined in defs.h */
278
  /*  if (current_language->la_language != language_ada) return -1; */
279
 
280
  result = get_entry_number (get_self_id ());
281
 
282
  /* return -1 if not found */
283
  return result == 0 ? -1 : result;
284
}
285
 
286
/* Print detailed information about specified task */
287
 
288
static void
289
info_task (char *arg, int from_tty)
290
{
291
  void *temp_task;
292
  struct task_entry *pt, *pt2;
293
  void *self_id, *caller;
294
  struct task_fields atcb, atcb2;
295
  struct entry_call call;
296
  int bounds[2];
297
  char image[256];
298
  int num;
299
 
300
  /* FIXME: language_ada should be defined in defs.h */
301
  /*  if (current_language->la_language != language_ada)
302
     {
303
     printf_filtered ("The current language does not support tasks.\n");
304
     return;
305
     }
306
   */
307
  pt = get_entry_vptr (atoi (arg));
308
  if (pt == NULL)
309
    {
310
      printf_filtered ("Task %s not found.\n", arg);
311
      return;
312
    }
313
 
314
  temp_task = pt->task_id;
315
 
316
  /* read the atcb in the inferior */
317
  READ_MEMORY ((CORE_ADDR) temp_task, atcb);
318
 
319
  /* print the Ada task id */
320
  printf_filtered ("Ada Task: %p\n", temp_task);
321
 
322
  /* print the name of the task */
323
  if (atcb.image.P_ARRAY != NULL)
324
    {
325
      READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb.image.P_BOUNDS), bounds);
326
      bounds[1] = EXTRACT_INT (bounds[1]);
327
      read_memory ((CORE_ADDR) EXTRACT_ADDRESS (atcb.image.P_ARRAY),
328
                   (char *) &image, bounds[1]);
329
      printf_filtered ("Name: %.*s\n", bounds[1], image);
330
    }
331
  else
332
    printf_filtered ("<no name>\n");
333
 
334
  /* print the thread id */
335
 
336
  if ((long) pt->thread < 65536)
337
    printf_filtered ("Thread: %ld\n", (long int) pt->thread);
338
  else
339
    printf_filtered ("Thread: %p\n", pt->thread);
340
 
341
  if ((long) pt->lwp != 0)
342
    {
343
      if ((long) pt->lwp < 65536)
344
        printf_filtered ("LWP: %ld\n", (long int) pt->lwp);
345
      else
346
        printf_filtered ("LWP: %p\n", pt->lwp);
347
    }
348
 
349
  /* print the parent gdb task id */
350
  num = get_entry_number (EXTRACT_ADDRESS (atcb.parent));
351
  if (num != 0)
352
    {
353
      printf_filtered ("Parent: %d", num);
354
      pt2 = get_entry_vptr (num);
355
      READ_MEMORY ((CORE_ADDR) pt2->task_id, atcb2);
356
 
357
      /* print the name of the task */
358
      if (atcb2.image.P_ARRAY != NULL)
359
        {
360
          READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb2.image.P_BOUNDS),
361
                       bounds);
362
          bounds[1] = EXTRACT_INT (bounds[1]);
363
          read_memory ((CORE_ADDR) EXTRACT_ADDRESS (atcb2.image.P_ARRAY),
364
                       (char *) &image, bounds[1]);
365
          printf_filtered (" (%.*s)\n", bounds[1], image);
366
        }
367
      else
368
        printf_filtered ("\n");
369
    }
370
  else
371
    printf_filtered ("No parent\n");
372
 
373
  /* print the base priority of the task */
374
  printf_filtered ("Base Priority: %d\n", EXTRACT_INT (atcb.priority));
375
 
376
  /* print the current state of the task */
377
 
378
  /* check if this task is accepting a rendezvous */
379
  if (atcb.call == NULL)
380
    caller = NULL;
381
  else
382
    {
383
      READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb.call), call);
384
      caller = EXTRACT_ADDRESS (call.self);
385
    }
386
 
387
  if (caller != NULL)
388
    {
389
      num = get_entry_number (caller);
390
      printf_filtered ("Accepting rendezvous with %d", num);
391
 
392
      if (num != 0)
393
        {
394
          pt2 = get_entry_vptr (num);
395
          READ_MEMORY ((CORE_ADDR) pt2->task_id, atcb2);
396
 
397
          /* print the name of the task */
398
          if (atcb2.image.P_ARRAY != NULL)
399
            {
400
              READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb2.image.P_BOUNDS),
401
                           bounds);
402
              bounds[1] = EXTRACT_INT (bounds[1]);
403
              read_memory ((CORE_ADDR) EXTRACT_ADDRESS (atcb2.image.P_ARRAY),
404
                           (char *) &image, bounds[1]);
405
              printf_filtered (" (%.*s)\n", bounds[1], image);
406
            }
407
          else
408
            printf_filtered ("\n");
409
        }
410
      else
411
        printf_filtered ("\n");
412
    }
413
  else
414
    printf_filtered ("State: %s\n", ada_long_task_states[atcb.state]);
415
}
416
 
417
#if 0
418
 
419
/* A useful function that shows the alignment of all the fields in the
420
   tasks_fields structure
421
 */
422
 
423
print_align (void)
424
{
425
  struct task_fields tf;
426
  void *tf_base = &(tf);
427
  void *tf_state = &(tf.state);
428
  void *tf_entry_num = &(tf.entry_num);
429
  void *tf_parent = &(tf.parent);
430
  void *tf_priority = &(tf.priority);
431
  void *tf_current_priority = &(tf.current_priority);
432
  void *tf_image = &(tf.image);
433
  void *tf_call = &(tf.call);
434
  void *tf_thread = &(tf.thread);
435
  void *tf_lwp = &(tf.lwp);
436
  printf_filtered ("\n");
437
  printf_filtered ("(tf_base = 0x%x)\n", tf_base);
438
  printf_filtered ("task_fields.entry_num        at %3d (0x%x)\n",
439
                   tf_entry_num - tf_base, tf_entry_num);
440
  printf_filtered ("task_fields.state            at %3d (0x%x)\n",
441
                   tf_state - tf_base, tf_state);
442
  printf_filtered ("task_fields.parent           at %3d (0x%x)\n",
443
                   tf_parent - tf_base, tf_parent);
444
  printf_filtered ("task_fields.priority         at %3d (0x%x)\n",
445
                   tf_priority - tf_base, tf_priority);
446
  printf_filtered ("task_fields.current_priority at %3d (0x%x)\n",
447
                   tf_current_priority - tf_base, tf_current_priority);
448
  printf_filtered ("task_fields.image            at %3d (0x%x)\n",
449
                   tf_image - tf_base, tf_image);
450
  printf_filtered ("task_fields.call             at %3d (0x%x)\n",
451
                   tf_call - tf_base, tf_call);
452
  printf_filtered ("task_fields.thread           at %3d (0x%x)\n",
453
                   tf_thread - tf_base, tf_thread);
454
  printf_filtered ("task_fields.lwp              at %3d (0x%x)\n",
455
                   tf_lwp - tf_base, tf_lwp);
456
  printf_filtered ("\n");
457
}
458
#endif
459
 
460
/* Print information about currently known tasks */
461
 
462
static void
463
info_tasks (char *arg, int from_tty)
464
{
465
  struct value *val;
466
  int i, task_number, state;
467
  void *temp_task, *temp_tasks[MAX_NUMBER_OF_KNOWN_TASKS];
468
  struct task_entry *pt;
469
  void *self_id, *caller, *thread_id = NULL;
470
  struct task_fields atcb;
471
  struct entry_call call;
472
  int bounds[2];
473
  char image[256];
474
  int size;
475
  char car;
476
 
477
#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
478
  pthreadTeb_t thr;
479
  gdb_gregset_t regs;
480
#endif
481
 
482
  static struct symbol *sym;
483
  static struct minimal_symbol *msym;
484
  static void *known_tasks_addr = NULL;
485
 
486
  int init_only = gdbtk_task_initialization;
487
  gdbtk_task_initialization = 0;
488
 
489
  task_number = 0;
490
 
491
  if (PIDGET (inferior_ptid) == 0)
492
    {
493
      printf_filtered ("The program is not being run under gdb. ");
494
      printf_filtered ("Use 'run' or 'attach' first.\n");
495
      return;
496
    }
497
 
498
  if (ada__tasks_check_symbol_table)
499
    {
500
      thread_support = 0;
501
#if (defined(__alpha__) && defined(__osf__) & !defined(VXWORKS_TARGET)) || \
502
    defined (_AIX)
503
      thread_support = 1;
504
#endif
505
 
506
      msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL);
507
      if (msym != NULL)
508
        known_tasks_addr = (void *) SYMBOL_VALUE_ADDRESS (msym);
509
      else
510
#ifndef VXWORKS_TARGET
511
        return;
512
#else
513
        {
514
          if (target_lookup_symbol (KNOWN_TASKS_NAME, &known_tasks_addr) != 0)
515
            return;
516
        }
517
#endif
518
 
519
      ada__tasks_check_symbol_table = 0;
520
    }
521
 
522
  if (known_tasks_addr == NULL)
523
    return;
524
 
525
#if !((defined(sun) && defined(__SVR4)) || defined(VXWORKS_TARGET) || defined(__WIN32__) || defined (hpux))
526
  if (thread_support)
527
#endif
528
    thread_id = GET_CURRENT_THREAD ();
529
 
530
  /* then we get a list of tasks created */
531
 
532
  init_task_list ();
533
 
534
  READ_MEMORY ((CORE_ADDR) known_tasks_addr, temp_tasks);
535
 
536
  for (i = 0; i < MAX_NUMBER_OF_KNOWN_TASKS; i++)
537
    {
538
      temp_task = EXTRACT_ADDRESS (temp_tasks[i]);
539
 
540
      if (temp_task != NULL)
541
        {
542
          task_number = get_entry_number (temp_task);
543
          if (task_number == 0)
544
            task_number = add_task_entry (temp_task, i);
545
        }
546
    }
547
 
548
  /* Return without printing anything if this function was called in
549
     order to init GDBTK tasking. */
550
 
551
  if (init_only)
552
    return;
553
 
554
  /* print the header */
555
 
556
#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
557
  printf_filtered
558
    ("  ID       TID P-ID Pri Stack  %% State                  Name\n");
559
#else
560
  printf_filtered ("  ID       TID P-ID Pri State                  Name\n");
561
#endif
562
 
563
  /* Now that we have a list of task id's, we can print them */
564
  pt = task_list;
565
  while (pt)
566
    {
567
      temp_task = pt->task_id;
568
 
569
      /* read the atcb in the inferior */
570
      READ_MEMORY ((CORE_ADDR) temp_task, atcb);
571
 
572
      /* store the thread id for future use */
573
      pt->thread = EXTRACT_ADDRESS (atcb.thread);
574
 
575
#if defined (linux)
576
      pt->lwp = (void *) THREAD_TO_PID (atcb.thread, 0);
577
#else
578
      pt->lwp = EXTRACT_ADDRESS (atcb.lwp);
579
#endif
580
 
581
      /* print a star if this task is the current one */
582
      if (thread_id)
583
#if defined (__WIN32__) || defined (SGI) || defined (hpux)
584
        printf_filtered (pt->lwp == thread_id ? "*" : " ");
585
#else
586
        printf_filtered (pt->thread == thread_id ? "*" : " ");
587
#endif
588
 
589
      /* print the gdb task id */
590
      printf_filtered ("%3d", pt->task_num);
591
 
592
      /* print the Ada task id */
593
#ifndef VXWORKS_TARGET
594
      printf_filtered (" %9lx", (long) temp_task);
595
#else
596
#ifdef TARGET_64
597
      printf_filtered (" %#9lx", (unsigned long) pt->thread & 0x3ffffffffff);
598
#else
599
      printf_filtered (" %#9lx", (long) pt->thread);
600
#endif
601
#endif
602
 
603
      /* print the parent gdb task id */
604
      printf_filtered
605
        (" %4d", get_entry_number (EXTRACT_ADDRESS (atcb.parent)));
606
 
607
      /* print the base priority of the task */
608
      printf_filtered (" %3d", EXTRACT_INT (atcb.priority));
609
 
610
#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET)
611
      if (pt->task_num == 1 || atcb.state == Terminated)
612
        {
613
          printf_filtered ("  Unknown");
614
          goto next;
615
        }
616
 
617
      read_memory ((CORE_ADDR) atcb.thread, &thr, sizeof (thr));
618
      current_thread = atcb.thread;
619
      regs.regs[SP_REGNUM] = 0;
620
      if (dec_thread_get_registers (&regs, NULL) == 0)
621
        {
622
          pt->stack_per = (100 * ((long) thr.__stack_base -
623
                                  regs.regs[SP_REGNUM])) / thr.__stack_size;
624
          /* if the thread is terminated but still there, the
625
             stack_base/size values are erroneous. Try to patch it */
626
          if (pt->stack_per < 0 || pt->stack_per > 100)
627
            pt->stack_per = 0;
628
        }
629
 
630
      /* print information about stack space used in the thread */
631
      if (thr.__stack_size < 1024 * 1024)
632
        {
633
          size = thr.__stack_size / 1024;
634
          car = 'K';
635
        }
636
      else if (thr.__stack_size < 1024 * 1024 * 1024)
637
        {
638
          size = thr.__stack_size / 1024 / 1024;
639
          car = 'M';
640
        }
641
      else                      /* Who knows... */
642
        {
643
          size = thr.__stack_size / 1024 / 1024 / 1024;
644
          car = 'G';
645
        }
646
      printf_filtered (" %4d%c %2d", size, car, pt->stack_per);
647
    next:
648
#endif
649
 
650
      /* print the current state of the task */
651
 
652
      /* check if this task is accepting a rendezvous */
653
      if (atcb.call == NULL)
654
        caller = NULL;
655
      else
656
        {
657
          READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb.call), call);
658
          caller = EXTRACT_ADDRESS (call.self);
659
        }
660
 
661
      if (caller != NULL)
662
        printf_filtered (" Accepting RV with %-4d",
663
                         get_entry_number (caller));
664
      else
665
        {
666
          state = atcb.state;
667
#if defined (__WIN32__) || defined (SGI) || defined (hpux)
668
          if (state == Runnable && (thread_id && pt->lwp == thread_id))
669
#else
670
          if (state == Runnable && (thread_id && pt->thread == thread_id))
671
#endif
672
            /* Replace "Runnable" by "Running" if this is the current task */
673
            printf_filtered (" %-22s", "Running");
674
          else
675
            printf_filtered (" %-22s", ada_task_states[state]);
676
        }
677
 
678
      /* finally, print the name of the task */
679
      if (atcb.image.P_ARRAY != NULL)
680
        {
681
          READ_MEMORY ((CORE_ADDR) EXTRACT_ADDRESS (atcb.image.P_BOUNDS),
682
                       bounds);
683
          bounds[1] = EXTRACT_INT (bounds[1]);
684
          read_memory ((CORE_ADDR) EXTRACT_ADDRESS (atcb.image.P_ARRAY),
685
                       (char *) &image, bounds[1]);
686
          printf_filtered (" %.*s\n", bounds[1], image);
687
        }
688
      else
689
        printf_filtered (" <no name>\n");
690
 
691
      pt = pt->next_task;
692
    }
693
}
694
 
695
/* Task list initialization for GDB-Tk.  We basically use info_tasks()
696
   to initialize our variables, but abort that function before we
697
   actually print anything. */
698
 
699
int
700
gdbtk_tcl_tasks_initialize (void)
701
{
702
  gdbtk_task_initialization = 1;
703
  info_tasks ("", gdb_stdout);
704
 
705
  return (task_list != NULL);
706
}
707
 
708
static void
709
info_tasks_command (char *arg, int from_tty)
710
{
711
  if (arg == NULL || *arg == '\000')
712
    info_tasks (arg, from_tty);
713
  else
714
    info_task (arg, from_tty);
715
}
716
 
717
/* Switch from one thread to another. */
718
 
719
static void
720
switch_to_thread (ptid_t ptid)
721
{
722
  if (ptid_equal (ptid, inferior_ptid))
723
    return;
724
 
725
  inferior_ptid = ptid;
726
  flush_cached_frames ();
727
  registers_changed ();
728
  stop_pc = read_pc ();
729
  select_frame (get_current_frame ());
730
}
731
 
732
/* Switch to a specified task. */
733
 
734
static int
735
task_switch (void *tid, void *lwpid)
736
{
737
  int res = 0, pid;
738
 
739
  if (thread_support)
740
    {
741
      flush_cached_frames ();
742
 
743
      if (current_task != current_task_id)
744
        {
745
          res = THREAD_FETCH_REGISTERS ();
746
        }
747
      else
748
        {
749
#if (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET))
750
          supply_gregset (&gregset_saved);
751
          supply_fpregset (&fpregset_saved);
752
#endif
753
        }
754
 
755
      if (res == 0)
756
        stop_pc = read_pc ();
757
      select_frame (get_current_frame ());
758
      return res;
759
    }
760
 
761
  return -1;
762
}
763
 
764
static void
765
task_command (char *tidstr, int from_tty)
766
{
767
  int num;
768
  struct task_entry *e;
769
 
770
  if (!tidstr)
771
    error ("Please specify a task ID.  Use the \"info tasks\" command to\n"
772
           "see the IDs of currently known tasks.");
773
 
774
  num = atoi (tidstr);
775
  e = get_entry_vptr (num);
776
 
777
  if (e == NULL)
778
    error ("Task ID %d not known.  Use the \"info tasks\" command to\n"
779
           "see the IDs of currently known tasks.", num);
780
 
781
  if (current_task_id == -1)
782
    {
783
#if (defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET))
784
      fill_gregset (&gregset_saved, -1);
785
      fill_fpregset (&fpregset_saved, -1);
786
#endif
787
      current_task_id = get_current_task ();
788
    }
789
 
790
  current_task = num;
791
  current_task_index = e->known_tasks_index;
792
  current_thread = e->thread;
793
  current_lwp = e->lwp;
794
  if (task_switch (e->thread, e->lwp) == 0)
795
    {
796
      /* FIXME: find_printable_frame should be defined in frame.h, and
797
         implemented in ada-lang.c */
798
      /*      find_printable_frame (selected_frame, frame_relative_level (selected_frame)); */
799
      printf_filtered ("[Switching to task %d]\n", num);
800
      print_stack_frame (selected_frame,
801
                         frame_relative_level (selected_frame), 1);
802
    }
803
  else
804
    printf_filtered ("Unable to switch to task %d\n", num);
805
}
806
 
807
void
808
_initialize_tasks (void)
809
{
810
  static struct cmd_list_element *task_cmd_list = NULL;
811
  extern struct cmd_list_element *cmdlist;
812
 
813
  add_info ("tasks", info_tasks_command,
814
            "Without argument: list all known Ada tasks, with status information.\n"
815
            "info tasks n: print detailed information of task n.\n");
816
 
817
  add_prefix_cmd ("task", class_run, task_command,
818
                  "Use this command to switch between tasks.\n\
819
 The new task ID must be currently known.", &task_cmd_list, "task ", 1, &cmdlist);
820
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.