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