1 /* GNU/Linux native-dependent code for debugging multiple forks. 2 3 Copyright (C) 2005-2015 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 "infrun.h" 24 #include "regcache.h" 25 #include "gdbcmd.h" 26 #include "infcall.h" 27 #include "objfiles.h" 28 #include "linux-fork.h" 29 #include "linux-nat.h" 30 #include "gdbthread.h" 31 #include "source.h" 32 33 #include <sys/ptrace.h> 34 #include "gdb_wait.h" 35 #include <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 /* Fork list data structure: */ 45 struct fork_info 46 { 47 struct fork_info *next; 48 ptid_t ptid; 49 ptid_t parent_ptid; 50 int num; /* Convenient handle (GDB fork id). */ 51 struct regcache *savedregs; /* Convenient for info fork, saves 52 having to actually switch contexts. */ 53 int clobber_regs; /* True if we should restore saved regs. */ 54 off_t *filepos; /* Set of open file descriptors' offsets. */ 55 int maxfd; 56 }; 57 58 /* Fork list methods: */ 59 60 int 61 forks_exist_p (void) 62 { 63 return (fork_list != NULL); 64 } 65 66 /* Add a fork to the internal fork list. */ 67 68 struct fork_info * 69 add_fork (pid_t pid) 70 { 71 struct fork_info *fp; 72 73 if (fork_list == NULL && pid != ptid_get_pid (inferior_ptid)) 74 { 75 /* Special case -- if this is the first fork in the list 76 (the list is hitherto empty), and if this new fork is 77 NOT the current inferior_ptid, then add inferior_ptid 78 first, as a special zeroeth fork id. */ 79 highest_fork_num = -1; 80 add_fork (ptid_get_pid (inferior_ptid)); /* safe recursion */ 81 } 82 83 fp = XCNEW (struct fork_info); 84 fp->ptid = ptid_build (pid, pid, 0); 85 fp->num = ++highest_fork_num; 86 fp->next = fork_list; 87 fork_list = fp; 88 return fp; 89 } 90 91 static void 92 free_fork (struct fork_info *fp) 93 { 94 /* Notes on step-resume breakpoints: since this is a concern for 95 threads, let's convince ourselves that it's not a concern for 96 forks. There are two ways for a fork_info to be created. First, 97 by the checkpoint command, in which case we're at a gdb prompt 98 and there can't be any step-resume breakpoint. Second, by a fork 99 in the user program, in which case we *may* have stepped into the 100 fork call, but regardless of whether we follow the parent or the 101 child, we will return to the same place and the step-resume 102 breakpoint, if any, will take care of itself as usual. And 103 unlike threads, we do not save a private copy of the step-resume 104 breakpoint -- so we're OK. */ 105 106 if (fp) 107 { 108 if (fp->savedregs) 109 regcache_xfree (fp->savedregs); 110 if (fp->filepos) 111 xfree (fp->filepos); 112 xfree (fp); 113 } 114 } 115 116 static void 117 delete_fork (ptid_t ptid) 118 { 119 struct fork_info *fp, *fpprev; 120 121 fpprev = NULL; 122 123 linux_nat_forget_process (ptid_get_pid (ptid)); 124 125 for (fp = fork_list; fp; fpprev = fp, fp = fp->next) 126 if (ptid_equal (fp->ptid, ptid)) 127 break; 128 129 if (!fp) 130 return; 131 132 if (fpprev) 133 fpprev->next = fp->next; 134 else 135 fork_list = fp->next; 136 137 free_fork (fp); 138 139 /* Special case: if there is now only one process in the list, 140 and if it is (hopefully!) the current inferior_ptid, then 141 remove it, leaving the list empty -- we're now down to the 142 default case of debugging a single process. */ 143 if (fork_list != NULL && fork_list->next == NULL && 144 ptid_equal (fork_list->ptid, inferior_ptid)) 145 { 146 /* Last fork -- delete from list and handle as solo process 147 (should be a safe recursion). */ 148 delete_fork (inferior_ptid); 149 } 150 } 151 152 /* Find a fork_info by matching PTID. */ 153 static struct fork_info * 154 find_fork_ptid (ptid_t ptid) 155 { 156 struct fork_info *fp; 157 158 for (fp = fork_list; fp; fp = fp->next) 159 if (ptid_equal (fp->ptid, ptid)) 160 return fp; 161 162 return NULL; 163 } 164 165 /* Find a fork_info by matching ID. */ 166 static struct fork_info * 167 find_fork_id (int num) 168 { 169 struct fork_info *fp; 170 171 for (fp = fork_list; fp; fp = fp->next) 172 if (fp->num == num) 173 return fp; 174 175 return NULL; 176 } 177 178 /* Find a fork_info by matching pid. */ 179 extern struct fork_info * 180 find_fork_pid (pid_t pid) 181 { 182 struct fork_info *fp; 183 184 for (fp = fork_list; fp; fp = fp->next) 185 if (pid == ptid_get_pid (fp->ptid)) 186 return fp; 187 188 return NULL; 189 } 190 191 static ptid_t 192 fork_id_to_ptid (int num) 193 { 194 struct fork_info *fork = find_fork_id (num); 195 if (fork) 196 return fork->ptid; 197 else 198 return pid_to_ptid (-1); 199 } 200 201 static void 202 init_fork_list (void) 203 { 204 struct fork_info *fp, *fpnext; 205 206 if (!fork_list) 207 return; 208 209 for (fp = fork_list; fp; fp = fpnext) 210 { 211 fpnext = fp->next; 212 free_fork (fp); 213 } 214 215 fork_list = NULL; 216 } 217 218 /* Fork list <-> gdb interface. */ 219 220 /* Utility function for fork_load/fork_save. 221 Calls lseek in the (current) inferior process. */ 222 223 static off_t 224 call_lseek (int fd, off_t offset, int whence) 225 { 226 char exp[80]; 227 228 snprintf (&exp[0], sizeof (exp), "lseek (%d, %ld, %d)", 229 fd, (long) offset, whence); 230 return (off_t) parse_and_eval_long (&exp[0]); 231 } 232 233 /* Load infrun state for the fork PTID. */ 234 235 static void 236 fork_load_infrun_state (struct fork_info *fp) 237 { 238 extern void nullify_last_target_wait_ptid (); 239 int i; 240 241 linux_nat_switch_fork (fp->ptid); 242 243 if (fp->savedregs && fp->clobber_regs) 244 regcache_cpy (get_current_regcache (), fp->savedregs); 245 246 registers_changed (); 247 reinit_frame_cache (); 248 249 stop_pc = regcache_read_pc (get_current_regcache ()); 250 nullify_last_target_wait_ptid (); 251 252 /* Now restore the file positions of open file descriptors. */ 253 if (fp->filepos) 254 { 255 for (i = 0; i <= fp->maxfd; i++) 256 if (fp->filepos[i] != (off_t) -1) 257 call_lseek (i, fp->filepos[i], SEEK_SET); 258 /* NOTE: I can get away with using SEEK_SET and SEEK_CUR because 259 this is native-only. If it ever has to be cross, we'll have 260 to rethink this. */ 261 } 262 } 263 264 /* Save infrun state for the fork PTID. 265 Exported for use by linux child_follow_fork. */ 266 267 static void 268 fork_save_infrun_state (struct fork_info *fp, int clobber_regs) 269 { 270 char path[PATH_MAX]; 271 struct dirent *de; 272 DIR *d; 273 274 if (fp->savedregs) 275 regcache_xfree (fp->savedregs); 276 277 fp->savedregs = regcache_dup (get_current_regcache ()); 278 fp->clobber_regs = clobber_regs; 279 280 if (clobber_regs) 281 { 282 /* Now save the 'state' (file position) of all open file descriptors. 283 Unfortunately fork does not take care of that for us... */ 284 snprintf (path, PATH_MAX, "/proc/%ld/fd", 285 (long) ptid_get_pid (fp->ptid)); 286 if ((d = opendir (path)) != NULL) 287 { 288 long tmp; 289 290 fp->maxfd = 0; 291 while ((de = readdir (d)) != NULL) 292 { 293 /* Count open file descriptors (actually find highest 294 numbered). */ 295 tmp = strtol (&de->d_name[0], NULL, 10); 296 if (fp->maxfd < tmp) 297 fp->maxfd = tmp; 298 } 299 /* Allocate array of file positions. */ 300 fp->filepos = xrealloc (fp->filepos, 301 (fp->maxfd + 1) * sizeof (*fp->filepos)); 302 303 /* Initialize to -1 (invalid). */ 304 for (tmp = 0; tmp <= fp->maxfd; tmp++) 305 fp->filepos[tmp] = -1; 306 307 /* Now find actual file positions. */ 308 rewinddir (d); 309 while ((de = readdir (d)) != NULL) 310 if (isdigit (de->d_name[0])) 311 { 312 tmp = strtol (&de->d_name[0], NULL, 10); 313 fp->filepos[tmp] = call_lseek (tmp, 0, SEEK_CUR); 314 } 315 closedir (d); 316 } 317 } 318 } 319 320 /* Kill 'em all, let God sort 'em out... */ 321 322 void 323 linux_fork_killall (void) 324 { 325 /* Walk list and kill every pid. No need to treat the 326 current inferior_ptid as special (we do not return a 327 status for it) -- however any process may be a child 328 or a parent, so may get a SIGCHLD from a previously 329 killed child. Wait them all out. */ 330 struct fork_info *fp; 331 pid_t pid, ret; 332 int status; 333 334 for (fp = fork_list; fp; fp = fp->next) 335 { 336 pid = ptid_get_pid (fp->ptid); 337 do { 338 /* Use SIGKILL instead of PTRACE_KILL because the former works even 339 if the thread is running, while the later doesn't. */ 340 kill (pid, SIGKILL); 341 ret = waitpid (pid, &status, 0); 342 /* We might get a SIGCHLD instead of an exit status. This is 343 aggravated by the first kill above - a child has just 344 died. MVS comment cut-and-pasted from linux-nat. */ 345 } while (ret == pid && WIFSTOPPED (status)); 346 } 347 init_fork_list (); /* Clear list, prepare to start fresh. */ 348 } 349 350 /* The current inferior_ptid has exited, but there are other viable 351 forks to debug. Delete the exiting one and context-switch to the 352 first available. */ 353 354 void 355 linux_fork_mourn_inferior (void) 356 { 357 /* Wait just one more time to collect the inferior's exit status. 358 Do not check whether this succeeds though, since we may be 359 dealing with a process that we attached to. Such a process will 360 only report its exit status to its original parent. */ 361 int status; 362 363 waitpid (ptid_get_pid (inferior_ptid), &status, 0); 364 365 /* OK, presumably inferior_ptid is the one who has exited. 366 We need to delete that one from the fork_list, and switch 367 to the next available fork. */ 368 delete_fork (inferior_ptid); 369 370 /* There should still be a fork - if there's only one left, 371 delete_fork won't remove it, because we haven't updated 372 inferior_ptid yet. */ 373 gdb_assert (fork_list); 374 375 fork_load_infrun_state (fork_list); 376 printf_filtered (_("[Switching to %s]\n"), 377 target_pid_to_str (inferior_ptid)); 378 379 /* If there's only one fork, switch back to non-fork mode. */ 380 if (fork_list->next == NULL) 381 delete_fork (inferior_ptid); 382 } 383 384 /* The current inferior_ptid is being detached, but there are other 385 viable forks to debug. Detach and delete it and context-switch to 386 the first available. */ 387 388 void 389 linux_fork_detach (const char *args, int from_tty) 390 { 391 /* OK, inferior_ptid is the one we are detaching from. We need to 392 delete it from the fork_list, and switch to the next available 393 fork. */ 394 395 if (ptrace (PTRACE_DETACH, ptid_get_pid (inferior_ptid), 0, 0)) 396 error (_("Unable to detach %s"), target_pid_to_str (inferior_ptid)); 397 398 delete_fork (inferior_ptid); 399 400 /* There should still be a fork - if there's only one left, 401 delete_fork won't remove it, because we haven't updated 402 inferior_ptid yet. */ 403 gdb_assert (fork_list); 404 405 fork_load_infrun_state (fork_list); 406 407 if (from_tty) 408 printf_filtered (_("[Switching to %s]\n"), 409 target_pid_to_str (inferior_ptid)); 410 411 /* If there's only one fork, switch back to non-fork mode. */ 412 if (fork_list->next == NULL) 413 delete_fork (inferior_ptid); 414 } 415 416 static void 417 inferior_call_waitpid_cleanup (void *fp) 418 { 419 struct fork_info *oldfp = fp; 420 421 if (oldfp) 422 { 423 /* Switch back to inferior_ptid. */ 424 remove_breakpoints (); 425 fork_load_infrun_state (oldfp); 426 insert_breakpoints (); 427 } 428 } 429 430 static int 431 inferior_call_waitpid (ptid_t pptid, int pid) 432 { 433 struct objfile *waitpid_objf; 434 struct value *waitpid_fn = NULL; 435 struct value *argv[4], *retv; 436 struct gdbarch *gdbarch = get_current_arch (); 437 struct fork_info *oldfp = NULL, *newfp = NULL; 438 struct cleanup *old_cleanup; 439 int ret = -1; 440 441 if (!ptid_equal (pptid, inferior_ptid)) 442 { 443 /* Switch to pptid. */ 444 oldfp = find_fork_ptid (inferior_ptid); 445 gdb_assert (oldfp != NULL); 446 newfp = find_fork_ptid (pptid); 447 gdb_assert (newfp != NULL); 448 fork_save_infrun_state (oldfp, 1); 449 remove_breakpoints (); 450 fork_load_infrun_state (newfp); 451 insert_breakpoints (); 452 } 453 454 old_cleanup = make_cleanup (inferior_call_waitpid_cleanup, oldfp); 455 456 /* Get the waitpid_fn. */ 457 if (lookup_minimal_symbol ("waitpid", NULL, NULL).minsym != NULL) 458 waitpid_fn = find_function_in_inferior ("waitpid", &waitpid_objf); 459 if (!waitpid_fn 460 && lookup_minimal_symbol ("_waitpid", NULL, NULL).minsym != 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>", MSYMBOL_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).minsym != NULL) 672 fork_fn = find_function_in_inferior ("fork", &fork_objf); 673 if (!fork_fn) 674 if (lookup_minimal_symbol ("_fork", NULL, NULL).minsym != 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 694 fp = find_fork_pid (retpid); 695 696 if (from_tty) 697 { 698 int parent_pid; 699 700 printf_filtered (_("checkpoint %d: fork returned pid %ld.\n"), 701 fp != NULL ? fp->num : -1, (long) retpid); 702 if (info_verbose) 703 { 704 parent_pid = ptid_get_lwp (last_target_ptid); 705 if (parent_pid == 0) 706 parent_pid = ptid_get_pid (last_target_ptid); 707 printf_filtered (_(" gdb says parent = %ld.\n"), 708 (long) parent_pid); 709 } 710 } 711 712 if (!fp) 713 error (_("Failed to find new fork")); 714 fork_save_infrun_state (fp, 1); 715 fp->parent_ptid = last_target_ptid; 716 } 717 718 static void 719 linux_fork_context (struct fork_info *newfp, int from_tty) 720 { 721 /* Now we attempt to switch processes. */ 722 struct fork_info *oldfp; 723 724 gdb_assert (newfp != NULL); 725 726 oldfp = find_fork_ptid (inferior_ptid); 727 gdb_assert (oldfp != NULL); 728 729 fork_save_infrun_state (oldfp, 1); 730 remove_breakpoints (); 731 fork_load_infrun_state (newfp); 732 insert_breakpoints (); 733 734 printf_filtered (_("Switching to %s\n"), 735 target_pid_to_str (inferior_ptid)); 736 737 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1); 738 } 739 740 /* Switch inferior process (checkpoint) context, by checkpoint id. */ 741 static void 742 restart_command (char *args, int from_tty) 743 { 744 struct fork_info *fp; 745 746 if (!args || !*args) 747 error (_("Requires argument (checkpoint id to restart)")); 748 749 if ((fp = find_fork_id (parse_and_eval_long (args))) == NULL) 750 error (_("Not found: checkpoint id %s"), args); 751 752 linux_fork_context (fp, from_tty); 753 } 754 755 void 756 _initialize_linux_fork (void) 757 { 758 init_fork_list (); 759 760 /* Checkpoint command: create a fork of the inferior process 761 and set it aside for later debugging. */ 762 763 add_com ("checkpoint", class_obscure, checkpoint_command, _("\ 764 Fork a duplicate process (experimental).")); 765 766 /* Restart command: restore the context of a specified checkpoint 767 process. */ 768 769 add_com ("restart", class_obscure, restart_command, _("\ 770 restart <n>: restore program context from a checkpoint.\n\ 771 Argument 'n' is checkpoint ID, as displayed by 'info checkpoints'.")); 772 773 /* Delete checkpoint command: kill the process and remove it from 774 the fork list. */ 775 776 add_cmd ("checkpoint", class_obscure, delete_checkpoint_command, _("\ 777 Delete a checkpoint (experimental)."), 778 &deletelist); 779 780 /* Detach checkpoint command: release the process to run independently, 781 and remove it from the fork list. */ 782 783 add_cmd ("checkpoint", class_obscure, detach_checkpoint_command, _("\ 784 Detach from a checkpoint (experimental)."), 785 &detachlist); 786 787 /* Info checkpoints command: list all forks/checkpoints 788 currently under gdb's control. */ 789 790 add_info ("checkpoints", info_checkpoints_command, 791 _("IDs of currently known checkpoints.")); 792 } 793