1/* Multi-process/thread control for GDB, the GNU debugger. 2 3 Copyright (C) 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 4 2000, 2001, 2002, 2003, 2004, 2007 Free Software Foundation, Inc. 5 6 Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA. 7 8 This file is part of GDB. 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 3 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 22 23#include "defs.h" 24#include "symtab.h" 25#include "frame.h" 26#include "inferior.h" 27#include "environ.h" 28#include "value.h" 29#include "target.h" 30#include "gdbthread.h" 31#include "exceptions.h" 32#include "command.h" 33#include "gdbcmd.h" 34#include "regcache.h" 35#include "gdb.h" 36#include "gdb_string.h" 37 38#include <ctype.h> 39#include <sys/types.h> 40#include <signal.h> 41#include "ui-out.h" 42 43/* Definition of struct thread_info exported to gdbthread.h */ 44 45/* Prototypes for exported functions. */ 46 47void _initialize_thread (void); 48 49/* Prototypes for local functions. */ 50 51static struct thread_info *thread_list = NULL; 52static int highest_thread_num; 53 54static struct thread_info *find_thread_id (int num); 55 56static void thread_command (char *tidstr, int from_tty); 57static void thread_apply_all_command (char *, int); 58static int thread_alive (struct thread_info *); 59static void info_threads_command (char *, int); 60static void thread_apply_command (char *, int); 61static void restore_current_thread (ptid_t); 62static void switch_to_thread (ptid_t ptid); 63static void prune_threads (void); 64static struct cleanup *make_cleanup_restore_current_thread (ptid_t, 65 struct frame_id); 66 67void 68delete_step_resume_breakpoint (void *arg) 69{ 70 struct breakpoint **breakpointp = (struct breakpoint **) arg; 71 struct thread_info *tp; 72 73 if (*breakpointp != NULL) 74 { 75 delete_breakpoint (*breakpointp); 76 for (tp = thread_list; tp; tp = tp->next) 77 if (tp->step_resume_breakpoint == *breakpointp) 78 tp->step_resume_breakpoint = NULL; 79 80 *breakpointp = NULL; 81 } 82} 83 84static void 85free_thread (struct thread_info *tp) 86{ 87 /* NOTE: this will take care of any left-over step_resume breakpoints, 88 but not any user-specified thread-specific breakpoints. */ 89 if (tp->step_resume_breakpoint) 90 delete_breakpoint (tp->step_resume_breakpoint); 91 92 /* FIXME: do I ever need to call the back-end to give it a 93 chance at this private data before deleting the thread? */ 94 if (tp->private) 95 xfree (tp->private); 96 97 xfree (tp); 98} 99 100void 101init_thread_list (void) 102{ 103 struct thread_info *tp, *tpnext; 104 105 highest_thread_num = 0; 106 if (!thread_list) 107 return; 108 109 for (tp = thread_list; tp; tp = tpnext) 110 { 111 tpnext = tp->next; 112 free_thread (tp); 113 } 114 115 thread_list = NULL; 116} 117 118/* add_thread now returns a pointer to the new thread_info, 119 so that back_ends can initialize their private data. */ 120 121struct thread_info * 122add_thread (ptid_t ptid) 123{ 124 struct thread_info *tp; 125 126 tp = (struct thread_info *) xmalloc (sizeof (*tp)); 127 memset (tp, 0, sizeof (*tp)); 128 tp->ptid = ptid; 129 tp->num = ++highest_thread_num; 130 tp->next = thread_list; 131 thread_list = tp; 132 return tp; 133} 134 135void 136delete_thread (ptid_t ptid) 137{ 138 struct thread_info *tp, *tpprev; 139 140 tpprev = NULL; 141 142 for (tp = thread_list; tp; tpprev = tp, tp = tp->next) 143 if (ptid_equal (tp->ptid, ptid)) 144 break; 145 146 if (!tp) 147 return; 148 149 if (tpprev) 150 tpprev->next = tp->next; 151 else 152 thread_list = tp->next; 153 154 free_thread (tp); 155} 156 157static struct thread_info * 158find_thread_id (int num) 159{ 160 struct thread_info *tp; 161 162 for (tp = thread_list; tp; tp = tp->next) 163 if (tp->num == num) 164 return tp; 165 166 return NULL; 167} 168 169/* Find a thread_info by matching PTID. */ 170struct thread_info * 171find_thread_pid (ptid_t ptid) 172{ 173 struct thread_info *tp; 174 175 for (tp = thread_list; tp; tp = tp->next) 176 if (ptid_equal (tp->ptid, ptid)) 177 return tp; 178 179 return NULL; 180} 181 182/* 183 * Thread iterator function. 184 * 185 * Calls a callback function once for each thread, so long as 186 * the callback function returns false. If the callback function 187 * returns true, the iteration will end and the current thread 188 * will be returned. This can be useful for implementing a 189 * search for a thread with arbitrary attributes, or for applying 190 * some operation to every thread. 191 * 192 * FIXME: some of the existing functionality, such as 193 * "Thread apply all", might be rewritten using this functionality. 194 */ 195 196struct thread_info * 197iterate_over_threads (int (*callback) (struct thread_info *, void *), 198 void *data) 199{ 200 struct thread_info *tp; 201 202 for (tp = thread_list; tp; tp = tp->next) 203 if ((*callback) (tp, data)) 204 return tp; 205 206 return NULL; 207} 208 209int 210valid_thread_id (int num) 211{ 212 struct thread_info *tp; 213 214 for (tp = thread_list; tp; tp = tp->next) 215 if (tp->num == num) 216 return 1; 217 218 return 0; 219} 220 221int 222pid_to_thread_id (ptid_t ptid) 223{ 224 struct thread_info *tp; 225 226 for (tp = thread_list; tp; tp = tp->next) 227 if (ptid_equal (tp->ptid, ptid)) 228 return tp->num; 229 230 return 0; 231} 232 233ptid_t 234thread_id_to_pid (int num) 235{ 236 struct thread_info *thread = find_thread_id (num); 237 if (thread) 238 return thread->ptid; 239 else 240 return pid_to_ptid (-1); 241} 242 243int 244in_thread_list (ptid_t ptid) 245{ 246 struct thread_info *tp; 247 248 for (tp = thread_list; tp; tp = tp->next) 249 if (ptid_equal (tp->ptid, ptid)) 250 return 1; 251 252 return 0; /* Never heard of 'im */ 253} 254 255/* Print a list of thread ids currently known, and the total number of 256 threads. To be used from within catch_errors. */ 257static int 258do_captured_list_thread_ids (struct ui_out *uiout, void *arg) 259{ 260 struct thread_info *tp; 261 int num = 0; 262 struct cleanup *cleanup_chain; 263 264 prune_threads (); 265 target_find_new_threads (); 266 267 cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids"); 268 269 for (tp = thread_list; tp; tp = tp->next) 270 { 271 num++; 272 ui_out_field_int (uiout, "thread-id", tp->num); 273 } 274 275 do_cleanups (cleanup_chain); 276 ui_out_field_int (uiout, "number-of-threads", num); 277 return GDB_RC_OK; 278} 279 280/* Official gdblib interface function to get a list of thread ids and 281 the total number. */ 282enum gdb_rc 283gdb_list_thread_ids (struct ui_out *uiout, char **error_message) 284{ 285 if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL, 286 error_message, RETURN_MASK_ALL) < 0) 287 return GDB_RC_FAIL; 288 return GDB_RC_OK; 289} 290 291/* Load infrun state for the thread PID. */ 292 293void 294load_infrun_state (ptid_t ptid, 295 CORE_ADDR *prev_pc, 296 int *trap_expected, 297 struct breakpoint **step_resume_breakpoint, 298 CORE_ADDR *step_range_start, 299 CORE_ADDR *step_range_end, 300 struct frame_id *step_frame_id, 301 int *handling_longjmp, 302 int *another_trap, 303 int *stepping_through_solib_after_catch, 304 bpstat *stepping_through_solib_catchpoints, 305 int *current_line, 306 struct symtab **current_symtab) 307{ 308 struct thread_info *tp; 309 310 /* If we can't find the thread, then we're debugging a single threaded 311 process. No need to do anything in that case. */ 312 tp = find_thread_id (pid_to_thread_id (ptid)); 313 if (tp == NULL) 314 return; 315 316 *prev_pc = tp->prev_pc; 317 *trap_expected = tp->trap_expected; 318 *step_resume_breakpoint = tp->step_resume_breakpoint; 319 *step_range_start = tp->step_range_start; 320 *step_range_end = tp->step_range_end; 321 *step_frame_id = tp->step_frame_id; 322 *handling_longjmp = tp->handling_longjmp; 323 *another_trap = tp->another_trap; 324 *stepping_through_solib_after_catch = 325 tp->stepping_through_solib_after_catch; 326 *stepping_through_solib_catchpoints = 327 tp->stepping_through_solib_catchpoints; 328 *current_line = tp->current_line; 329 *current_symtab = tp->current_symtab; 330} 331 332/* Save infrun state for the thread PID. */ 333 334void 335save_infrun_state (ptid_t ptid, 336 CORE_ADDR prev_pc, 337 int trap_expected, 338 struct breakpoint *step_resume_breakpoint, 339 CORE_ADDR step_range_start, 340 CORE_ADDR step_range_end, 341 const struct frame_id *step_frame_id, 342 int handling_longjmp, 343 int another_trap, 344 int stepping_through_solib_after_catch, 345 bpstat stepping_through_solib_catchpoints, 346 int current_line, 347 struct symtab *current_symtab) 348{ 349 struct thread_info *tp; 350 351 /* If we can't find the thread, then we're debugging a single-threaded 352 process. Nothing to do in that case. */ 353 tp = find_thread_id (pid_to_thread_id (ptid)); 354 if (tp == NULL) 355 return; 356 357 tp->prev_pc = prev_pc; 358 tp->trap_expected = trap_expected; 359 tp->step_resume_breakpoint = step_resume_breakpoint; 360 tp->step_range_start = step_range_start; 361 tp->step_range_end = step_range_end; 362 tp->step_frame_id = (*step_frame_id); 363 tp->handling_longjmp = handling_longjmp; 364 tp->another_trap = another_trap; 365 tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch; 366 tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints; 367 tp->current_line = current_line; 368 tp->current_symtab = current_symtab; 369} 370 371/* Return true if TP is an active thread. */ 372static int 373thread_alive (struct thread_info *tp) 374{ 375 if (PIDGET (tp->ptid) == -1) 376 return 0; 377 if (!target_thread_alive (tp->ptid)) 378 { 379 tp->ptid = pid_to_ptid (-1); /* Mark it as dead */ 380 return 0; 381 } 382 return 1; 383} 384 385static void 386prune_threads (void) 387{ 388 struct thread_info *tp, *next; 389 390 for (tp = thread_list; tp; tp = next) 391 { 392 next = tp->next; 393 if (!thread_alive (tp)) 394 delete_thread (tp->ptid); 395 } 396} 397 398/* Print information about currently known threads 399 400 * Note: this has the drawback that it _really_ switches 401 * threads, which frees the frame cache. A no-side 402 * effects info-threads command would be nicer. 403 */ 404 405static void 406info_threads_command (char *arg, int from_tty) 407{ 408 struct thread_info *tp; 409 ptid_t current_ptid; 410 struct frame_info *cur_frame; 411 struct cleanup *old_chain; 412 struct frame_id saved_frame_id; 413 char *extra_info; 414 415 /* Backup current thread and selected frame. */ 416 saved_frame_id = get_frame_id (get_selected_frame (NULL)); 417 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); 418 419 prune_threads (); 420 target_find_new_threads (); 421 current_ptid = inferior_ptid; 422 for (tp = thread_list; tp; tp = tp->next) 423 { 424 if (ptid_equal (tp->ptid, current_ptid)) 425 printf_filtered ("* "); 426 else 427 printf_filtered (" "); 428 429 printf_filtered ("%d %s", tp->num, target_tid_to_str (tp->ptid)); 430 431 extra_info = target_extra_thread_info (tp); 432 if (extra_info) 433 printf_filtered (" (%s)", extra_info); 434 puts_filtered (" "); 435 /* That switch put us at the top of the stack (leaf frame). */ 436 switch_to_thread (tp->ptid); 437 print_stack_frame (get_selected_frame (NULL), 0, LOCATION); 438 } 439 440 /* Restores the current thread and the frame selected before 441 the "info threads" command. */ 442 do_cleanups (old_chain); 443 444 /* If case we were not able to find the original frame, print the 445 new selected frame. */ 446 if (frame_find_by_id (saved_frame_id) == NULL) 447 { 448 warning (_("Couldn't restore frame in current thread, at frame 0")); 449 print_stack_frame (get_selected_frame (NULL), 0, LOCATION); 450 } 451} 452 453/* Switch from one thread to another. */ 454 455static void 456switch_to_thread (ptid_t ptid) 457{ 458 if (ptid_equal (ptid, inferior_ptid)) 459 return; 460 461 inferior_ptid = ptid; 462 reinit_frame_cache (); 463 registers_changed (); 464 stop_pc = read_pc (); 465} 466 467static void 468restore_current_thread (ptid_t ptid) 469{ 470 if (!ptid_equal (ptid, inferior_ptid)) 471 { 472 switch_to_thread (ptid); 473 } 474} 475 476static void 477restore_selected_frame (struct frame_id a_frame_id) 478{ 479 struct frame_info *selected_frame_info = NULL; 480 481 if (frame_id_eq (a_frame_id, null_frame_id)) 482 return; 483 484 if ((selected_frame_info = frame_find_by_id (a_frame_id)) != NULL) 485 { 486 select_frame (selected_frame_info); 487 } 488} 489 490struct current_thread_cleanup 491{ 492 ptid_t inferior_ptid; 493 struct frame_id selected_frame_id; 494}; 495 496static void 497do_restore_current_thread_cleanup (void *arg) 498{ 499 struct current_thread_cleanup *old = arg; 500 restore_current_thread (old->inferior_ptid); 501 restore_selected_frame (old->selected_frame_id); 502 xfree (old); 503} 504 505static struct cleanup * 506make_cleanup_restore_current_thread (ptid_t inferior_ptid, 507 struct frame_id a_frame_id) 508{ 509 struct current_thread_cleanup *old 510 = xmalloc (sizeof (struct current_thread_cleanup)); 511 old->inferior_ptid = inferior_ptid; 512 old->selected_frame_id = a_frame_id; 513 return make_cleanup (do_restore_current_thread_cleanup, old); 514} 515 516/* Apply a GDB command to a list of threads. List syntax is a whitespace 517 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist 518 of two numbers seperated by a hyphen. Examples: 519 520 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4 521 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9 522 thread apply all p x/i $pc Apply x/i $pc cmd to all threads 523 */ 524 525static void 526thread_apply_all_command (char *cmd, int from_tty) 527{ 528 struct thread_info *tp; 529 struct cleanup *old_chain; 530 struct cleanup *saved_cmd_cleanup_chain; 531 char *saved_cmd; 532 struct frame_id saved_frame_id; 533 ptid_t current_ptid; 534 int thread_has_changed = 0; 535 536 if (cmd == NULL || *cmd == '\000') 537 error (_("Please specify a command following the thread ID list")); 538 539 current_ptid = inferior_ptid; 540 saved_frame_id = get_frame_id (get_selected_frame (NULL)); 541 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); 542 543 /* It is safe to update the thread list now, before 544 traversing it for "thread apply all". MVS */ 545 target_find_new_threads (); 546 547 /* Save a copy of the command in case it is clobbered by 548 execute_command */ 549 saved_cmd = xstrdup (cmd); 550 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd); 551 for (tp = thread_list; tp; tp = tp->next) 552 if (thread_alive (tp)) 553 { 554 switch_to_thread (tp->ptid); 555 printf_filtered (_("\nThread %d (%s):\n"), 556 tp->num, target_tid_to_str (inferior_ptid)); 557 execute_command (cmd, from_tty); 558 strcpy (cmd, saved_cmd); /* Restore exact command used previously */ 559 } 560 561 if (!ptid_equal (current_ptid, inferior_ptid)) 562 thread_has_changed = 1; 563 564 do_cleanups (saved_cmd_cleanup_chain); 565 do_cleanups (old_chain); 566 /* Print stack frame only if we changed thread. */ 567 if (thread_has_changed) 568 print_stack_frame (get_current_frame (), 1, SRC_LINE); 569 570} 571 572static void 573thread_apply_command (char *tidlist, int from_tty) 574{ 575 char *cmd; 576 char *p; 577 struct cleanup *old_chain; 578 struct cleanup *saved_cmd_cleanup_chain; 579 char *saved_cmd; 580 struct frame_id saved_frame_id; 581 ptid_t current_ptid; 582 int thread_has_changed = 0; 583 584 if (tidlist == NULL || *tidlist == '\000') 585 error (_("Please specify a thread ID list")); 586 587 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++); 588 589 if (*cmd == '\000') 590 error (_("Please specify a command following the thread ID list")); 591 592 current_ptid = inferior_ptid; 593 saved_frame_id = get_frame_id (get_selected_frame (NULL)); 594 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); 595 596 /* Save a copy of the command in case it is clobbered by 597 execute_command */ 598 saved_cmd = xstrdup (cmd); 599 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd); 600 while (tidlist < cmd) 601 { 602 struct thread_info *tp; 603 int start, end; 604 605 start = strtol (tidlist, &p, 10); 606 if (p == tidlist) 607 error (_("Error parsing %s"), tidlist); 608 tidlist = p; 609 610 while (*tidlist == ' ' || *tidlist == '\t') 611 tidlist++; 612 613 if (*tidlist == '-') /* Got a range of IDs? */ 614 { 615 tidlist++; /* Skip the - */ 616 end = strtol (tidlist, &p, 10); 617 if (p == tidlist) 618 error (_("Error parsing %s"), tidlist); 619 tidlist = p; 620 621 while (*tidlist == ' ' || *tidlist == '\t') 622 tidlist++; 623 } 624 else 625 end = start; 626 627 for (; start <= end; start++) 628 { 629 tp = find_thread_id (start); 630 631 if (!tp) 632 warning (_("Unknown thread %d."), start); 633 else if (!thread_alive (tp)) 634 warning (_("Thread %d has terminated."), start); 635 else 636 { 637 switch_to_thread (tp->ptid); 638 printf_filtered (_("\nThread %d (%s):\n"), tp->num, 639 target_tid_to_str (inferior_ptid)); 640 execute_command (cmd, from_tty); 641 strcpy (cmd, saved_cmd); /* Restore exact command used previously */ 642 } 643 } 644 } 645 646 if (!ptid_equal (current_ptid, inferior_ptid)) 647 thread_has_changed = 1; 648 649 do_cleanups (saved_cmd_cleanup_chain); 650 do_cleanups (old_chain); 651 /* Print stack frame only if we changed thread. */ 652 if (thread_has_changed) 653 print_stack_frame (get_current_frame (), 1, SRC_LINE); 654} 655 656/* Switch to the specified thread. Will dispatch off to thread_apply_command 657 if prefix of arg is `apply'. */ 658 659static void 660thread_command (char *tidstr, int from_tty) 661{ 662 if (!tidstr) 663 { 664 /* Don't generate an error, just say which thread is current. */ 665 if (target_has_stack) 666 printf_filtered (_("[Current thread is %d (%s)]\n"), 667 pid_to_thread_id (inferior_ptid), 668 target_tid_to_str (inferior_ptid)); 669 else 670 error (_("No stack.")); 671 return; 672 } 673 674 gdb_thread_select (uiout, tidstr, NULL); 675} 676 677static int 678do_captured_thread_select (struct ui_out *uiout, void *tidstr) 679{ 680 int num; 681 struct thread_info *tp; 682 683 num = value_as_long (parse_and_eval (tidstr)); 684 685 tp = find_thread_id (num); 686 687 if (!tp) 688 error (_("Thread ID %d not known."), num); 689 690 if (!thread_alive (tp)) 691 error (_("Thread ID %d has terminated."), num); 692 693 switch_to_thread (tp->ptid); 694 695 ui_out_text (uiout, "[Switching to thread "); 696 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid)); 697 ui_out_text (uiout, " ("); 698 ui_out_text (uiout, target_tid_to_str (inferior_ptid)); 699 ui_out_text (uiout, ")]"); 700 701 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); 702 return GDB_RC_OK; 703} 704 705enum gdb_rc 706gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message) 707{ 708 if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr, 709 error_message, RETURN_MASK_ALL) < 0) 710 return GDB_RC_FAIL; 711 return GDB_RC_OK; 712} 713 714/* Commands with a prefix of `thread'. */ 715struct cmd_list_element *thread_cmd_list = NULL; 716 717void 718_initialize_thread (void) 719{ 720 static struct cmd_list_element *thread_apply_list = NULL; 721 722 add_info ("threads", info_threads_command, 723 _("IDs of currently known threads.")); 724 725 add_prefix_cmd ("thread", class_run, thread_command, _("\ 726Use this command to switch between threads.\n\ 727The new thread ID must be currently known."), 728 &thread_cmd_list, "thread ", 1, &cmdlist); 729 730 add_prefix_cmd ("apply", class_run, thread_apply_command, 731 _("Apply a command to a list of threads."), 732 &thread_apply_list, "thread apply ", 1, &thread_cmd_list); 733 734 add_cmd ("all", class_run, thread_apply_all_command, 735 _("Apply a command to all threads."), &thread_apply_list); 736 737 if (!xdb_commands) 738 add_com_alias ("t", "thread", class_run, 1); 739} 740