]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/thread.c
Index: sh/ChangeLog
[thirdparty/binutils-gdb.git] / gdb / thread.c
CommitLineData
c906108c 1/* Multi-process/thread control for GDB, the GNU debugger.
8926118c
AC
2
3 Copyright 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998,
7789d0fa 4 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
8926118c 5
b6ba6518 6 Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
c906108c 7
c5aa993b 8 This file is part of GDB.
c906108c 9
c5aa993b
JM
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.
c906108c 14
c5aa993b
JM
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.
c906108c 19
c5aa993b
JM
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. */
c906108c
SS
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"
4e052eda 35#include "regcache.h"
5b7f31a4 36#include "gdb.h"
b66d6d2e 37#include "gdb_string.h"
c906108c
SS
38
39#include <ctype.h>
40#include <sys/types.h>
41#include <signal.h>
8b93c638 42#include "ui-out.h"
c906108c 43
c5aa993b 44/*#include "lynxos-core.h" */
c906108c 45
0d06e24b 46/* Definition of struct thread_info exported to gdbthread.h */
c906108c
SS
47
48/* Prototypes for exported functions. */
49
a14ed312 50void _initialize_thread (void);
c906108c
SS
51
52/* Prototypes for local functions. */
53
c906108c
SS
54static struct thread_info *thread_list = NULL;
55static int highest_thread_num;
56
a14ed312 57static struct thread_info *find_thread_id (int num);
c906108c 58
a14ed312
KB
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);
39f77062
KB
64static void restore_current_thread (ptid_t);
65static void switch_to_thread (ptid_t ptid);
a14ed312 66static void prune_threads (void);
c906108c 67
8601f500
MS
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
7c952b6d
ND
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)
b8c9b27d 96 xfree (tp->private);
7c952b6d 97
b8c9b27d 98 xfree (tp);
7c952b6d
ND
99}
100
c906108c 101void
fba45db2 102init_thread_list (void)
c906108c
SS
103{
104 struct thread_info *tp, *tpnext;
105
7c952b6d 106 highest_thread_num = 0;
c906108c
SS
107 if (!thread_list)
108 return;
109
110 for (tp = thread_list; tp; tp = tpnext)
111 {
112 tpnext = tp->next;
7c952b6d 113 free_thread (tp);
c906108c
SS
114 }
115
116 thread_list = NULL;
c906108c
SS
117}
118
0d06e24b
JM
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 *
39f77062 123add_thread (ptid_t ptid)
c906108c
SS
124{
125 struct thread_info *tp;
126
6c0d3f6a
MS
127 tp = (struct thread_info *) xmalloc (sizeof (*tp));
128 memset (tp, 0, sizeof (*tp));
39f77062 129 tp->ptid = ptid;
c906108c 130 tp->num = ++highest_thread_num;
c906108c
SS
131 tp->next = thread_list;
132 thread_list = tp;
0d06e24b 133 return tp;
c906108c
SS
134}
135
136void
39f77062 137delete_thread (ptid_t ptid)
c906108c
SS
138{
139 struct thread_info *tp, *tpprev;
140
141 tpprev = NULL;
142
143 for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
39f77062 144 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
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
7c952b6d 155 free_thread (tp);
c906108c
SS
156}
157
158static struct thread_info *
fba45db2 159find_thread_id (int num)
c906108c
SS
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
39f77062 170/* Find a thread_info by matching PTID. */
0d06e24b 171struct thread_info *
39f77062 172find_thread_pid (ptid_t ptid)
0d06e24b
JM
173{
174 struct thread_info *tp;
175
176 for (tp = thread_list; tp; tp = tp->next)
39f77062 177 if (ptid_equal (tp->ptid, ptid))
0d06e24b
JM
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 *
fd118b61
KB
198iterate_over_threads (int (*callback) (struct thread_info *, void *),
199 void *data)
0d06e24b
JM
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
c906108c 210int
fba45db2 211valid_thread_id (int num)
c906108c
SS
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
39f77062 223pid_to_thread_id (ptid_t ptid)
c906108c
SS
224{
225 struct thread_info *tp;
226
227 for (tp = thread_list; tp; tp = tp->next)
39f77062 228 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
229 return tp->num;
230
231 return 0;
232}
233
39f77062 234ptid_t
fba45db2 235thread_id_to_pid (int num)
c906108c
SS
236{
237 struct thread_info *thread = find_thread_id (num);
238 if (thread)
39f77062 239 return thread->ptid;
c906108c 240 else
39f77062 241 return pid_to_ptid (-1);
c906108c
SS
242}
243
244int
39f77062 245in_thread_list (ptid_t ptid)
c906108c
SS
246{
247 struct thread_info *tp;
248
249 for (tp = thread_list; tp; tp = tp->next)
39f77062 250 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
251 return 1;
252
253 return 0; /* Never heard of 'im */
254}
8926118c 255
8b93c638
JM
256/* Print a list of thread ids currently known, and the total number of
257 threads. To be used from within catch_errors. */
6949171e
JJ
258static int
259do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
8b93c638
JM
260{
261 struct thread_info *tp;
262 int num = 0;
3b31d625 263 struct cleanup *cleanup_chain;
8b93c638 264
7990a578
EZ
265 prune_threads ();
266 target_find_new_threads ();
267
3b31d625 268 cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids");
8b93c638
JM
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
3b31d625 276 do_cleanups (cleanup_chain);
8b93c638
JM
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
2b65245e 284gdb_list_thread_ids (struct ui_out *uiout)
8b93c638 285{
2b65245e
AC
286 return catch_exceptions (uiout, do_captured_list_thread_ids, NULL,
287 NULL, RETURN_MASK_ALL);
8b93c638 288}
c906108c
SS
289
290/* Load infrun state for the thread PID. */
291
c5aa993b 292void
6949171e
JJ
293load_infrun_state (ptid_t ptid,
294 CORE_ADDR *prev_pc,
6c0d3f6a 295 int *trap_expected,
fba45db2 296 struct breakpoint **step_resume_breakpoint,
6949171e 297 CORE_ADDR *step_range_start,
6c0d3f6a 298 CORE_ADDR *step_range_end,
6949171e 299 struct frame_id *step_frame_id,
6c0d3f6a 300 int *handling_longjmp,
6949171e 301 int *another_trap,
6c0d3f6a 302 int *stepping_through_solib_after_catch,
fba45db2 303 bpstat *stepping_through_solib_catchpoints,
6949171e 304 int *current_line,
f2c9ca08 305 struct symtab **current_symtab)
c906108c
SS
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. */
39f77062 311 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
312 if (tp == NULL)
313 return;
314
315 *prev_pc = tp->prev_pc;
6c0d3f6a 316 *trap_expected = tp->trap_expected;
c906108c
SS
317 *step_resume_breakpoint = tp->step_resume_breakpoint;
318 *step_range_start = tp->step_range_start;
319 *step_range_end = tp->step_range_end;
aa0cd9c1 320 *step_frame_id = tp->step_frame_id;
c906108c 321 *handling_longjmp = tp->handling_longjmp;
c906108c 322 *another_trap = tp->another_trap;
6949171e
JJ
323 *stepping_through_solib_after_catch =
324 tp->stepping_through_solib_after_catch;
325 *stepping_through_solib_catchpoints =
326 tp->stepping_through_solib_catchpoints;
6c0d3f6a
MS
327 *current_line = tp->current_line;
328 *current_symtab = tp->current_symtab;
c906108c
SS
329}
330
331/* Save infrun state for the thread PID. */
332
c5aa993b 333void
6949171e
JJ
334save_infrun_state (ptid_t ptid,
335 CORE_ADDR prev_pc,
6c0d3f6a 336 int trap_expected,
fba45db2 337 struct breakpoint *step_resume_breakpoint,
6949171e 338 CORE_ADDR step_range_start,
6c0d3f6a 339 CORE_ADDR step_range_end,
6949171e 340 const struct frame_id *step_frame_id,
6c0d3f6a 341 int handling_longjmp,
6949171e 342 int another_trap,
6c0d3f6a 343 int stepping_through_solib_after_catch,
fba45db2 344 bpstat stepping_through_solib_catchpoints,
6c0d3f6a 345 int current_line,
f2c9ca08 346 struct symtab *current_symtab)
c906108c
SS
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. */
39f77062 352 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
353 if (tp == NULL)
354 return;
355
356 tp->prev_pc = prev_pc;
6c0d3f6a 357 tp->trap_expected = trap_expected;
c906108c
SS
358 tp->step_resume_breakpoint = step_resume_breakpoint;
359 tp->step_range_start = step_range_start;
360 tp->step_range_end = step_range_end;
aa0cd9c1 361 tp->step_frame_id = (*step_frame_id);
c906108c 362 tp->handling_longjmp = handling_longjmp;
c906108c
SS
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;
6c0d3f6a
MS
366 tp->current_line = current_line;
367 tp->current_symtab = current_symtab;
c906108c
SS
368}
369
370/* Return true if TP is an active thread. */
371static int
fba45db2 372thread_alive (struct thread_info *tp)
c906108c 373{
39f77062 374 if (PIDGET (tp->ptid) == -1)
c906108c 375 return 0;
39f77062 376 if (!target_thread_alive (tp->ptid))
c906108c 377 {
39f77062 378 tp->ptid = pid_to_ptid (-1); /* Mark it as dead */
c906108c
SS
379 return 0;
380 }
381 return 1;
382}
383
384static void
fba45db2 385prune_threads (void)
c906108c 386{
d4f3574e 387 struct thread_info *tp, *next;
c906108c 388
c906108c
SS
389 for (tp = thread_list; tp; tp = next)
390 {
391 next = tp->next;
392 if (!thread_alive (tp))
39f77062 393 delete_thread (tp->ptid);
c906108c
SS
394 }
395}
396
397/* Print information about currently known threads
c5aa993b 398
c906108c
SS
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
fba45db2 405info_threads_command (char *arg, int from_tty)
c906108c
SS
406{
407 struct thread_info *tp;
39f77062 408 ptid_t current_ptid;
c5aa993b 409 struct frame_info *cur_frame;
b04f3ab4 410 struct frame_id saved_frame_id = get_frame_id (get_selected_frame (NULL));
0d06e24b 411 char *extra_info;
c906108c 412
c906108c 413 prune_threads ();
b83266a0 414 target_find_new_threads ();
39f77062 415 current_ptid = inferior_ptid;
c906108c
SS
416 for (tp = thread_list; tp; tp = tp->next)
417 {
39f77062 418 if (ptid_equal (tp->ptid, current_ptid))
c906108c
SS
419 printf_filtered ("* ");
420 else
421 printf_filtered (" ");
422
39f77062 423 printf_filtered ("%d %s", tp->num, target_tid_to_str (tp->ptid));
0d06e24b
JM
424
425 extra_info = target_extra_thread_info (tp);
426 if (extra_info)
427 printf_filtered (" (%s)", extra_info);
428 puts_filtered (" ");
429
39f77062 430 switch_to_thread (tp->ptid);
b04f3ab4 431 print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
c906108c
SS
432 }
433
39f77062 434 switch_to_thread (current_ptid);
c906108c 435
7789d0fa
AC
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)
c906108c 442 {
7789d0fa 443 /* Ooops, can't restore, tell user where we are. */
c906108c 444 warning ("Couldn't restore frame in current thread, at frame 0");
b04f3ab4 445 print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
c906108c
SS
446 }
447 else
448 {
0f7d239c 449 select_frame (cur_frame);
7789d0fa
AC
450 /* re-show current frame. */
451 show_stack_frame (cur_frame);
c906108c 452 }
c906108c
SS
453}
454
455/* Switch from one thread to another. */
456
457static void
39f77062 458switch_to_thread (ptid_t ptid)
c906108c 459{
39f77062 460 if (ptid_equal (ptid, inferior_ptid))
c906108c
SS
461 return;
462
39f77062 463 inferior_ptid = ptid;
c906108c
SS
464 flush_cached_frames ();
465 registers_changed ();
c5aa993b 466 stop_pc = read_pc ();
0f7d239c 467 select_frame (get_current_frame ());
c906108c
SS
468}
469
470static void
39f77062 471restore_current_thread (ptid_t ptid)
c906108c 472{
6949171e 473 if (!ptid_equal (ptid, inferior_ptid))
c906108c 474 {
39f77062 475 switch_to_thread (ptid);
0faf0076 476 print_stack_frame (get_current_frame (), 1, SRC_LINE);
c906108c
SS
477 }
478}
479
6ecce94d
AC
480struct current_thread_cleanup
481{
39f77062 482 ptid_t inferior_ptid;
6ecce94d
AC
483};
484
485static void
486do_restore_current_thread_cleanup (void *arg)
487{
488 struct current_thread_cleanup *old = arg;
39f77062 489 restore_current_thread (old->inferior_ptid);
b8c9b27d 490 xfree (old);
6ecce94d
AC
491}
492
493static struct cleanup *
39f77062 494make_cleanup_restore_current_thread (ptid_t inferior_ptid)
6ecce94d
AC
495{
496 struct current_thread_cleanup *old
497 = xmalloc (sizeof (struct current_thread_cleanup));
39f77062 498 old->inferior_ptid = inferior_ptid;
6ecce94d
AC
499 return make_cleanup (do_restore_current_thread_cleanup, old);
500}
501
c906108c
SS
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
c5aa993b
JM
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 */
c906108c
SS
510
511static void
fba45db2 512thread_apply_all_command (char *cmd, int from_tty)
c906108c
SS
513{
514 struct thread_info *tp;
515 struct cleanup *old_chain;
e35ce267
CF
516 struct cleanup *saved_cmd_cleanup_chain;
517 char *saved_cmd;
c906108c
SS
518
519 if (cmd == NULL || *cmd == '\000')
520 error ("Please specify a command following the thread ID list");
521
39f77062 522 old_chain = make_cleanup_restore_current_thread (inferior_ptid);
c906108c 523
e9d196c5
MS
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
e35ce267
CF
528 /* Save a copy of the command in case it is clobbered by
529 execute_command */
5b616ba1 530 saved_cmd = xstrdup (cmd);
b8c9b27d 531 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
532 for (tp = thread_list; tp; tp = tp->next)
533 if (thread_alive (tp))
534 {
39f77062 535 switch_to_thread (tp->ptid);
c906108c 536 printf_filtered ("\nThread %d (%s):\n",
6949171e 537 tp->num, target_tid_to_str (inferior_ptid));
c906108c 538 execute_command (cmd, from_tty);
6949171e 539 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c 540 }
6ecce94d 541
e35ce267 542 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 543 do_cleanups (old_chain);
c906108c
SS
544}
545
546static void
fba45db2 547thread_apply_command (char *tidlist, int from_tty)
c906108c
SS
548{
549 char *cmd;
550 char *p;
551 struct cleanup *old_chain;
e35ce267
CF
552 struct cleanup *saved_cmd_cleanup_chain;
553 char *saved_cmd;
c906108c
SS
554
555 if (tidlist == NULL || *tidlist == '\000')
556 error ("Please specify a thread ID list");
557
c5aa993b 558 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
559
560 if (*cmd == '\000')
561 error ("Please specify a command following the thread ID list");
562
39f77062 563 old_chain = make_cleanup_restore_current_thread (inferior_ptid);
c906108c 564
e35ce267
CF
565 /* Save a copy of the command in case it is clobbered by
566 execute_command */
5b616ba1 567 saved_cmd = xstrdup (cmd);
b8c9b27d 568 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
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 {
c5aa993b 584 tidlist++; /* Skip the - */
c906108c
SS
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 {
39f77062 606 switch_to_thread (tp->ptid);
c906108c 607 printf_filtered ("\nThread %d (%s):\n", tp->num,
39f77062 608 target_tid_to_str (inferior_ptid));
c906108c 609 execute_command (cmd, from_tty);
e35ce267 610 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c
SS
611 }
612 }
613 }
6ecce94d 614
e35ce267 615 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 616 do_cleanups (old_chain);
c906108c
SS
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
fba45db2 623thread_command (char *tidstr, int from_tty)
c906108c 624{
c906108c
SS
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",
39f77062 630 pid_to_thread_id (inferior_ptid),
007d08bb 631 target_tid_to_str (inferior_ptid));
c906108c
SS
632 else
633 error ("No stack.");
634 return;
635 }
c5394b80 636
2b65245e 637 gdb_thread_select (uiout, tidstr);
c5394b80
JM
638}
639
640static int
6949171e 641do_captured_thread_select (struct ui_out *uiout, void *tidstr)
c5394b80
JM
642{
643 int num;
644 struct thread_info *tp;
645
81490ea1 646 num = value_as_long (parse_and_eval (tidstr));
c906108c
SS
647
648 tp = find_thread_id (num);
649
8b93c638
JM
650 if (!tp)
651 error ("Thread ID %d not known.", num);
c906108c
SS
652
653 if (!thread_alive (tp))
654 error ("Thread ID %d has terminated.\n", num);
655
39f77062 656 switch_to_thread (tp->ptid);
c906108c 657
8b93c638 658 ui_out_text (uiout, "[Switching to thread ");
39f77062 659 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
8b93c638 660 ui_out_text (uiout, " (");
39f77062 661 ui_out_text (uiout, target_tid_to_str (inferior_ptid));
8b93c638 662 ui_out_text (uiout, ")]");
c5394b80 663
b04f3ab4 664 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
c5394b80
JM
665 return GDB_RC_OK;
666}
667
668enum gdb_rc
6949171e 669gdb_thread_select (struct ui_out *uiout, char *tidstr)
c5394b80 670{
2b65245e
AC
671 return catch_exceptions (uiout, do_captured_thread_select, tidstr,
672 NULL, RETURN_MASK_ALL);
c906108c
SS
673}
674
675/* Commands with a prefix of `thread'. */
676struct cmd_list_element *thread_cmd_list = NULL;
677
678void
fba45db2 679_initialize_thread (void)
c906108c
SS
680{
681 static struct cmd_list_element *thread_apply_list = NULL;
c906108c
SS
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\
6949171e 688The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1, &cmdlist);
c906108c
SS
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,
6949171e 695 "Apply a command to all threads.", &thread_apply_list);
c906108c
SS
696
697 if (!xdb_commands)
698 add_com_alias ("t", "thread", class_run, 1);
699}