| OLD | NEW |
| 1 /* Multi-process control for GDB, the GNU debugger. | 1 /* Multi-process control for GDB, the GNU debugger. |
| 2 | 2 |
| 3 Copyright (C) 2008-2012 Free Software Foundation, Inc. | 3 Copyright (C) 2008-2012 Free Software Foundation, Inc. |
| 4 | 4 |
| 5 This file is part of GDB. | 5 This file is part of GDB. |
| 6 | 6 |
| 7 This program is free software; you can redistribute it and/or modify | 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 | 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 | 9 the Free Software Foundation; either version 3 of the License, or |
| 10 (at your option) any later version. | 10 (at your option) any later version. |
| 11 | 11 |
| 12 This program is distributed in the hope that it will be useful, | 12 This program is distributed in the hope that it will be useful, |
| 13 but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 GNU General Public License for more details. | 15 GNU General Public License for more details. |
| 16 | 16 |
| 17 You should have received a copy of the GNU General Public License | 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/>. */ | 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 19 | 19 |
| 20 #include "defs.h" | 20 #include "defs.h" |
| 21 #include "exec.h" | 21 #include "exec.h" |
| 22 #include "inferior.h" | 22 #include "inferior.h" |
| 23 #include "target.h" | 23 #include "target.h" |
| 24 #include "command.h" | 24 #include "command.h" |
| 25 #include "completer.h" |
| 25 #include "gdbcmd.h" | 26 #include "gdbcmd.h" |
| 26 #include "gdbthread.h" | 27 #include "gdbthread.h" |
| 27 #include "ui-out.h" | 28 #include "ui-out.h" |
| 28 #include "observer.h" | 29 #include "observer.h" |
| 29 #include "gdbthread.h" | 30 #include "gdbthread.h" |
| 30 #include "gdbcore.h" | 31 #include "gdbcore.h" |
| 31 #include "symfile.h" | 32 #include "symfile.h" |
| 32 #include "environ.h" | 33 #include "environ.h" |
| 33 #include "cli/cli-utils.h" | 34 #include "cli/cli-utils.h" |
| 34 #include "continuations.h" | 35 #include "continuations.h" |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 { | 172 { |
| 172 if (arg->silent) | 173 if (arg->silent) |
| 173 delete_thread_silent (tp->ptid); | 174 delete_thread_silent (tp->ptid); |
| 174 else | 175 else |
| 175 delete_thread (tp->ptid); | 176 delete_thread (tp->ptid); |
| 176 } | 177 } |
| 177 | 178 |
| 178 return 0; | 179 return 0; |
| 179 } | 180 } |
| 180 | 181 |
| 181 void | |
| 182 delete_threads_of_inferior (int pid) | |
| 183 { | |
| 184 struct inferior *inf; | |
| 185 struct delete_thread_of_inferior_arg arg; | |
| 186 | |
| 187 for (inf = inferior_list; inf; inf = inf->next) | |
| 188 if (inf->pid == pid) | |
| 189 break; | |
| 190 | |
| 191 if (!inf) | |
| 192 return; | |
| 193 | |
| 194 arg.pid = pid; | |
| 195 arg.silent = 1; | |
| 196 | |
| 197 iterate_over_threads (delete_thread_of_inferior, &arg); | |
| 198 } | |
| 199 | |
| 200 /* If SILENT then be quiet -- don't announce a inferior death, or the | 182 /* If SILENT then be quiet -- don't announce a inferior death, or the |
| 201 exit of its threads. */ | 183 exit of its threads. */ |
| 202 | 184 |
| 203 void | 185 void |
| 204 delete_inferior_1 (struct inferior *todel, int silent) | 186 delete_inferior_1 (struct inferior *todel, int silent) |
| 205 { | 187 { |
| 206 struct inferior *inf, *infprev; | 188 struct inferior *inf, *infprev; |
| 207 struct delete_thread_of_inferior_arg arg; | 189 struct delete_thread_of_inferior_arg arg; |
| 208 | 190 |
| 209 infprev = NULL; | 191 infprev = NULL; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 arg.pid = inf->pid; | 251 arg.pid = inf->pid; |
| 270 arg.silent = silent; | 252 arg.silent = silent; |
| 271 | 253 |
| 272 iterate_over_threads (delete_thread_of_inferior, &arg); | 254 iterate_over_threads (delete_thread_of_inferior, &arg); |
| 273 | 255 |
| 274 /* Notify the observers before removing the inferior from the list, | 256 /* Notify the observers before removing the inferior from the list, |
| 275 so that the observers have a chance to look it up. */ | 257 so that the observers have a chance to look it up. */ |
| 276 observer_notify_inferior_exit (inf); | 258 observer_notify_inferior_exit (inf); |
| 277 | 259 |
| 278 inf->pid = 0; | 260 inf->pid = 0; |
| 261 inf->fake_pid_p = 0; |
| 279 if (inf->vfork_parent != NULL) | 262 if (inf->vfork_parent != NULL) |
| 280 { | 263 { |
| 281 inf->vfork_parent->vfork_child = NULL; | 264 inf->vfork_parent->vfork_child = NULL; |
| 282 inf->vfork_parent = NULL; | 265 inf->vfork_parent = NULL; |
| 283 } | 266 } |
| 284 | 267 |
| 285 inf->has_exit_code = 0; | 268 inf->has_exit_code = 0; |
| 286 inf->exit_code = 0; | 269 inf->exit_code = 0; |
| 287 } | 270 } |
| 288 | 271 |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 { | 501 { |
| 519 struct inferior *inf; | 502 struct inferior *inf; |
| 520 int count = 0; | 503 int count = 0; |
| 521 | 504 |
| 522 for (inf = inferior_list; inf != NULL; inf = inf->next) | 505 for (inf = inferior_list; inf != NULL; inf = inf->next) |
| 523 count++; | 506 count++; |
| 524 | 507 |
| 525 return count; | 508 return count; |
| 526 } | 509 } |
| 527 | 510 |
| 511 /* Converts an inferior process id to a string. Like |
| 512 target_pid_to_str, but special cases the null process. */ |
| 513 |
| 514 static char * |
| 515 inferior_pid_to_str (int pid) |
| 516 { |
| 517 if (pid != 0) |
| 518 return target_pid_to_str (pid_to_ptid (pid)); |
| 519 else |
| 520 return _("<null>"); |
| 521 } |
| 522 |
| 528 /* Prints the list of inferiors and their details on UIOUT. This is a | 523 /* Prints the list of inferiors and their details on UIOUT. This is a |
| 529 version of 'info_inferior_command' suitable for use from MI. | 524 version of 'info_inferior_command' suitable for use from MI. |
| 530 | 525 |
| 531 If REQUESTED_INFERIORS is not NULL, it's a list of GDB ids of the | 526 If REQUESTED_INFERIORS is not NULL, it's a list of GDB ids of the |
| 532 inferiors that should be printed. Otherwise, all inferiors are | 527 inferiors that should be printed. Otherwise, all inferiors are |
| 533 printed. */ | 528 printed. */ |
| 534 | 529 |
| 535 static void | 530 static void |
| 536 print_inferior (struct ui_out *uiout, char *requested_inferiors) | 531 print_inferior (struct ui_out *uiout, char *requested_inferiors) |
| 537 { | 532 { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 | 566 |
| 572 chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); | 567 chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); |
| 573 | 568 |
| 574 if (inf == current_inferior ()) | 569 if (inf == current_inferior ()) |
| 575 ui_out_field_string (uiout, "current", "*"); | 570 ui_out_field_string (uiout, "current", "*"); |
| 576 else | 571 else |
| 577 ui_out_field_skip (uiout, "current"); | 572 ui_out_field_skip (uiout, "current"); |
| 578 | 573 |
| 579 ui_out_field_int (uiout, "number", inf->num); | 574 ui_out_field_int (uiout, "number", inf->num); |
| 580 | 575 |
| 581 if (inf->pid) | 576 ui_out_field_string (uiout, "target-id", |
| 582 » ui_out_field_string (uiout, "target-id", | 577 » » » inferior_pid_to_str (inf->pid)); |
| 583 » » » target_pid_to_str (pid_to_ptid (inf->pid))); | |
| 584 else | |
| 585 » ui_out_field_string (uiout, "target-id", "<null>"); | |
| 586 | 578 |
| 587 if (inf->pspace->ebfd) | 579 if (inf->pspace->ebfd) |
| 588 ui_out_field_string (uiout, "exec", | 580 ui_out_field_string (uiout, "exec", |
| 589 bfd_get_filename (inf->pspace->ebfd)); | 581 bfd_get_filename (inf->pspace->ebfd)); |
| 590 else | 582 else |
| 591 ui_out_field_skip (uiout, "exec"); | 583 ui_out_field_skip (uiout, "exec"); |
| 592 | 584 |
| 593 /* Print extra info that isn't really fit to always present in | 585 /* Print extra info that isn't really fit to always present in |
| 594 tabular form. Currently we print the vfork parent/child | 586 tabular form. Currently we print the vfork parent/child |
| 595 relationships, if any. */ | 587 relationships, if any. */ |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 int num; | 684 int num; |
| 693 | 685 |
| 694 num = parse_and_eval_long (args); | 686 num = parse_and_eval_long (args); |
| 695 | 687 |
| 696 inf = find_inferior_id (num); | 688 inf = find_inferior_id (num); |
| 697 if (inf == NULL) | 689 if (inf == NULL) |
| 698 error (_("Inferior ID %d not known."), num); | 690 error (_("Inferior ID %d not known."), num); |
| 699 | 691 |
| 700 printf_filtered (_("[Switching to inferior %d [%s] (%s)]\n"), | 692 printf_filtered (_("[Switching to inferior %d [%s] (%s)]\n"), |
| 701 inf->num, | 693 inf->num, |
| 702 » » target_pid_to_str (pid_to_ptid (inf->pid)), | 694 » » inferior_pid_to_str (inf->pid), |
| 703 (inf->pspace->ebfd | 695 (inf->pspace->ebfd |
| 704 ? bfd_get_filename (inf->pspace->ebfd) | 696 ? bfd_get_filename (inf->pspace->ebfd) |
| 705 : _("<noexec>"))); | 697 : _("<noexec>"))); |
| 706 | 698 |
| 707 if (inf->pid != 0) | 699 if (inf->pid != 0) |
| 708 { | 700 { |
| 709 if (inf->pid != ptid_get_pid (inferior_ptid)) | 701 if (inf->pid != ptid_get_pid (inferior_ptid)) |
| 710 { | 702 { |
| 711 struct thread_info *tp; | 703 struct thread_info *tp; |
| 712 | 704 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 743 /* Print information about currently known inferiors. */ | 735 /* Print information about currently known inferiors. */ |
| 744 | 736 |
| 745 static void | 737 static void |
| 746 info_inferiors_command (char *args, int from_tty) | 738 info_inferiors_command (char *args, int from_tty) |
| 747 { | 739 { |
| 748 print_inferior (current_uiout, args); | 740 print_inferior (current_uiout, args); |
| 749 } | 741 } |
| 750 | 742 |
| 751 /* remove-inferior ID */ | 743 /* remove-inferior ID */ |
| 752 | 744 |
| 753 void | 745 static void |
| 754 remove_inferior_command (char *args, int from_tty) | 746 remove_inferior_command (char *args, int from_tty) |
| 755 { | 747 { |
| 756 int num; | 748 int num; |
| 757 struct inferior *inf; | 749 struct inferior *inf; |
| 758 struct get_number_or_range_state state; | 750 struct get_number_or_range_state state; |
| 759 | 751 |
| 760 if (args == NULL || *args == '\0') | 752 if (args == NULL || *args == '\0') |
| 761 error (_("Requires an argument (inferior id(s) to remove)")); | 753 error (_("Requires an argument (inferior id(s) to remove)")); |
| 762 | 754 |
| 763 init_number_or_range (&state, args); | 755 init_number_or_range (&state, args); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 802 pspace = add_program_space (aspace); | 794 pspace = add_program_space (aspace); |
| 803 inf = add_inferior (0); | 795 inf = add_inferior (0); |
| 804 inf->pspace = pspace; | 796 inf->pspace = pspace; |
| 805 inf->aspace = pspace->aspace; | 797 inf->aspace = pspace->aspace; |
| 806 | 798 |
| 807 return inf; | 799 return inf; |
| 808 } | 800 } |
| 809 | 801 |
| 810 /* add-inferior [-copies N] [-exec FILENAME] */ | 802 /* add-inferior [-copies N] [-exec FILENAME] */ |
| 811 | 803 |
| 812 void | 804 static void |
| 813 add_inferior_command (char *args, int from_tty) | 805 add_inferior_command (char *args, int from_tty) |
| 814 { | 806 { |
| 815 int i, copies = 1; | 807 int i, copies = 1; |
| 816 char *exec = NULL; | 808 char *exec = NULL; |
| 817 char **argv; | 809 char **argv; |
| 818 struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); | 810 struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); |
| 819 | 811 |
| 820 if (args) | 812 if (args) |
| 821 { | 813 { |
| 822 argv = gdb_buildargv (args); | 814 argv = gdb_buildargv (args); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 exec_file_attach (exec, from_tty); | 857 exec_file_attach (exec, from_tty); |
| 866 symbol_file_add_main (exec, from_tty); | 858 symbol_file_add_main (exec, from_tty); |
| 867 } | 859 } |
| 868 } | 860 } |
| 869 | 861 |
| 870 do_cleanups (old_chain); | 862 do_cleanups (old_chain); |
| 871 } | 863 } |
| 872 | 864 |
| 873 /* clone-inferior [-copies N] [ID] */ | 865 /* clone-inferior [-copies N] [ID] */ |
| 874 | 866 |
| 875 void | 867 static void |
| 876 clone_inferior_command (char *args, int from_tty) | 868 clone_inferior_command (char *args, int from_tty) |
| 877 { | 869 { |
| 878 int i, copies = 1; | 870 int i, copies = 1; |
| 879 char **argv; | 871 char **argv; |
| 880 struct inferior *orginf = NULL; | 872 struct inferior *orginf = NULL; |
| 881 struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); | 873 struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); |
| 882 | 874 |
| 883 if (args) | 875 if (args) |
| 884 { | 876 { |
| 885 argv = gdb_buildargv (args); | 877 argv = gdb_buildargv (args); |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1055 gdb_assert (data->index < inf->num_data); | 1047 gdb_assert (data->index < inf->num_data); |
| 1056 inf->data[data->index] = value; | 1048 inf->data[data->index] = value; |
| 1057 } | 1049 } |
| 1058 | 1050 |
| 1059 void * | 1051 void * |
| 1060 inferior_data (struct inferior *inf, const struct inferior_data *data) | 1052 inferior_data (struct inferior *inf, const struct inferior_data *data) |
| 1061 { | 1053 { |
| 1062 gdb_assert (data->index < inf->num_data); | 1054 gdb_assert (data->index < inf->num_data); |
| 1063 return inf->data[data->index]; | 1055 return inf->data[data->index]; |
| 1064 } | 1056 } |
error: old chunk mismatch |
None
| OLD | NEW |