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