GDB (API)
/home/stan/gdb/src/gdb/linux-fork.c
Go to the documentation of this file.
00001 /* GNU/Linux native-dependent code for debugging multiple forks.
00002 
00003    Copyright (C) 2005-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "arch-utils.h"
00022 #include "inferior.h"
00023 #include "regcache.h"
00024 #include "gdbcmd.h"
00025 #include "infcall.h"
00026 #include "objfiles.h"
00027 #include "gdb_assert.h"
00028 #include "gdb_string.h"
00029 #include "linux-fork.h"
00030 #include "linux-nat.h"
00031 #include "gdbthread.h"
00032 #include "source.h"
00033 
00034 #include <sys/ptrace.h>
00035 #include "gdb_wait.h"
00036 #include "gdb_dirent.h"
00037 #include <ctype.h>
00038 
00039 struct fork_info *fork_list;
00040 static int highest_fork_num;
00041 
00042 /* Prevent warning from -Wmissing-prototypes.  */
00043 extern void _initialize_linux_fork (void);
00044 
00045 /* Fork list data structure:  */
00046 struct fork_info
00047 {
00048   struct fork_info *next;
00049   ptid_t ptid;
00050   ptid_t parent_ptid;
00051   int num;                      /* Convenient handle (GDB fork id).  */
00052   struct regcache *savedregs;   /* Convenient for info fork, saves
00053                                    having to actually switch contexts.  */
00054   int clobber_regs;             /* True if we should restore saved regs.  */
00055   off_t *filepos;               /* Set of open file descriptors' offsets.  */
00056   int maxfd;
00057 };
00058 
00059 /* Fork list methods:  */
00060 
00061 int
00062 forks_exist_p (void)
00063 {
00064   return (fork_list != NULL);
00065 }
00066 
00067 /* Add a fork to the internal fork list.  */
00068 
00069 struct fork_info *
00070 add_fork (pid_t pid)
00071 {
00072   struct fork_info *fp;
00073 
00074   if (fork_list == NULL && pid != ptid_get_pid (inferior_ptid))
00075     {
00076       /* Special case -- if this is the first fork in the list
00077          (the list is hitherto empty), and if this new fork is
00078          NOT the current inferior_ptid, then add inferior_ptid
00079          first, as a special zeroeth fork id.  */
00080       highest_fork_num = -1;
00081       add_fork (ptid_get_pid (inferior_ptid));  /* safe recursion */
00082     }
00083 
00084   fp = XZALLOC (struct fork_info);
00085   fp->ptid = ptid_build (pid, pid, 0);
00086   fp->num = ++highest_fork_num;
00087   fp->next = fork_list;
00088   fork_list = fp;
00089   return fp;
00090 }
00091 
00092 static void
00093 free_fork (struct fork_info *fp)
00094 {
00095   /* Notes on step-resume breakpoints: since this is a concern for
00096      threads, let's convince ourselves that it's not a concern for
00097      forks.  There are two ways for a fork_info to be created.  First,
00098      by the checkpoint command, in which case we're at a gdb prompt
00099      and there can't be any step-resume breakpoint.  Second, by a fork
00100      in the user program, in which case we *may* have stepped into the
00101      fork call, but regardless of whether we follow the parent or the
00102      child, we will return to the same place and the step-resume
00103      breakpoint, if any, will take care of itself as usual.  And
00104      unlike threads, we do not save a private copy of the step-resume
00105      breakpoint -- so we're OK.  */
00106 
00107   if (fp)
00108     {
00109       if (fp->savedregs)
00110         regcache_xfree (fp->savedregs);
00111       if (fp->filepos)
00112         xfree (fp->filepos);
00113       xfree (fp);
00114     }
00115 }
00116 
00117 static void
00118 delete_fork (ptid_t ptid)
00119 {
00120   struct fork_info *fp, *fpprev;
00121 
00122   fpprev = NULL;
00123 
00124   linux_nat_forget_process (ptid_get_pid (ptid));
00125 
00126   for (fp = fork_list; fp; fpprev = fp, fp = fp->next)
00127     if (ptid_equal (fp->ptid, ptid))
00128       break;
00129 
00130   if (!fp)
00131     return;
00132 
00133   if (fpprev)
00134     fpprev->next = fp->next;
00135   else
00136     fork_list = fp->next;
00137 
00138   free_fork (fp);
00139 
00140   /* Special case: if there is now only one process in the list,
00141      and if it is (hopefully!) the current inferior_ptid, then
00142      remove it, leaving the list empty -- we're now down to the
00143      default case of debugging a single process.  */
00144   if (fork_list != NULL && fork_list->next == NULL &&
00145       ptid_equal (fork_list->ptid, inferior_ptid))
00146     {
00147       /* Last fork -- delete from list and handle as solo process
00148          (should be a safe recursion).  */
00149       delete_fork (inferior_ptid);
00150     }
00151 }
00152 
00153 /* Find a fork_info by matching PTID.  */
00154 static struct fork_info *
00155 find_fork_ptid (ptid_t ptid)
00156 {
00157   struct fork_info *fp;
00158 
00159   for (fp = fork_list; fp; fp = fp->next)
00160     if (ptid_equal (fp->ptid, ptid))
00161       return fp;
00162 
00163   return NULL;
00164 }
00165 
00166 /* Find a fork_info by matching ID.  */
00167 static struct fork_info *
00168 find_fork_id (int num)
00169 {
00170   struct fork_info *fp;
00171 
00172   for (fp = fork_list; fp; fp = fp->next)
00173     if (fp->num == num)
00174       return fp;
00175 
00176   return NULL;
00177 }
00178 
00179 /* Find a fork_info by matching pid.  */
00180 extern struct fork_info *
00181 find_fork_pid (pid_t pid)
00182 {
00183   struct fork_info *fp;
00184 
00185   for (fp = fork_list; fp; fp = fp->next)
00186     if (pid == ptid_get_pid (fp->ptid))
00187       return fp;
00188 
00189   return NULL;
00190 }
00191 
00192 static ptid_t
00193 fork_id_to_ptid (int num)
00194 {
00195   struct fork_info *fork = find_fork_id (num);
00196   if (fork)
00197     return fork->ptid;
00198   else
00199     return pid_to_ptid (-1);
00200 }
00201 
00202 static void
00203 init_fork_list (void)
00204 {
00205   struct fork_info *fp, *fpnext;
00206 
00207   if (!fork_list)
00208     return;
00209 
00210   for (fp = fork_list; fp; fp = fpnext)
00211     {
00212       fpnext = fp->next;
00213       free_fork (fp);
00214     }
00215 
00216   fork_list = NULL;
00217 }
00218 
00219 /* Fork list <-> gdb interface.  */
00220 
00221 /* Utility function for fork_load/fork_save.
00222    Calls lseek in the (current) inferior process.  */
00223 
00224 static off_t
00225 call_lseek (int fd, off_t offset, int whence)
00226 {
00227   char exp[80];
00228 
00229   snprintf (&exp[0], sizeof (exp), "lseek (%d, %ld, %d)",
00230             fd, (long) offset, whence);
00231   return (off_t) parse_and_eval_long (&exp[0]);
00232 }
00233 
00234 /* Load infrun state for the fork PTID.  */
00235 
00236 static void
00237 fork_load_infrun_state (struct fork_info *fp)
00238 {
00239   extern void nullify_last_target_wait_ptid ();
00240   int i;
00241 
00242   linux_nat_switch_fork (fp->ptid);
00243 
00244   if (fp->savedregs && fp->clobber_regs)
00245     regcache_cpy (get_current_regcache (), fp->savedregs);
00246 
00247   registers_changed ();
00248   reinit_frame_cache ();
00249 
00250   stop_pc = regcache_read_pc (get_current_regcache ());
00251   nullify_last_target_wait_ptid ();
00252 
00253   /* Now restore the file positions of open file descriptors.  */
00254   if (fp->filepos)
00255     {
00256       for (i = 0; i <= fp->maxfd; i++)
00257         if (fp->filepos[i] != (off_t) -1)
00258           call_lseek (i, fp->filepos[i], SEEK_SET);
00259       /* NOTE: I can get away with using SEEK_SET and SEEK_CUR because
00260          this is native-only.  If it ever has to be cross, we'll have
00261          to rethink this.  */
00262     }
00263 }
00264 
00265 /* Save infrun state for the fork PTID.
00266    Exported for use by linux child_follow_fork.  */
00267 
00268 static void
00269 fork_save_infrun_state (struct fork_info *fp, int clobber_regs)
00270 {
00271   char path[PATH_MAX];
00272   struct dirent *de;
00273   DIR *d;
00274 
00275   if (fp->savedregs)
00276     regcache_xfree (fp->savedregs);
00277 
00278   fp->savedregs = regcache_dup (get_current_regcache ());
00279   fp->clobber_regs = clobber_regs;
00280 
00281   if (clobber_regs)
00282     {
00283       /* Now save the 'state' (file position) of all open file descriptors.
00284          Unfortunately fork does not take care of that for us...  */
00285       snprintf (path, PATH_MAX, "/proc/%ld/fd",
00286                 (long) ptid_get_pid (fp->ptid));
00287       if ((d = opendir (path)) != NULL)
00288         {
00289           long tmp;
00290 
00291           fp->maxfd = 0;
00292           while ((de = readdir (d)) != NULL)
00293             {
00294               /* Count open file descriptors (actually find highest
00295                  numbered).  */
00296               tmp = strtol (&de->d_name[0], NULL, 10);
00297               if (fp->maxfd < tmp)
00298                 fp->maxfd = tmp;
00299             }
00300           /* Allocate array of file positions.  */
00301           fp->filepos = xrealloc (fp->filepos,
00302                                   (fp->maxfd + 1) * sizeof (*fp->filepos));
00303 
00304           /* Initialize to -1 (invalid).  */
00305           for (tmp = 0; tmp <= fp->maxfd; tmp++)
00306             fp->filepos[tmp] = -1;
00307 
00308           /* Now find actual file positions.  */
00309           rewinddir (d);
00310           while ((de = readdir (d)) != NULL)
00311             if (isdigit (de->d_name[0]))
00312               {
00313                 tmp = strtol (&de->d_name[0], NULL, 10);
00314                 fp->filepos[tmp] = call_lseek (tmp, 0, SEEK_CUR);
00315               }
00316           closedir (d);
00317         }
00318     }
00319 }
00320 
00321 /* Kill 'em all, let God sort 'em out...  */
00322 
00323 void
00324 linux_fork_killall (void)
00325 {
00326   /* Walk list and kill every pid.  No need to treat the
00327      current inferior_ptid as special (we do not return a
00328      status for it) -- however any process may be a child
00329      or a parent, so may get a SIGCHLD from a previously
00330      killed child.  Wait them all out.  */
00331   struct fork_info *fp;
00332   pid_t pid, ret;
00333   int status;
00334 
00335   for (fp = fork_list; fp; fp = fp->next)
00336     {
00337       pid = ptid_get_pid (fp->ptid);
00338       do {
00339         /* Use SIGKILL instead of PTRACE_KILL because the former works even
00340            if the thread is running, while the later doesn't.  */
00341         kill (pid, SIGKILL);
00342         ret = waitpid (pid, &status, 0);
00343         /* We might get a SIGCHLD instead of an exit status.  This is
00344          aggravated by the first kill above - a child has just
00345          died.  MVS comment cut-and-pasted from linux-nat.  */
00346       } while (ret == pid && WIFSTOPPED (status));
00347     }
00348   init_fork_list ();    /* Clear list, prepare to start fresh.  */
00349 }
00350 
00351 /* The current inferior_ptid has exited, but there are other viable
00352    forks to debug.  Delete the exiting one and context-switch to the
00353    first available.  */
00354 
00355 void
00356 linux_fork_mourn_inferior (void)
00357 {
00358   /* Wait just one more time to collect the inferior's exit status.
00359      Do not check whether this succeeds though, since we may be
00360      dealing with a process that we attached to.  Such a process will
00361      only report its exit status to its original parent.  */
00362   int status;
00363 
00364   waitpid (ptid_get_pid (inferior_ptid), &status, 0);
00365 
00366   /* OK, presumably inferior_ptid is the one who has exited.
00367      We need to delete that one from the fork_list, and switch
00368      to the next available fork.  */
00369   delete_fork (inferior_ptid);
00370 
00371   /* There should still be a fork - if there's only one left,
00372      delete_fork won't remove it, because we haven't updated
00373      inferior_ptid yet.  */
00374   gdb_assert (fork_list);
00375 
00376   fork_load_infrun_state (fork_list);
00377   printf_filtered (_("[Switching to %s]\n"),
00378                    target_pid_to_str (inferior_ptid));
00379 
00380   /* If there's only one fork, switch back to non-fork mode.  */
00381   if (fork_list->next == NULL)
00382     delete_fork (inferior_ptid);
00383 }
00384 
00385 /* The current inferior_ptid is being detached, but there are other
00386    viable forks to debug.  Detach and delete it and context-switch to
00387    the first available.  */
00388 
00389 void
00390 linux_fork_detach (char *args, int from_tty)
00391 {
00392   /* OK, inferior_ptid is the one we are detaching from.  We need to
00393      delete it from the fork_list, and switch to the next available
00394      fork.  */
00395 
00396   if (ptrace (PTRACE_DETACH, ptid_get_pid (inferior_ptid), 0, 0))
00397     error (_("Unable to detach %s"), target_pid_to_str (inferior_ptid));
00398 
00399   delete_fork (inferior_ptid);
00400 
00401   /* There should still be a fork - if there's only one left,
00402      delete_fork won't remove it, because we haven't updated
00403      inferior_ptid yet.  */
00404   gdb_assert (fork_list);
00405 
00406   fork_load_infrun_state (fork_list);
00407 
00408   if (from_tty)
00409     printf_filtered (_("[Switching to %s]\n"),
00410                      target_pid_to_str (inferior_ptid));
00411 
00412   /* If there's only one fork, switch back to non-fork mode.  */
00413   if (fork_list->next == NULL)
00414     delete_fork (inferior_ptid);
00415 }
00416 
00417 static void
00418 inferior_call_waitpid_cleanup (void *fp)
00419 {
00420   struct fork_info *oldfp = fp;
00421 
00422   if (oldfp)
00423     {
00424       /* Switch back to inferior_ptid.  */
00425       remove_breakpoints ();
00426       fork_load_infrun_state (oldfp);
00427       insert_breakpoints ();
00428     }
00429 }
00430 
00431 static int
00432 inferior_call_waitpid (ptid_t pptid, int pid)
00433 {
00434   struct objfile *waitpid_objf;
00435   struct value *waitpid_fn = NULL;
00436   struct value *argv[4], *retv;
00437   struct gdbarch *gdbarch = get_current_arch ();
00438   struct fork_info *oldfp = NULL, *newfp = NULL;
00439   struct cleanup *old_cleanup;
00440   int ret = -1;
00441 
00442   if (!ptid_equal (pptid, inferior_ptid))
00443     {
00444       /* Switch to pptid.  */
00445       oldfp = find_fork_ptid (inferior_ptid);
00446       gdb_assert (oldfp != NULL);
00447       newfp = find_fork_ptid (pptid);
00448       gdb_assert (newfp != NULL);
00449       fork_save_infrun_state (oldfp, 1);
00450       remove_breakpoints ();
00451       fork_load_infrun_state (newfp);
00452       insert_breakpoints ();
00453     }
00454 
00455   old_cleanup = make_cleanup (inferior_call_waitpid_cleanup, oldfp);
00456 
00457   /* Get the waitpid_fn.  */
00458   if (lookup_minimal_symbol ("waitpid", NULL, NULL) != NULL)
00459     waitpid_fn = find_function_in_inferior ("waitpid", &waitpid_objf);
00460   if (!waitpid_fn && lookup_minimal_symbol ("_waitpid", NULL, NULL) != NULL)
00461     waitpid_fn = find_function_in_inferior ("_waitpid", &waitpid_objf);
00462   if (!waitpid_fn)
00463     goto out;
00464 
00465   /* Get the argv.  */
00466   argv[0] = value_from_longest (builtin_type (gdbarch)->builtin_int, pid);
00467   argv[1] = value_from_pointer (builtin_type (gdbarch)->builtin_data_ptr, 0);
00468   argv[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
00469   argv[3] = 0;
00470 
00471   retv = call_function_by_hand (waitpid_fn, 3, argv);
00472   if (value_as_long (retv) < 0)
00473     goto out;
00474 
00475   ret = 0;
00476 
00477 out:
00478   do_cleanups (old_cleanup);
00479   return ret;
00480 }
00481 
00482 /* Fork list <-> user interface.  */
00483 
00484 static void
00485 delete_checkpoint_command (char *args, int from_tty)
00486 {
00487   ptid_t ptid, pptid;
00488   struct fork_info *fi;
00489 
00490   if (!args || !*args)
00491     error (_("Requires argument (checkpoint id to delete)"));
00492 
00493   ptid = fork_id_to_ptid (parse_and_eval_long (args));
00494   if (ptid_equal (ptid, minus_one_ptid))
00495     error (_("No such checkpoint id, %s"), args);
00496 
00497   if (ptid_equal (ptid, inferior_ptid))
00498     error (_("\
00499 Please switch to another checkpoint before deleting the current one"));
00500 
00501   if (ptrace (PTRACE_KILL, ptid_get_pid (ptid), 0, 0))
00502     error (_("Unable to kill pid %s"), target_pid_to_str (ptid));
00503 
00504   fi = find_fork_ptid (ptid);
00505   gdb_assert (fi);
00506   pptid = fi->parent_ptid;
00507 
00508   if (from_tty)
00509     printf_filtered (_("Killed %s\n"), target_pid_to_str (ptid));
00510 
00511   delete_fork (ptid);
00512 
00513   /* If fi->parent_ptid is not a part of lwp but it's a part of checkpoint
00514      list, waitpid the ptid.
00515      If fi->parent_ptid is a part of lwp and it is stoped, waitpid the
00516      ptid.  */
00517   if ((!find_thread_ptid (pptid) && find_fork_ptid (pptid))
00518       || (find_thread_ptid (pptid) && is_stopped (pptid)))
00519     {
00520       if (inferior_call_waitpid (pptid, ptid_get_pid (ptid)))
00521         warning (_("Unable to wait pid %s"), target_pid_to_str (ptid));
00522     }
00523 }
00524 
00525 static void
00526 detach_checkpoint_command (char *args, int from_tty)
00527 {
00528   ptid_t ptid;
00529 
00530   if (!args || !*args)
00531     error (_("Requires argument (checkpoint id to detach)"));
00532 
00533   ptid = fork_id_to_ptid (parse_and_eval_long (args));
00534   if (ptid_equal (ptid, minus_one_ptid))
00535     error (_("No such checkpoint id, %s"), args);
00536 
00537   if (ptid_equal (ptid, inferior_ptid))
00538     error (_("\
00539 Please switch to another checkpoint before detaching the current one"));
00540 
00541   if (ptrace (PTRACE_DETACH, ptid_get_pid (ptid), 0, 0))
00542     error (_("Unable to detach %s"), target_pid_to_str (ptid));
00543 
00544   if (from_tty)
00545     printf_filtered (_("Detached %s\n"), target_pid_to_str (ptid));
00546 
00547   delete_fork (ptid);
00548 }
00549 
00550 /* Print information about currently known checkpoints.  */
00551 
00552 static void
00553 info_checkpoints_command (char *arg, int from_tty)
00554 {
00555   struct gdbarch *gdbarch = get_current_arch ();
00556   struct symtab_and_line sal;
00557   struct fork_info *fp;
00558   ULONGEST pc;
00559   int requested = -1;
00560   struct fork_info *printed = NULL;
00561 
00562   if (arg && *arg)
00563     requested = (int) parse_and_eval_long (arg);
00564 
00565   for (fp = fork_list; fp; fp = fp->next)
00566     {
00567       if (requested > 0 && fp->num != requested)
00568         continue;
00569 
00570       printed = fp;
00571       if (ptid_equal (fp->ptid, inferior_ptid))
00572         {
00573           printf_filtered ("* ");
00574           pc = regcache_read_pc (get_current_regcache ());
00575         }
00576       else
00577         {
00578           printf_filtered ("  ");
00579           pc = regcache_read_pc (fp->savedregs);
00580         }
00581       printf_filtered ("%d %s", fp->num, target_pid_to_str (fp->ptid));
00582       if (fp->num == 0)
00583         printf_filtered (_(" (main process)"));
00584       printf_filtered (_(" at "));
00585       fputs_filtered (paddress (gdbarch, pc), gdb_stdout);
00586 
00587       sal = find_pc_line (pc, 0);
00588       if (sal.symtab)
00589         printf_filtered (_(", file %s"),
00590                          symtab_to_filename_for_display (sal.symtab));
00591       if (sal.line)
00592         printf_filtered (_(", line %d"), sal.line);
00593       if (!sal.symtab && !sal.line)
00594         {
00595           struct bound_minimal_symbol msym;
00596 
00597           msym = lookup_minimal_symbol_by_pc (pc);
00598           if (msym.minsym)
00599             printf_filtered (", <%s>", SYMBOL_LINKAGE_NAME (msym.minsym));
00600         }
00601 
00602       putchar_filtered ('\n');
00603     }
00604   if (printed == NULL)
00605     {
00606       if (requested > 0)
00607         printf_filtered (_("No checkpoint number %d.\n"), requested);
00608       else
00609         printf_filtered (_("No checkpoints.\n"));
00610     }
00611 }
00612 
00613 /* The PID of the process we're checkpointing.  */
00614 static int checkpointing_pid = 0;
00615 
00616 int
00617 linux_fork_checkpointing_p (int pid)
00618 {
00619   return (checkpointing_pid == pid);
00620 }
00621 
00622 /* Callback for iterate over threads.  Used to check whether
00623    the current inferior is multi-threaded.  Returns true as soon
00624    as it sees the second thread of the current inferior.  */
00625 
00626 static int
00627 inf_has_multiple_thread_cb (struct thread_info *tp, void *data)
00628 {
00629   int *count_p = (int *) data;
00630   
00631   if (current_inferior ()->pid == ptid_get_pid (tp->ptid))
00632     (*count_p)++;
00633   
00634   /* Stop the iteration if multiple threads have been detected.  */
00635   return *count_p > 1;
00636 }
00637 
00638 /* Return true if the current inferior is multi-threaded.  */
00639 
00640 static int
00641 inf_has_multiple_threads (void)
00642 {
00643   int count = 0;
00644 
00645   iterate_over_threads (inf_has_multiple_thread_cb, &count);
00646   return (count > 1);
00647 }
00648 
00649 static void
00650 checkpoint_command (char *args, int from_tty)
00651 {
00652   struct objfile *fork_objf;
00653   struct gdbarch *gdbarch;
00654   struct target_waitstatus last_target_waitstatus;
00655   ptid_t last_target_ptid;
00656   struct value *fork_fn = NULL, *ret;
00657   struct fork_info *fp;
00658   pid_t retpid;
00659   struct cleanup *old_chain;
00660 
00661   if (!target_has_execution) 
00662     error (_("The program is not being run."));
00663 
00664   /* Ensure that the inferior is not multithreaded.  */
00665   update_thread_list ();
00666   if (inf_has_multiple_threads ())
00667     error (_("checkpoint: can't checkpoint multiple threads."));
00668   
00669   /* Make the inferior fork, record its (and gdb's) state.  */
00670 
00671   if (lookup_minimal_symbol ("fork", NULL, NULL) != NULL)
00672     fork_fn = find_function_in_inferior ("fork", &fork_objf);
00673   if (!fork_fn)
00674     if (lookup_minimal_symbol ("_fork", NULL, NULL) != NULL)
00675       fork_fn = find_function_in_inferior ("fork", &fork_objf);
00676   if (!fork_fn)
00677     error (_("checkpoint: can't find fork function in inferior."));
00678 
00679   gdbarch = get_objfile_arch (fork_objf);
00680   ret = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
00681 
00682   /* Tell linux-nat.c that we're checkpointing this inferior.  */
00683   old_chain = make_cleanup_restore_integer (&checkpointing_pid);
00684   checkpointing_pid = ptid_get_pid (inferior_ptid);
00685 
00686   ret = call_function_by_hand (fork_fn, 0, &ret);
00687   do_cleanups (old_chain);
00688   if (!ret)     /* Probably can't happen.  */
00689     error (_("checkpoint: call_function_by_hand returned null."));
00690 
00691   retpid = value_as_long (ret);
00692   get_last_target_status (&last_target_ptid, &last_target_waitstatus);
00693   if (from_tty)
00694     {
00695       int parent_pid;
00696 
00697       printf_filtered (_("checkpoint: fork returned pid %ld.\n"),
00698                        (long) retpid);
00699       if (info_verbose)
00700         {
00701           parent_pid = ptid_get_lwp (last_target_ptid);
00702           if (parent_pid == 0)
00703             parent_pid = ptid_get_pid (last_target_ptid);
00704           printf_filtered (_("   gdb says parent = %ld.\n"),
00705                            (long) parent_pid);
00706         }
00707     }
00708 
00709   fp = find_fork_pid (retpid);
00710   if (!fp)
00711     error (_("Failed to find new fork"));
00712   fork_save_infrun_state (fp, 1);
00713   fp->parent_ptid = last_target_ptid;
00714 }
00715 
00716 static void
00717 linux_fork_context (struct fork_info *newfp, int from_tty)
00718 {
00719   /* Now we attempt to switch processes.  */
00720   struct fork_info *oldfp;
00721 
00722   gdb_assert (newfp != NULL);
00723 
00724   oldfp = find_fork_ptid (inferior_ptid);
00725   gdb_assert (oldfp != NULL);
00726 
00727   fork_save_infrun_state (oldfp, 1);
00728   remove_breakpoints ();
00729   fork_load_infrun_state (newfp);
00730   insert_breakpoints ();
00731 
00732   printf_filtered (_("Switching to %s\n"),
00733                    target_pid_to_str (inferior_ptid));
00734 
00735   print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
00736 }
00737 
00738 /* Switch inferior process (checkpoint) context, by checkpoint id.  */
00739 static void
00740 restart_command (char *args, int from_tty)
00741 {
00742   struct fork_info *fp;
00743 
00744   if (!args || !*args)
00745     error (_("Requires argument (checkpoint id to restart)"));
00746 
00747   if ((fp = find_fork_id (parse_and_eval_long (args))) == NULL)
00748     error (_("Not found: checkpoint id %s"), args);
00749 
00750   linux_fork_context (fp, from_tty);
00751 }
00752 
00753 void
00754 _initialize_linux_fork (void)
00755 {
00756   init_fork_list ();
00757 
00758   /* Checkpoint command: create a fork of the inferior process
00759      and set it aside for later debugging.  */
00760 
00761   add_com ("checkpoint", class_obscure, checkpoint_command, _("\
00762 Fork a duplicate process (experimental)."));
00763 
00764   /* Restart command: restore the context of a specified checkpoint
00765      process.  */
00766 
00767   add_com ("restart", class_obscure, restart_command, _("\
00768 restart <n>: restore program context from a checkpoint.\n\
00769 Argument 'n' is checkpoint ID, as displayed by 'info checkpoints'."));
00770 
00771   /* Delete checkpoint command: kill the process and remove it from
00772      the fork list.  */
00773 
00774   add_cmd ("checkpoint", class_obscure, delete_checkpoint_command, _("\
00775 Delete a checkpoint (experimental)."),
00776            &deletelist);
00777 
00778   /* Detach checkpoint command: release the process to run independently,
00779      and remove it from the fork list.  */
00780 
00781   add_cmd ("checkpoint", class_obscure, detach_checkpoint_command, _("\
00782 Detach from a checkpoint (experimental)."),
00783            &detachlist);
00784 
00785   /* Info checkpoints command: list all forks/checkpoints
00786      currently under gdb's control.  */
00787 
00788   add_info ("checkpoints", info_checkpoints_command,
00789             _("IDs of currently known checkpoints."));
00790 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines