b89e8b52981fc986eec8e42cbc01f6797eafb260
[external/binutils.git] / gdb / linux-fork.c
1 /* GNU/Linux native-dependent code for debugging multiple forks.
2
3    Copyright (C) 2005, 2006, 2007, 2008, 2009 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 "arch-utils.h"
22 #include "inferior.h"
23 #include "regcache.h"
24 #include "gdbcmd.h"
25 #include "infcall.h"
26 #include "objfiles.h"
27 #include "gdb_assert.h"
28 #include "gdb_string.h"
29 #include "linux-fork.h"
30 #include "linux-nat.h"
31
32 #include <sys/ptrace.h>
33 #include "gdb_wait.h"
34 #include <sys/param.h>
35 #include "gdb_dirent.h"
36 #include <ctype.h>
37
38 struct fork_info *fork_list;
39 static int highest_fork_num;
40
41 /* Prevent warning from -Wmissing-prototypes.  */
42 extern void _initialize_linux_fork (void);
43
44 int detach_fork = 1;            /* Default behavior is to detach
45                                    newly forked processes (legacy).  */
46
47 /* Fork list data structure:  */
48 struct fork_info
49 {
50   struct fork_info *next;
51   ptid_t ptid;
52   int num;                      /* Convenient handle (GDB fork id) */
53   struct regcache *savedregs;   /* Convenient for info fork, saves 
54                                    having to actually switch contexts.  */
55   int clobber_regs;             /* True if we should restore saved regs.  */
56   ULONGEST pc;                  /* PC for info fork.  */
57   off_t *filepos;               /* Set of open file descriptors' offsets.  */
58   int maxfd;
59 };
60
61 /* Fork list methods:  */
62
63 extern int
64 forks_exist_p (void)
65 {
66   return (fork_list != NULL);
67 }
68
69 /* Add a fork to internal fork list.
70    Called from linux child_follow_fork.  */
71
72 extern struct fork_info *
73 add_fork (pid_t pid)
74 {
75   struct fork_info *fp;
76
77   if (fork_list == NULL && pid != PIDGET (inferior_ptid))
78     {
79       /* Special case -- if this is the first fork in the list
80          (the list is hitherto empty), and if this new fork is
81          NOT the current inferior_ptid, then add inferior_ptid
82          first, as a special zeroeth fork id.  */
83       highest_fork_num = -1;
84       add_fork (PIDGET (inferior_ptid));        /* safe recursion */
85     }
86
87   fp = XZALLOC (struct fork_info);
88   fp->ptid = ptid_build (pid, pid, 0);
89   fp->num = ++highest_fork_num;
90   fp->next = fork_list;
91   fork_list = fp;
92   return fp;
93 }
94
95 static void
96 free_fork (struct fork_info *fp)
97 {
98   /* Notes on step-resume breakpoints: since this is a concern for
99      threads, let's convince ourselves that it's not a concern for
100      forks.  There are two ways for a fork_info to be created.  First,
101      by the checkpoint command, in which case we're at a gdb prompt
102      and there can't be any step-resume breakpoint.  Second, by a fork
103      in the user program, in which case we *may* have stepped into the
104      fork call, but regardless of whether we follow the parent or the
105      child, we will return to the same place and the step-resume
106      breakpoint, if any, will take care of itself as usual.  And
107      unlike threads, we do not save a private copy of the step-resume
108      breakpoint -- so we're OK.  */
109
110   if (fp)
111     {
112       if (fp->savedregs)
113         regcache_xfree (fp->savedregs);
114       if (fp->filepos)
115         xfree (fp->filepos);
116       xfree (fp);
117     }
118 }
119
120 static void
121 delete_fork (ptid_t ptid)
122 {
123   struct fork_info *fp, *fpprev;
124
125   fpprev = NULL;
126
127   for (fp = fork_list; fp; fpprev = fp, fp = fp->next)
128     if (ptid_equal (fp->ptid, ptid))
129       break;
130
131   if (!fp)
132     return;
133
134   if (fpprev)
135     fpprev->next = fp->next;
136   else
137     fork_list = fp->next;
138
139   free_fork (fp);
140
141   /* Special case: if there is now only one process in the list, 
142      and if it is (hopefully!) the current inferior_ptid, then
143      remove it, leaving the list empty -- we're now down to the
144      default case of debugging a single process.  */
145   if (fork_list != NULL && fork_list->next == NULL &&
146       ptid_equal (fork_list->ptid, inferior_ptid))
147     {
148       /* Last fork -- delete from list and handle as solo process
149          (should be a safe recursion).  */
150       delete_fork (inferior_ptid);
151     }
152 }
153
154 /* Find a fork_info by matching PTID.  */
155 static struct fork_info *
156 find_fork_ptid (ptid_t ptid)
157 {
158   struct fork_info *fp;
159
160   for (fp = fork_list; fp; fp = fp->next)
161     if (ptid_equal (fp->ptid, ptid))
162       return fp;
163
164   return NULL;
165 }
166
167 /* Find a fork_info by matching ID.  */
168 static struct fork_info *
169 find_fork_id (int num)
170 {
171   struct fork_info *fp;
172
173   for (fp = fork_list; fp; fp = fp->next)
174     if (fp->num == num)
175       return fp;
176
177   return NULL;
178 }
179
180 /* Find a fork_info by matching pid.  */
181 extern struct fork_info *
182 find_fork_pid (pid_t pid)
183 {
184   struct fork_info *fp;
185
186   for (fp = fork_list; fp; fp = fp->next)
187     if (pid == ptid_get_pid (fp->ptid))
188       return fp;
189
190   return NULL;
191 }
192
193 static ptid_t
194 fork_id_to_ptid (int num)
195 {
196   struct fork_info *fork = find_fork_id (num);
197   if (fork)
198     return fork->ptid;
199   else
200     return pid_to_ptid (-1);
201 }
202
203 static void
204 init_fork_list (void)
205 {
206   struct fork_info *fp, *fpnext;
207
208   if (!fork_list)
209     return;
210
211   for (fp = fork_list; fp; fp = fpnext)
212     {
213       fpnext = fp->next;
214       delete_inferior (ptid_get_pid (fp->ptid));
215       free_fork (fp);
216     }
217
218   fork_list = NULL;
219 }
220
221 /* Fork list <-> gdb interface.  */
222
223 /* Utility function for fork_load/fork_save.  
224    Calls lseek in the (current) inferior process.  */
225
226 static off_t
227 call_lseek (int fd, off_t offset, int whence)
228 {
229   char exp[80];
230
231   snprintf (&exp[0], sizeof (exp), "lseek (%d, %ld, %d)",
232             fd, (long) offset, whence);
233   return (off_t) parse_and_eval_long (&exp[0]);
234 }
235
236 /* Load infrun state for the fork PTID.  */
237
238 static void
239 fork_load_infrun_state (struct fork_info *fp)
240 {
241   extern void nullify_last_target_wait_ptid ();
242   int i;
243
244   inferior_ptid = fp->ptid;
245
246   linux_nat_switch_fork (inferior_ptid);
247
248   if (fp->savedregs && fp->clobber_regs)
249     regcache_cpy (get_current_regcache (), fp->savedregs);
250
251   registers_changed ();
252   reinit_frame_cache ();
253
254   stop_pc = regcache_read_pc (get_current_regcache ());
255   nullify_last_target_wait_ptid ();
256
257   /* Now restore the file positions of open file descriptors.  */
258   if (fp->filepos)
259     {
260       for (i = 0; i <= fp->maxfd; i++)
261         if (fp->filepos[i] != (off_t) -1)
262           call_lseek (i, fp->filepos[i], SEEK_SET);
263       /* NOTE: I can get away with using SEEK_SET and SEEK_CUR because
264          this is native-only.  If it ever has to be cross, we'll have
265          to rethink this.  */
266     }
267 }
268
269 /* Save infrun state for the fork PTID.
270    Exported for use by linux child_follow_fork.  */
271
272 extern void
273 fork_save_infrun_state (struct fork_info *fp, int clobber_regs)
274 {
275   char path[MAXPATHLEN];
276   struct dirent *de;
277   DIR *d;
278
279   if (fp->savedregs)
280     regcache_xfree (fp->savedregs);
281
282   fp->savedregs = regcache_dup (get_current_regcache ());
283   fp->clobber_regs = clobber_regs;
284   fp->pc = regcache_read_pc (get_current_regcache ());
285
286   if (clobber_regs)
287     {
288       /* Now save the 'state' (file position) of all open file descriptors.
289          Unfortunately fork does not take care of that for us...  */
290       snprintf (path, MAXPATHLEN, "/proc/%ld/fd", (long) PIDGET (fp->ptid));
291       if ((d = opendir (path)) != NULL)
292         {
293           long tmp;
294
295           fp->maxfd = 0;
296           while ((de = readdir (d)) != NULL)
297             {
298               /* Count open file descriptors (actually find highest
299                  numbered).  */
300               tmp = strtol (&de->d_name[0], NULL, 10);
301               if (fp->maxfd < tmp)
302                 fp->maxfd = tmp;
303             }
304           /* Allocate array of file positions.  */
305           fp->filepos = xrealloc (fp->filepos, 
306                                   (fp->maxfd + 1) * sizeof (*fp->filepos));
307
308           /* Initialize to -1 (invalid).  */
309           for (tmp = 0; tmp <= fp->maxfd; tmp++)
310             fp->filepos[tmp] = -1;
311
312           /* Now find actual file positions.  */
313           rewinddir (d);
314           while ((de = readdir (d)) != NULL)
315             if (isdigit (de->d_name[0]))
316               {
317                 tmp = strtol (&de->d_name[0], NULL, 10);
318                 fp->filepos[tmp] = call_lseek (tmp, 0, SEEK_CUR);
319               }
320           closedir (d);
321         }
322     }
323 }
324
325 /* Kill 'em all, let God sort 'em out...  */
326
327 extern void
328 linux_fork_killall (void)
329 {
330   /* Walk list and kill every pid.  No need to treat the
331      current inferior_ptid as special (we do not return a
332      status for it) -- however any process may be a child
333      or a parent, so may get a SIGCHLD from a previously
334      killed child.  Wait them all out.  */
335   struct fork_info *fp;
336   pid_t pid, ret;
337   int status;
338
339   for (fp = fork_list; fp; fp = fp->next)
340     {
341       pid = PIDGET (fp->ptid);
342       do {
343         /* Use SIGKILL instead of PTRACE_KILL because the former works even
344            if the thread is running, while the later doesn't.  */
345         kill (pid, SIGKILL);
346         ret = waitpid (pid, &status, 0);
347         /* We might get a SIGCHLD instead of an exit status.  This is
348          aggravated by the first kill above - a child has just
349          died.  MVS comment cut-and-pasted from linux-nat.  */
350       } while (ret == pid && WIFSTOPPED (status));
351     }
352   init_fork_list ();    /* Clear list, prepare to start fresh.  */
353 }
354
355 /* The current inferior_ptid has exited, but there are other viable
356    forks to debug.  Delete the exiting one and context-switch to the
357    first available.  */
358
359 extern void
360 linux_fork_mourn_inferior (void)
361 {
362   /* Wait just one more time to collect the inferior's exit status.
363      Do not check whether this succeeds though, since we may be
364      dealing with a process that we attached to.  Such a process will
365      only report its exit status to its original parent.  */
366   int status;
367
368   waitpid (ptid_get_pid (inferior_ptid), &status, 0);
369
370   /* OK, presumably inferior_ptid is the one who has exited.
371      We need to delete that one from the fork_list, and switch
372      to the next available fork.  */
373   delete_fork (inferior_ptid);
374   /* Delete process from GDB's inferior list.  */
375   delete_inferior (ptid_get_pid (inferior_ptid));
376
377   /* There should still be a fork - if there's only one left,
378      delete_fork won't remove it, because we haven't updated
379      inferior_ptid yet.  */
380   gdb_assert (fork_list);
381
382   fork_load_infrun_state (fork_list);
383   printf_filtered (_("[Switching to %s]\n"),
384                    target_pid_to_str (inferior_ptid));
385
386   /* If there's only one fork, switch back to non-fork mode.  */
387   if (fork_list->next == NULL)
388     delete_fork (inferior_ptid);
389 }
390
391 /* The current inferior_ptid is being detached, but there are other
392    viable forks to debug.  Detach and delete it and context-switch to
393    the first available.  */
394
395 extern void
396 linux_fork_detach (char *args, int from_tty)
397 {
398   /* OK, inferior_ptid is the one we are detaching from.  We need to
399      delete it from the fork_list, and switch to the next available
400      fork.  */
401
402   if (ptrace (PTRACE_DETACH, PIDGET (inferior_ptid), 0, 0))
403     error (_("Unable to detach %s"), target_pid_to_str (inferior_ptid));
404
405   delete_fork (inferior_ptid);
406   /* Delete process from GDB's inferior list.  */
407   delete_inferior (ptid_get_pid (inferior_ptid));
408
409   /* There should still be a fork - if there's only one left,
410      delete_fork won't remove it, because we haven't updated
411      inferior_ptid yet.  */
412   gdb_assert (fork_list);
413
414   fork_load_infrun_state (fork_list);
415
416   if (from_tty)
417     printf_filtered (_("[Switching to %s]\n"),
418                      target_pid_to_str (inferior_ptid));
419
420   /* If there's only one fork, switch back to non-fork mode.  */
421   if (fork_list->next == NULL)
422     delete_fork (inferior_ptid);
423 }
424
425 /* Fork list <-> user interface.  */
426
427 static void
428 delete_fork_command (char *args, int from_tty)
429 {
430   ptid_t ptid;
431
432   if (!args || !*args)
433     error (_("Requires argument (fork/checkpoint id to delete)"));
434
435   ptid = fork_id_to_ptid (parse_and_eval_long (args));
436   if (ptid_equal (ptid, minus_one_ptid))
437     error (_("No such fork/checkpoint id, %s"), args);
438
439   if (ptid_equal (ptid, inferior_ptid))
440     error (_("Please switch to another fork/checkpoint before deleting the current one"));
441
442   if (ptrace (PTRACE_KILL, PIDGET (ptid), 0, 0))
443     error (_("Unable to kill pid %s"), target_pid_to_str (ptid));
444
445   if (from_tty)
446     printf_filtered (_("Killed %s\n"), target_pid_to_str (ptid));
447
448   delete_fork (ptid);
449   /* Delete process from GDB's inferior list.  */
450   delete_inferior (ptid_get_pid (ptid));
451 }
452
453 static void
454 detach_fork_command (char *args, int from_tty)
455 {
456   ptid_t ptid;
457
458   if (!args || !*args)
459     error (_("Requires argument (fork id to detach)"));
460
461   ptid = fork_id_to_ptid (parse_and_eval_long (args));
462   if (ptid_equal (ptid, minus_one_ptid))
463     error (_("No such fork id, %s"), args);
464
465   if (ptid_equal (ptid, inferior_ptid))
466     error (_("Please switch to another fork before detaching the current one"));
467
468   if (ptrace (PTRACE_DETACH, PIDGET (ptid), 0, 0))
469     error (_("Unable to detach %s"), target_pid_to_str (ptid));
470
471   if (from_tty)
472     printf_filtered (_("Detached %s\n"), target_pid_to_str (ptid));
473
474   delete_fork (ptid);
475   /* Delete process from GDB's process table.  */
476   detach_inferior (ptid_get_pid (ptid));
477 }
478
479 /* Print information about currently known forks.  */
480
481 static void
482 info_forks_command (char *arg, int from_tty)
483 {
484   struct gdbarch *gdbarch = get_current_arch ();
485   struct frame_info *cur_frame;
486   struct symtab_and_line sal;
487   struct symtab *cur_symtab;
488   struct fork_info *fp;
489   int cur_line;
490   ULONGEST pc;
491   int requested = -1;
492   struct fork_info *printed = NULL;
493
494   if (arg && *arg)
495     requested = (int) parse_and_eval_long (arg);
496
497   for (fp = fork_list; fp; fp = fp->next)
498     {
499       if (requested > 0 && fp->num != requested)
500         continue;
501
502       printed = fp;
503       if (ptid_equal (fp->ptid, inferior_ptid))
504         {
505           printf_filtered ("* ");
506           pc = regcache_read_pc (get_current_regcache ());
507         }
508       else
509         {
510           printf_filtered ("  ");
511           pc = fp->pc;
512         }
513       printf_filtered ("%d %s", fp->num, target_pid_to_str (fp->ptid));
514       if (fp->num == 0)
515         printf_filtered (_(" (main process)"));
516       printf_filtered (_(" at "));
517       fputs_filtered (paddress (gdbarch, pc), gdb_stdout);
518
519       sal = find_pc_line (pc, 0);
520       if (sal.symtab)
521         {
522           char *tmp = strrchr (sal.symtab->filename, '/');
523
524           if (tmp)
525             printf_filtered (_(", file %s"), tmp + 1);
526           else
527             printf_filtered (_(", file %s"), sal.symtab->filename);
528         }
529       if (sal.line)
530         printf_filtered (_(", line %d"), sal.line);
531       if (!sal.symtab && !sal.line)
532         {
533           struct minimal_symbol *msym;
534
535           msym = lookup_minimal_symbol_by_pc (pc);
536           if (msym)
537             printf_filtered (", <%s>", SYMBOL_LINKAGE_NAME (msym));
538         }
539
540       putchar_filtered ('\n');
541     }
542   if (printed == NULL)
543     {
544       if (requested > 0)
545         printf_filtered (_("No fork number %d.\n"), requested);
546       else
547         printf_filtered (_("No forks.\n"));
548     }
549 }
550
551 /* Save/restore mode variable 'detach_fork':
552    We need to temporarily take over this mode variable, while
553    preserving the user-specified state, and make sure that it 
554    gets restored in case of error.
555
556    The int pointer that we use comes from the caller, so we can
557    be called more than once (even though currently we don't need to).  */
558
559 static void 
560 restore_detach_fork (void *arg)
561 {
562   detach_fork = *(int *) arg;
563 }
564
565 static struct cleanup *
566 save_detach_fork (int *saved_val)
567 {
568   *saved_val = detach_fork;
569   return make_cleanup (restore_detach_fork, (void *) saved_val);
570 }
571
572 static void
573 checkpoint_command (char *args, int from_tty)
574 {
575   struct objfile *fork_objf;
576   struct gdbarch *gdbarch;
577   struct target_waitstatus last_target_waitstatus;
578   ptid_t last_target_ptid;
579   struct value *fork_fn = NULL, *ret;
580   struct fork_info *fp;
581   pid_t retpid;
582   struct cleanup *old_chain;
583   long i;
584   /* Make this temp var static, 'cause it's used in the error context.  */
585   static int temp_detach_fork;
586
587   /* Remove breakpoints, so that they are not inserted
588      in the forked process.  */
589   remove_breakpoints ();
590
591   /* Make the inferior fork, record its (and gdb's) state.  */
592
593   if (lookup_minimal_symbol ("fork", NULL, NULL) != NULL)
594     fork_fn = find_function_in_inferior ("fork", &fork_objf);
595   if (!fork_fn)
596     if (lookup_minimal_symbol ("_fork", NULL, NULL) != NULL)
597       fork_fn = find_function_in_inferior ("fork", &fork_objf);
598   if (!fork_fn)
599     error (_("checkpoint: can't find fork function in inferior."));
600
601   gdbarch = get_objfile_arch (fork_objf);
602   ret = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
603   old_chain = save_detach_fork (&temp_detach_fork);
604   detach_fork = 0;
605   ret = call_function_by_hand (fork_fn, 0, &ret);
606   do_cleanups (old_chain);
607   if (!ret)     /* Probably can't happen.  */
608     error (_("checkpoint: call_function_by_hand returned null."));
609
610   retpid = value_as_long (ret);
611   get_last_target_status (&last_target_ptid, &last_target_waitstatus);
612   if (from_tty)
613     {
614       int parent_pid;
615
616       printf_filtered (_("checkpoint: fork returned pid %ld.\n"), 
617                        (long) retpid);
618       if (info_verbose)
619         {
620           parent_pid = ptid_get_lwp (last_target_ptid);
621           if (parent_pid == 0)
622             parent_pid = ptid_get_pid (last_target_ptid);
623           printf_filtered (_("   gdb says parent = %ld.\n"), 
624                            (long) parent_pid);
625         }
626     }
627
628   fp = find_fork_pid (retpid);
629   if (!fp)
630     error (_("Failed to find new fork"));
631   fork_save_infrun_state (fp, 1);
632   insert_breakpoints ();
633 }
634
635 static void
636 linux_fork_context (struct fork_info *newfp, int from_tty)
637 {
638   /* Now we attempt to switch processes.  */
639   struct fork_info *oldfp;
640   ptid_t ptid;
641   int id, i;
642
643   gdb_assert (newfp != NULL);
644
645   oldfp = find_fork_ptid (inferior_ptid);
646   gdb_assert (oldfp != NULL);
647
648   fork_save_infrun_state (oldfp, 1);
649   remove_breakpoints ();
650   fork_load_infrun_state (newfp);
651   insert_breakpoints ();
652
653   printf_filtered (_("Switching to %s\n"), 
654                    target_pid_to_str (inferior_ptid));
655
656   print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
657 }
658
659 /* Switch inferior process (fork) context, by process id.  */
660 static void
661 process_command (char *args, int from_tty)
662 {
663   struct fork_info *fp;
664
665   if (!args || !*args)
666     error (_("Requires argument (process id to switch to)"));
667
668   if ((fp = find_fork_pid (parse_and_eval_long (args))) == NULL)
669     error (_("Not found: process id %s"), args);
670
671   linux_fork_context (fp, from_tty);
672 }
673
674 /* Switch inferior process (fork) context, by fork id.  */
675 static void
676 fork_command (char *args, int from_tty)
677 {
678   struct fork_info *fp;
679
680   if (!args || !*args)
681     error (_("Requires argument (fork id to switch to)"));
682
683   if ((fp = find_fork_id (parse_and_eval_long (args))) == NULL)
684     error (_("Not found: fork id %s"), args);
685
686   linux_fork_context (fp, from_tty);
687 }
688
689 /* Switch inferior process (fork) context, by checkpoint id.  */
690 static void
691 restart_command (char *args, int from_tty)
692 {
693   struct fork_info *fp;
694
695   if (!args || !*args)
696     error (_("Requires argument (checkpoint id to restart)"));
697
698   if ((fp = find_fork_id (parse_and_eval_long (args))) == NULL)
699     error (_("Not found: checkpoint id %s"), args);
700
701   linux_fork_context (fp, from_tty);
702 }
703
704 void
705 _initialize_linux_fork (void)
706 {
707   init_fork_list ();
708
709   /* Set/show detach-on-fork: user-settable mode.  */
710
711   add_setshow_boolean_cmd ("detach-on-fork", class_obscure, &detach_fork, _("\
712 Set whether gdb will detach the child of a fork."), _("\
713 Show whether gdb will detach the child of a fork."), _("\
714 Tells gdb whether to detach the child of a fork."), 
715                            NULL, NULL, &setlist, &showlist);
716
717   /* Set/show restart-auto-finish: user-settable count.  Causes the
718      first "restart" of a fork to do some number of "finish" commands
719      before returning to user.
720
721      Useful because otherwise the virgin fork process will be stopped
722      somewhere in the un-interesting fork system call.  */
723
724   /* Checkpoint command: create a fork of the inferior process
725      and set it aside for later debugging.  */
726
727   add_com ("checkpoint", class_obscure, checkpoint_command, _("\
728 Fork a duplicate process (experimental)."));
729
730   /* Restart command: restore the context of a specified fork
731      process.  May be used for "program forks" as well as for
732      "debugger forks" (checkpoints).  */
733
734   add_com ("restart", class_obscure, restart_command, _("\
735 restart <n>: restore program context from a checkpoint.\n\
736 Argument 'n' is checkpoint ID, as displayed by 'info checkpoints'."));
737
738   /* Delete checkpoint command: kill the process and remove it from
739      fork list.  */
740
741   add_cmd ("checkpoint", class_obscure, delete_fork_command, _("\
742 Delete a fork/checkpoint (experimental)."),
743            &deletelist);
744
745   /* Detach checkpoint command: release the process to run independently, 
746      and remove it from the fork list.  */
747
748   add_cmd ("checkpoint", class_obscure, detach_fork_command, _("\
749 Detach from a fork/checkpoint (experimental)."),
750            &detachlist);
751
752   /* Info checkpoints command: list all forks/checkpoints 
753      currently under gdb's control.  */
754
755   add_info ("checkpoints", info_forks_command,
756             _("IDs of currently known forks/checkpoints."));
757
758   /* Command aliases (let "fork" and "checkpoint" be used 
759      interchangeably).  */
760
761   add_alias_cmd ("fork", "checkpoint", class_obscure, 1, &deletelist);
762   add_alias_cmd ("fork", "checkpoint", class_obscure, 1, &detachlist);
763   add_info_alias ("forks", "checkpoints", 0);
764
765   /* "fork <n>" (by analogy to "thread <n>").  */
766   add_com ("fork", class_obscure, fork_command, _("\
767 fork <n>: Switch between forked processes.\n\
768 Argument 'n' is fork ID, as displayed by 'info forks'."));
769
770   /* "process <proc id>" as opposed to "fork <fork id>".  */
771   add_com ("process", class_obscure, process_command, _("\
772 process <pid>: Switch between forked processes.\n\
773 Argument 'pid' is process ID, as displayed by 'info forks' or 'shell ps'."));
774 }