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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [inferior.c] - Blame information for rev 862

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

Line No. Rev Author Line
1 227 jeremybenn
/* Multi-process control for GDB, the GNU debugger.
2
 
3
   Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "defs.h"
21
#include "exec.h"
22
#include "inferior.h"
23
#include "target.h"
24
#include "command.h"
25
#include "gdbcmd.h"
26
#include "gdbthread.h"
27
#include "ui-out.h"
28
#include "observer.h"
29
#include "gdbthread.h"
30
#include "gdbcore.h"
31
#include "symfile.h"
32
#include "environ.h"
33
 
34
void _initialize_inferiors (void);
35
 
36
static void inferior_alloc_data (struct inferior *inf);
37
static void inferior_free_data (struct inferior *inf);
38
 
39
struct inferior *inferior_list = NULL;
40
static int highest_inferior_num;
41
 
42
/* Print notices on inferior events (attach, detach, etc.), set with
43
   `set print inferior-events'.  */
44
static int print_inferior_events = 0;
45
 
46
/* The Current Inferior.  */
47
static struct inferior *current_inferior_ = NULL;
48
 
49
struct inferior*
50
current_inferior (void)
51
{
52
  return current_inferior_;
53
}
54
 
55
void
56
set_current_inferior (struct inferior *inf)
57
{
58
  /* There's always an inferior.  */
59
  gdb_assert (inf != NULL);
60
 
61
  current_inferior_ = inf;
62
}
63
 
64
/* A cleanups callback, helper for save_current_program_space
65
   below.  */
66
 
67
static void
68
restore_inferior (void *arg)
69
{
70
  struct inferior *saved_inferior = arg;
71
  set_current_inferior (saved_inferior);
72
}
73
 
74
/* Save the current program space so that it may be restored by a later
75
   call to do_cleanups.  Returns the struct cleanup pointer needed for
76
   later doing the cleanup.  */
77
 
78
struct cleanup *
79
save_current_inferior (void)
80
{
81
  struct cleanup *old_chain = make_cleanup (restore_inferior,
82
                                            current_inferior_);
83
  return old_chain;
84
}
85
 
86
static void
87
free_inferior (struct inferior *inf)
88
{
89
  discard_all_inferior_continuations (inf);
90
  inferior_free_data (inf);
91
  xfree (inf->args);
92
  xfree (inf->terminal);
93
  free_environ (inf->environment);
94
  xfree (inf->private);
95
  xfree (inf);
96
}
97
 
98
void
99
init_inferior_list (void)
100
{
101
  struct inferior *inf, *infnext;
102
 
103
  highest_inferior_num = 0;
104
  if (!inferior_list)
105
    return;
106
 
107
  for (inf = inferior_list; inf; inf = infnext)
108
    {
109
      infnext = inf->next;
110
      free_inferior (inf);
111
    }
112
 
113
  inferior_list = NULL;
114
}
115
 
116
struct inferior *
117
add_inferior_silent (int pid)
118
{
119
  struct inferior *inf;
120
 
121
  inf = xmalloc (sizeof (*inf));
122
  memset (inf, 0, sizeof (*inf));
123
  inf->pid = pid;
124
 
125
  inf->stop_soon = NO_STOP_QUIETLY;
126
 
127
  inf->num = ++highest_inferior_num;
128
  inf->next = inferior_list;
129
  inferior_list = inf;
130
 
131
  inf->environment = make_environ ();
132
  init_environ (inf->environment);
133
 
134
  inferior_alloc_data (inf);
135
 
136
  if (pid != 0)
137
    inferior_appeared (inf, pid);
138
 
139
  return inf;
140
}
141
 
142
struct inferior *
143
add_inferior (int pid)
144
{
145
  struct inferior *inf = add_inferior_silent (pid);
146
 
147
  if (print_inferior_events)
148
    printf_unfiltered (_("[New inferior %d]\n"), pid);
149
 
150
  return inf;
151
}
152
 
153
struct delete_thread_of_inferior_arg
154
{
155
  int pid;
156
  int silent;
157
};
158
 
159
static int
160
delete_thread_of_inferior (struct thread_info *tp, void *data)
161
{
162
  struct delete_thread_of_inferior_arg *arg = data;
163
 
164
  if (ptid_get_pid (tp->ptid) == arg->pid)
165
    {
166
      if (arg->silent)
167
        delete_thread_silent (tp->ptid);
168
      else
169
        delete_thread (tp->ptid);
170
    }
171
 
172
  return 0;
173
}
174
 
175
void
176
delete_threads_of_inferior (int pid)
177
{
178
  struct inferior *inf;
179
  struct delete_thread_of_inferior_arg arg;
180
 
181
  for (inf = inferior_list; inf; inf = inf->next)
182
    if (inf->pid == pid)
183
      break;
184
 
185
  if (!inf)
186
    return;
187
 
188
  arg.pid = pid;
189
  arg.silent = 1;
190
 
191
  iterate_over_threads (delete_thread_of_inferior, &arg);
192
}
193
 
194
/* If SILENT then be quiet -- don't announce a inferior death, or the
195
   exit of its threads.  */
196
 
197
static void
198
delete_inferior_1 (struct inferior *todel, int silent)
199
{
200
  struct inferior *inf, *infprev;
201
  struct delete_thread_of_inferior_arg arg;
202
 
203
  infprev = NULL;
204
 
205
  for (inf = inferior_list; inf; infprev = inf, inf = inf->next)
206
    if (inf == todel)
207
      break;
208
 
209
  if (!inf)
210
    return;
211
 
212
  arg.pid = inf->pid;
213
  arg.silent = silent;
214
 
215
  iterate_over_threads (delete_thread_of_inferior, &arg);
216
 
217
  if (infprev)
218
    infprev->next = inf->next;
219
  else
220
    inferior_list = inf->next;
221
 
222
  free_inferior (inf);
223
}
224
 
225
void
226
delete_inferior (int pid)
227
{
228
  struct inferior *inf = find_inferior_pid (pid);
229
 
230
  delete_inferior_1 (inf, 0);
231
 
232
  if (print_inferior_events)
233
    printf_unfiltered (_("[Inferior %d exited]\n"), pid);
234
}
235
 
236
void
237
delete_inferior_silent (int pid)
238
{
239
  struct inferior *inf = find_inferior_pid (pid);
240
 
241
  delete_inferior_1 (inf, 1);
242
}
243
 
244
 
245
/* If SILENT then be quiet -- don't announce a inferior exit, or the
246
   exit of its threads.  */
247
 
248
static void
249
exit_inferior_1 (struct inferior *inftoex, int silent)
250
{
251
  struct inferior *inf;
252
  struct delete_thread_of_inferior_arg arg;
253
 
254
  for (inf = inferior_list; inf; inf = inf->next)
255
    if (inf == inftoex)
256
      break;
257
 
258
  if (!inf)
259
    return;
260
 
261
  arg.pid = inf->pid;
262
  arg.silent = silent;
263
 
264
  iterate_over_threads (delete_thread_of_inferior, &arg);
265
 
266
  /* Notify the observers before removing the inferior from the list,
267
     so that the observers have a chance to look it up.  */
268
  observer_notify_inferior_exit (inf->pid);
269
 
270
  inf->pid = 0;
271
  if (inf->vfork_parent != NULL)
272
    {
273
      inf->vfork_parent->vfork_child = NULL;
274
      inf->vfork_parent = NULL;
275
    }
276
}
277
 
278
void
279
exit_inferior (int pid)
280
{
281
  struct inferior *inf = find_inferior_pid (pid);
282
  exit_inferior_1 (inf, 0);
283
 
284
  if (print_inferior_events)
285
    printf_unfiltered (_("[Inferior %d exited]\n"), pid);
286
}
287
 
288
void
289
exit_inferior_silent (int pid)
290
{
291
  struct inferior *inf = find_inferior_pid (pid);
292
  exit_inferior_1 (inf, 1);
293
}
294
 
295
void
296
exit_inferior_num_silent (int num)
297
{
298
  struct inferior *inf = find_inferior_id (num);
299
 
300
  exit_inferior_1 (inf, 1);
301
}
302
 
303
void
304
detach_inferior (int pid)
305
{
306
  struct inferior *inf = find_inferior_pid (pid);
307
  exit_inferior_1 (inf, 1);
308
 
309
  if (print_inferior_events)
310
    printf_unfiltered (_("[Inferior %d detached]\n"), pid);
311
}
312
 
313
void
314
inferior_appeared (struct inferior *inf, int pid)
315
{
316
  inf->pid = pid;
317
 
318
  observer_notify_inferior_appeared (pid);
319
}
320
 
321
void
322
discard_all_inferiors (void)
323
{
324
  struct inferior *inf;
325
 
326
  for (inf = inferior_list; inf; inf = inf->next)
327
    {
328
      if (inf->pid != 0)
329
        exit_inferior_silent (inf->pid);
330
    }
331
}
332
 
333
struct inferior *
334
find_inferior_id (int num)
335
{
336
  struct inferior *inf;
337
 
338
  for (inf = inferior_list; inf; inf = inf->next)
339
    if (inf->num == num)
340
      return inf;
341
 
342
  return NULL;
343
}
344
 
345
struct inferior *
346
find_inferior_pid (int pid)
347
{
348
  struct inferior *inf;
349
 
350
  /* Looking for inferior pid == 0 is always wrong, and indicative of
351
     a bug somewhere else.  There may be more than one with pid == 0,
352
     for instance.  */
353
  gdb_assert (pid != 0);
354
 
355
  for (inf = inferior_list; inf; inf = inf->next)
356
    if (inf->pid == pid)
357
      return inf;
358
 
359
  return NULL;
360
}
361
 
362
/* Find an inferior bound to PSPACE.  */
363
 
364
struct inferior *
365
find_inferior_for_program_space (struct program_space *pspace)
366
{
367
  struct inferior *inf;
368
 
369
  for (inf = inferior_list; inf != NULL; inf = inf->next)
370
    {
371
      if (inf->pspace == pspace)
372
        return inf;
373
    }
374
 
375
  return NULL;
376
}
377
 
378
struct inferior *
379
iterate_over_inferiors (int (*callback) (struct inferior *, void *),
380
                        void *data)
381
{
382
  struct inferior *inf, *infnext;
383
 
384
  for (inf = inferior_list; inf; inf = infnext)
385
    {
386
      infnext = inf->next;
387
      if ((*callback) (inf, data))
388
        return inf;
389
    }
390
 
391
  return NULL;
392
}
393
 
394
int
395
valid_gdb_inferior_id (int num)
396
{
397
  struct inferior *inf;
398
 
399
  for (inf = inferior_list; inf; inf = inf->next)
400
    if (inf->num == num)
401
      return 1;
402
 
403
  return 0;
404
}
405
 
406
int
407
pid_to_gdb_inferior_id (int pid)
408
{
409
  struct inferior *inf;
410
 
411
  for (inf = inferior_list; inf; inf = inf->next)
412
    if (inf->pid == pid)
413
      return inf->num;
414
 
415
  return 0;
416
}
417
 
418
int
419
gdb_inferior_id_to_pid (int num)
420
{
421
  struct inferior *inferior = find_inferior_id (num);
422
  if (inferior)
423
    return inferior->pid;
424
  else
425
    return -1;
426
}
427
 
428
int
429
in_inferior_list (int pid)
430
{
431
  struct inferior *inf;
432
 
433
  for (inf = inferior_list; inf; inf = inf->next)
434
    if (inf->pid == pid)
435
      return 1;
436
 
437
  return 0;
438
}
439
 
440
int
441
have_inferiors (void)
442
{
443
  struct inferior *inf;
444
 
445
  for (inf = inferior_list; inf; inf = inf->next)
446
    if (inf->pid != 0)
447
      return 1;
448
 
449
  return 0;
450
}
451
 
452
int
453
have_live_inferiors (void)
454
{
455
  struct target_ops *t;
456
 
457
  /* The check on stratum suffices, as GDB doesn't currently support
458
     multiple target interfaces.  */
459
  if (have_inferiors ())
460
    for (t = current_target.beneath; t != NULL; t = t->beneath)
461
      if (t->to_stratum == process_stratum)
462
        return 1;
463
 
464
  return 0;
465
}
466
 
467
/* Prune away automatically added program spaces that aren't required
468
   anymore.  */
469
 
470
void
471
prune_inferiors (void)
472
{
473
  struct inferior *ss, **ss_link;
474
  struct inferior *current = current_inferior ();
475
 
476
  ss = inferior_list;
477
  ss_link = &inferior_list;
478
  while (ss)
479
    {
480
      if (ss == current
481
          || !ss->removable
482
          || ss->pid != 0)
483
        {
484
          ss_link = &ss->next;
485
          ss = *ss_link;
486
          continue;
487
        }
488
 
489
      *ss_link = ss->next;
490
      delete_inferior_1 (ss, 1);
491
      ss = *ss_link;
492
    }
493
 
494
  prune_program_spaces ();
495
}
496
 
497
/* Simply returns the count of inferiors.  */
498
 
499
int
500
number_of_inferiors (void)
501
{
502
  struct inferior *inf;
503
  int count = 0;
504
 
505
  for (inf = inferior_list; inf != NULL; inf = inf->next)
506
    count++;
507
 
508
  return count;
509
}
510
 
511
/* Prints the list of inferiors and their details on UIOUT.  This is a
512
   version of 'info_inferior_command' suitable for use from MI.
513
 
514
   If REQUESTED_INFERIOR is not -1, it's the GDB id of the inferior that
515
   should be printed.  Otherwise, all inferiors are printed.  */
516
void
517
print_inferior (struct ui_out *uiout, int requested_inferior)
518
{
519
  struct inferior *inf;
520
  struct cleanup *old_chain;
521
  int inf_count = 0;
522
 
523
  /* Compute number of inferiors we will print.  */
524
  for (inf = inferior_list; inf; inf = inf->next)
525
    {
526
      struct cleanup *chain2;
527
 
528
      if (requested_inferior != -1 && inf->num != requested_inferior)
529
        continue;
530
 
531
      ++inf_count;
532
    }
533
 
534
  if (inf_count == 0)
535
    {
536
      ui_out_message (uiout, 0, "No inferiors.\n");
537
      return;
538
    }
539
 
540
  old_chain = make_cleanup_ui_out_table_begin_end (uiout, 4, inf_count,
541
                                                   "inferiors");
542
  ui_out_table_header (uiout, 1, ui_left, "current", "");
543
  ui_out_table_header (uiout, 4, ui_left, "number", "Num");
544
  ui_out_table_header (uiout, 17, ui_left, "target-id", "Description");
545
  ui_out_table_header (uiout, 17, ui_left, "exec", "Executable");
546
 
547
  ui_out_table_body (uiout);
548
  for (inf = inferior_list; inf; inf = inf->next)
549
    {
550
      struct cleanup *chain2;
551
 
552
      if (requested_inferior != -1 && inf->num != requested_inferior)
553
        continue;
554
 
555
      chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
556
 
557
      if (inf == current_inferior ())
558
        ui_out_field_string (uiout, "current", "*");
559
      else
560
        ui_out_field_skip (uiout, "current");
561
 
562
      ui_out_field_int (uiout, "number", inf->num);
563
 
564
      if (inf->pid)
565
        ui_out_field_string (uiout, "target-id",
566
                             target_pid_to_str (pid_to_ptid (inf->pid)));
567
      else
568
        ui_out_field_string (uiout, "target-id", "<null>");
569
 
570
      if (inf->pspace->ebfd)
571
        ui_out_field_string (uiout, "exec",
572
                             bfd_get_filename (inf->pspace->ebfd));
573
      else
574
        ui_out_field_skip (uiout, "exec");
575
 
576
      /* Print extra info that isn't really fit to always present in
577
         tabular form.  Currently we print the vfork parent/child
578
         relationships, if any.  */
579
      if (inf->vfork_parent)
580
        {
581
          ui_out_text (uiout, _("\n\tis vfork child of inferior "));
582
          ui_out_field_int (uiout, "vfork-parent", inf->vfork_parent->num);
583
        }
584
      if (inf->vfork_child)
585
        {
586
          ui_out_text (uiout, _("\n\tis vfork parent of inferior "));
587
          ui_out_field_int (uiout, "vfork-child", inf->vfork_child->num);
588
        }
589
 
590
      ui_out_text (uiout, "\n");
591
      do_cleanups (chain2);
592
    }
593
 
594
  do_cleanups (old_chain);
595
}
596
 
597
static void
598
detach_inferior_command (char *args, int from_tty)
599
{
600
  int num, pid;
601
  struct thread_info *tp;
602
 
603
  if (!args || !*args)
604
    error (_("Requires argument (inferior id to detach)"));
605
 
606
  num = parse_and_eval_long (args);
607
 
608
  if (!valid_gdb_inferior_id (num))
609
    error (_("Inferior ID %d not known."), num);
610
 
611
  pid = gdb_inferior_id_to_pid (num);
612
 
613
  tp = any_thread_of_process (pid);
614
  if (!tp)
615
    error (_("Inferior has no threads."));
616
 
617
  switch_to_thread (tp->ptid);
618
 
619
  detach_command (NULL, from_tty);
620
}
621
 
622
static void
623
kill_inferior_command (char *args, int from_tty)
624
{
625
  int num, pid;
626
  struct thread_info *tp;
627
 
628
  if (!args || !*args)
629
    error (_("Requires argument (inferior id to kill)"));
630
 
631
  num = parse_and_eval_long (args);
632
 
633
  if (!valid_gdb_inferior_id (num))
634
    error (_("Inferior ID %d not known."), num);
635
 
636
  pid = gdb_inferior_id_to_pid (num);
637
 
638
  tp = any_thread_of_process (pid);
639
  if (!tp)
640
    error (_("Inferior has no threads."));
641
 
642
  switch_to_thread (tp->ptid);
643
 
644
  target_kill ();
645
 
646
  bfd_cache_close_all ();
647
}
648
 
649
static void
650
inferior_command (char *args, int from_tty)
651
{
652
  struct inferior *inf;
653
  int num;
654
 
655
  num = parse_and_eval_long (args);
656
 
657
  inf = find_inferior_id (num);
658
  if (inf == NULL)
659
    error (_("Inferior ID %d not known."), num);
660
 
661
  printf_filtered (_("[Switching to inferior %d [%s] (%s)]\n"),
662
                   inf->num,
663
                   target_pid_to_str (pid_to_ptid (inf->pid)),
664
                   (inf->pspace->ebfd
665
                    ? bfd_get_filename (inf->pspace->ebfd)
666
                    : _("<noexec>")));
667
 
668
  if (inf->pid != 0)
669
    {
670
      if (inf->pid != ptid_get_pid (inferior_ptid))
671
        {
672
          struct thread_info *tp;
673
 
674
          tp = any_thread_of_process (inf->pid);
675
          if (!tp)
676
            error (_("Inferior has no threads."));
677
 
678
          switch_to_thread (tp->ptid);
679
        }
680
 
681
      printf_filtered (_("[Switching to thread %d (%s)] "),
682
                       pid_to_thread_id (inferior_ptid),
683
                       target_pid_to_str (inferior_ptid));
684
    }
685
  else
686
    {
687
      struct inferior *inf;
688
 
689
      inf = find_inferior_id (num);
690
      set_current_inferior (inf);
691
      switch_to_thread (null_ptid);
692
      set_current_program_space (inf->pspace);
693
    }
694
 
695
  if (inf->pid != 0 && is_running (inferior_ptid))
696
    ui_out_text (uiout, "(running)\n");
697
  else if (inf->pid != 0)
698
    {
699
      ui_out_text (uiout, "\n");
700
      print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
701
    }
702
}
703
 
704
/* Print information about currently known inferiors.  */
705
 
706
static void
707
info_inferiors_command (char *args, int from_tty)
708
{
709
  int requested = -1;
710
 
711
  if (args && *args)
712
    {
713
      requested = parse_and_eval_long (args);
714
      if (!valid_gdb_inferior_id (requested))
715
        error (_("Inferior ID %d not known."), requested);
716
    }
717
 
718
  print_inferior (uiout, requested);
719
}
720
 
721
/* remove-inferior ID */
722
 
723
void
724
remove_inferior_command (char *args, int from_tty)
725
{
726
  int num;
727
  struct inferior *inf;
728
 
729
  num = parse_and_eval_long (args);
730
  inf = find_inferior_id (num);
731
 
732
  if (inf == NULL)
733
    error (_("Inferior ID %d not known."), num);
734
 
735
  if (inf == current_inferior ())
736
    error (_("Can not remove current symbol inferior."));
737
 
738
  delete_inferior_1 (inf, 1);
739
}
740
 
741
 
742
/* add-inferior [-copies N] [-exec FILENAME]  */
743
 
744
void
745
add_inferior_command (char *args, int from_tty)
746
{
747
  int i, copies = 1;
748
  char *exec = NULL;
749
  char **argv;
750
  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
751
 
752
  if (args)
753
    {
754
      argv = gdb_buildargv (args);
755
      make_cleanup_freeargv (argv);
756
 
757
      for (; *argv != NULL; argv++)
758
        {
759
          if (**argv == '-')
760
            {
761
              if (strcmp (*argv, "-copies") == 0)
762
                {
763
                  ++argv;
764
                  if (!*argv)
765
                    error (_("No argument to -copies"));
766
                  copies = parse_and_eval_long (*argv);
767
                }
768
              else if (strcmp (*argv, "-exec") == 0)
769
                {
770
                  ++argv;
771
                  if (!*argv)
772
                    error (_("No argument to -exec"));
773
                  exec = *argv;
774
                }
775
            }
776
          else
777
            error (_("Invalid argument"));
778
        }
779
    }
780
 
781
  save_current_space_and_thread ();
782
 
783
  for (i = 0; i < copies; ++i)
784
    {
785
      struct address_space *aspace;
786
      struct program_space *pspace;
787
      struct inferior *inf;
788
 
789
      /* If all inferiors share an address space on this system, this
790
         doesn't really return a new address space; otherwise, it
791
         really does.  */
792
      aspace = maybe_new_address_space ();
793
      pspace = add_program_space (aspace);
794
      inf = add_inferior (0);
795
      inf->pspace = pspace;
796
      inf->aspace = pspace->aspace;
797
 
798
      printf_filtered (_("Added inferior %d\n"), inf->num);
799
 
800
      if (exec != NULL)
801
        {
802
          /* Switch over temporarily, while reading executable and
803
             symbols.q  */
804
          set_current_program_space (pspace);
805
          set_current_inferior (inf);
806
          switch_to_thread (null_ptid);
807
 
808
          exec_file_attach (exec, from_tty);
809
          symbol_file_add_main (exec, from_tty);
810
        }
811
    }
812
 
813
  do_cleanups (old_chain);
814
}
815
 
816
/* clone-inferior [-copies N] [ID] */
817
 
818
void
819
clone_inferior_command (char *args, int from_tty)
820
{
821
  int i, copies = 1;
822
  char **argv;
823
  struct inferior *orginf = NULL;
824
  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
825
 
826
  if (args)
827
    {
828
      argv = gdb_buildargv (args);
829
      make_cleanup_freeargv (argv);
830
 
831
      for (; *argv != NULL; argv++)
832
        {
833
          if (**argv == '-')
834
            {
835
              if (strcmp (*argv, "-copies") == 0)
836
                {
837
                  ++argv;
838
                  if (!*argv)
839
                    error (_("No argument to -copies"));
840
                  copies = parse_and_eval_long (*argv);
841
 
842
                  if (copies < 0)
843
                    error (_("Invalid copies number"));
844
                }
845
            }
846
          else
847
            {
848
              if (orginf == NULL)
849
                {
850
                  int num;
851
 
852
                  /* The first non-option (-) argument specified the
853
                     program space ID.  */
854
                  num = parse_and_eval_long (*argv);
855
                  orginf = find_inferior_id (num);
856
 
857
                  if (orginf == NULL)
858
                    error (_("Inferior ID %d not known."), num);
859
                  continue;
860
                }
861
              else
862
                error (_("Invalid argument"));
863
            }
864
        }
865
    }
866
 
867
  /* If no inferior id was specified, then the user wants to clone the
868
     current inferior.  */
869
  if (orginf == NULL)
870
    orginf = current_inferior ();
871
 
872
  save_current_space_and_thread ();
873
 
874
  for (i = 0; i < copies; ++i)
875
    {
876
      struct address_space *aspace;
877
      struct program_space *pspace;
878
      struct inferior *inf;
879
 
880
      /* If all inferiors share an address space on this system, this
881
         doesn't really return a new address space; otherwise, it
882
         really does.  */
883
      aspace = maybe_new_address_space ();
884
      pspace = add_program_space (aspace);
885
      inf = add_inferior (0);
886
      inf->pspace = pspace;
887
      inf->aspace = pspace->aspace;
888
 
889
      printf_filtered (_("Added inferior %d.\n"), inf->num);
890
 
891
      set_current_inferior (inf);
892
      switch_to_thread (null_ptid);
893
      clone_program_space (pspace, orginf->pspace);
894
    }
895
 
896
  do_cleanups (old_chain);
897
}
898
 
899
/* Print notices when new inferiors are created and die.  */
900
static void
901
show_print_inferior_events (struct ui_file *file, int from_tty,
902
                           struct cmd_list_element *c, const char *value)
903
{
904
  fprintf_filtered (file, _("Printing of inferior events is %s.\n"), value);
905
}
906
 
907
 
908
 
909
/* Keep a registry of per-inferior data-pointers required by other GDB
910
   modules.  */
911
 
912
struct inferior_data
913
{
914
  unsigned index;
915
  void (*cleanup) (struct inferior *, void *);
916
};
917
 
918
struct inferior_data_registration
919
{
920
  struct inferior_data *data;
921
  struct inferior_data_registration *next;
922
};
923
 
924
struct inferior_data_registry
925
{
926
  struct inferior_data_registration *registrations;
927
  unsigned num_registrations;
928
};
929
 
930
static struct inferior_data_registry inferior_data_registry
931
  = { NULL, 0 };
932
 
933
const struct inferior_data *
934
register_inferior_data_with_cleanup
935
  (void (*cleanup) (struct inferior *, void *))
936
{
937
  struct inferior_data_registration **curr;
938
 
939
  /* Append new registration.  */
940
  for (curr = &inferior_data_registry.registrations;
941
       *curr != NULL; curr = &(*curr)->next);
942
 
943
  *curr = XMALLOC (struct inferior_data_registration);
944
  (*curr)->next = NULL;
945
  (*curr)->data = XMALLOC (struct inferior_data);
946
  (*curr)->data->index = inferior_data_registry.num_registrations++;
947
  (*curr)->data->cleanup = cleanup;
948
 
949
  return (*curr)->data;
950
}
951
 
952
const struct inferior_data *
953
register_inferior_data (void)
954
{
955
  return register_inferior_data_with_cleanup (NULL);
956
}
957
 
958
static void
959
inferior_alloc_data (struct inferior *inf)
960
{
961
  gdb_assert (inf->data == NULL);
962
  inf->num_data = inferior_data_registry.num_registrations;
963
  inf->data = XCALLOC (inf->num_data, void *);
964
}
965
 
966
static void
967
inferior_free_data (struct inferior *inf)
968
{
969
  gdb_assert (inf->data != NULL);
970
  clear_inferior_data (inf);
971
  xfree (inf->data);
972
  inf->data = NULL;
973
}
974
 
975
void
976
clear_inferior_data (struct inferior *inf)
977
{
978
  struct inferior_data_registration *registration;
979
  int i;
980
 
981
  gdb_assert (inf->data != NULL);
982
 
983
  for (registration = inferior_data_registry.registrations, i = 0;
984
       i < inf->num_data;
985
       registration = registration->next, i++)
986
    if (inf->data[i] != NULL && registration->data->cleanup)
987
      registration->data->cleanup (inf, inf->data[i]);
988
 
989
  memset (inf->data, 0, inf->num_data * sizeof (void *));
990
}
991
 
992
void
993
set_inferior_data (struct inferior *inf,
994
                       const struct inferior_data *data,
995
                       void *value)
996
{
997
  gdb_assert (data->index < inf->num_data);
998
  inf->data[data->index] = value;
999
}
1000
 
1001
void *
1002
inferior_data (struct inferior *inf, const struct inferior_data *data)
1003
{
1004
  gdb_assert (data->index < inf->num_data);
1005
  return inf->data[data->index];
1006
}
1007
 
1008
void
1009
initialize_inferiors (void)
1010
{
1011
  /* There's always one inferior.  Note that this function isn't an
1012
     automatic _initialize_foo function, since other _initialize_foo
1013
     routines may need to install their per-inferior data keys.  We
1014
     can only allocate an inferior when all those modules have done
1015
     that.  Do this after initialize_progspace, due to the
1016
     current_program_space reference.  */
1017
  current_inferior_ = add_inferior (0);
1018
  current_inferior_->pspace = current_program_space;
1019
  current_inferior_->aspace = current_program_space->aspace;
1020
 
1021
  add_info ("inferiors", info_inferiors_command,
1022
            _("IDs of currently known inferiors."));
1023
 
1024
  add_com ("add-inferior", no_class, add_inferior_command, _("\
1025
Add a new inferior.\n\
1026
Usage: add-inferior [-copies <N>] [-exec <FILENAME>]\n\
1027
N is the optional number of inferior to add, default is 1.\n\
1028
FILENAME is the file name of the executable to use\n\
1029
as main program."));
1030
 
1031
  add_com ("remove-inferior", no_class, remove_inferior_command, _("\
1032
Remove inferior ID.\n\
1033
Usage: remove-inferior ID"));
1034
 
1035
  add_com ("clone-inferior", no_class, clone_inferior_command, _("\
1036
Clone inferior ID.\n\
1037
Usage: clone-inferior [-copies <N>] [ID]\n\
1038
Add N copies of inferior ID.  The new inferior has the same\n\
1039
executable loaded as the copied inferior.  If -copies is not specified,\n\
1040
adds 1 copy.  If ID is not specified, it is the current inferior\n\
1041
that is cloned."));
1042
 
1043
  add_cmd ("inferior", class_run, detach_inferior_command, _("\
1044
Detach from inferior ID."),
1045
           &detachlist);
1046
 
1047
  add_cmd ("inferior", class_run, kill_inferior_command, _("\
1048
Kill inferior ID."),
1049
           &killlist);
1050
 
1051
  add_cmd ("inferior", class_run, inferior_command, _("\
1052
Use this command to switch between inferiors.\n\
1053
The new inferior ID must be currently known."),
1054
           &cmdlist);
1055
 
1056
  add_setshow_boolean_cmd ("inferior-events", no_class,
1057
         &print_inferior_events, _("\
1058
Set printing of inferior events (e.g., inferior start and exit)."), _("\
1059
Show printing of inferior events (e.g., inferior start and exit)."), NULL,
1060
         NULL,
1061
         show_print_inferior_events,
1062
         &setprintlist, &showprintlist);
1063
 
1064
}

powered by: WebSVN 2.1.0

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