GDB (API)
|
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 }