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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [inferior.c] - Blame information for rev 853

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

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

powered by: WebSVN 2.1.0

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