]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/thread.c
*** empty log message ***
[thirdparty/binutils-gdb.git] / gdb / thread.c
CommitLineData
c906108c 1/* Multi-process/thread control for GDB, the GNU debugger.
8926118c 2
6aba47ca
DJ
3 Copyright (C) 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 2000, 2001, 2002, 2003, 2004, 2007 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
a9762ec7 12 the Free Software Foundation; either version 3 of the License, or
c5aa993b 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 20 You should have received a copy of the GNU General Public License
a9762ec7 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
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"
60250e8b 31#include "exceptions.h"
c906108c
SS
32#include "command.h"
33#include "gdbcmd.h"
4e052eda 34#include "regcache.h"
5b7f31a4 35#include "gdb.h"
b66d6d2e 36#include "gdb_string.h"
c906108c
SS
37
38#include <ctype.h>
39#include <sys/types.h>
40#include <signal.h>
8b93c638 41#include "ui-out.h"
c906108c 42
0d06e24b 43/* Definition of struct thread_info exported to gdbthread.h */
c906108c
SS
44
45/* Prototypes for exported functions. */
46
a14ed312 47void _initialize_thread (void);
c906108c
SS
48
49/* Prototypes for local functions. */
50
c906108c
SS
51static struct thread_info *thread_list = NULL;
52static int highest_thread_num;
53
a14ed312 54static struct thread_info *find_thread_id (int num);
c906108c 55
a14ed312
KB
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);
39f77062 61static void restore_current_thread (ptid_t);
a14ed312 62static void prune_threads (void);
99b3d574
DP
63static struct cleanup *make_cleanup_restore_current_thread (ptid_t,
64 struct frame_id);
c906108c 65
8601f500
MS
66void
67delete_step_resume_breakpoint (void *arg)
68{
69 struct breakpoint **breakpointp = (struct breakpoint **) arg;
70 struct thread_info *tp;
71
72 if (*breakpointp != NULL)
73 {
74 delete_breakpoint (*breakpointp);
75 for (tp = thread_list; tp; tp = tp->next)
76 if (tp->step_resume_breakpoint == *breakpointp)
77 tp->step_resume_breakpoint = NULL;
78
79 *breakpointp = NULL;
80 }
81}
82
7c952b6d
ND
83static void
84free_thread (struct thread_info *tp)
85{
86 /* NOTE: this will take care of any left-over step_resume breakpoints,
4d8453a5
DJ
87 but not any user-specified thread-specific breakpoints. We can not
88 delete the breakpoint straight-off, because the inferior might not
89 be stopped at the moment. */
7c952b6d 90 if (tp->step_resume_breakpoint)
4d8453a5 91 tp->step_resume_breakpoint->disposition = disp_del_at_next_stop;
7c952b6d
ND
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
ce43223b 284gdb_list_thread_ids (struct ui_out *uiout, char **error_message)
8b93c638 285{
b0b13bb4
DJ
286 if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL,
287 error_message, RETURN_MASK_ALL) < 0)
288 return GDB_RC_FAIL;
289 return GDB_RC_OK;
8b93c638 290}
c906108c
SS
291
292/* Load infrun state for the thread PID. */
293
c5aa993b 294void
6949171e
JJ
295load_infrun_state (ptid_t ptid,
296 CORE_ADDR *prev_pc,
6c0d3f6a 297 int *trap_expected,
fba45db2 298 struct breakpoint **step_resume_breakpoint,
6949171e 299 CORE_ADDR *step_range_start,
6c0d3f6a 300 CORE_ADDR *step_range_end,
6949171e 301 struct frame_id *step_frame_id,
6c0d3f6a 302 int *handling_longjmp,
6949171e 303 int *another_trap,
6c0d3f6a 304 int *stepping_through_solib_after_catch,
fba45db2 305 bpstat *stepping_through_solib_catchpoints,
6949171e 306 int *current_line,
f2c9ca08 307 struct symtab **current_symtab)
c906108c
SS
308{
309 struct thread_info *tp;
310
311 /* If we can't find the thread, then we're debugging a single threaded
312 process. No need to do anything in that case. */
39f77062 313 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
314 if (tp == NULL)
315 return;
316
317 *prev_pc = tp->prev_pc;
6c0d3f6a 318 *trap_expected = tp->trap_expected;
c906108c
SS
319 *step_resume_breakpoint = tp->step_resume_breakpoint;
320 *step_range_start = tp->step_range_start;
321 *step_range_end = tp->step_range_end;
aa0cd9c1 322 *step_frame_id = tp->step_frame_id;
c906108c 323 *handling_longjmp = tp->handling_longjmp;
c906108c 324 *another_trap = tp->another_trap;
6949171e
JJ
325 *stepping_through_solib_after_catch =
326 tp->stepping_through_solib_after_catch;
327 *stepping_through_solib_catchpoints =
328 tp->stepping_through_solib_catchpoints;
6c0d3f6a
MS
329 *current_line = tp->current_line;
330 *current_symtab = tp->current_symtab;
c906108c
SS
331}
332
333/* Save infrun state for the thread PID. */
334
c5aa993b 335void
6949171e
JJ
336save_infrun_state (ptid_t ptid,
337 CORE_ADDR prev_pc,
6c0d3f6a 338 int trap_expected,
fba45db2 339 struct breakpoint *step_resume_breakpoint,
6949171e 340 CORE_ADDR step_range_start,
6c0d3f6a 341 CORE_ADDR step_range_end,
6949171e 342 const struct frame_id *step_frame_id,
6c0d3f6a 343 int handling_longjmp,
6949171e 344 int another_trap,
6c0d3f6a 345 int stepping_through_solib_after_catch,
fba45db2 346 bpstat stepping_through_solib_catchpoints,
6c0d3f6a 347 int current_line,
f2c9ca08 348 struct symtab *current_symtab)
c906108c
SS
349{
350 struct thread_info *tp;
351
352 /* If we can't find the thread, then we're debugging a single-threaded
353 process. Nothing to do in that case. */
39f77062 354 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
355 if (tp == NULL)
356 return;
357
358 tp->prev_pc = prev_pc;
6c0d3f6a 359 tp->trap_expected = trap_expected;
c906108c
SS
360 tp->step_resume_breakpoint = step_resume_breakpoint;
361 tp->step_range_start = step_range_start;
362 tp->step_range_end = step_range_end;
aa0cd9c1 363 tp->step_frame_id = (*step_frame_id);
c906108c 364 tp->handling_longjmp = handling_longjmp;
c906108c
SS
365 tp->another_trap = another_trap;
366 tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
367 tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
6c0d3f6a
MS
368 tp->current_line = current_line;
369 tp->current_symtab = current_symtab;
c906108c
SS
370}
371
372/* Return true if TP is an active thread. */
373static int
fba45db2 374thread_alive (struct thread_info *tp)
c906108c 375{
39f77062 376 if (PIDGET (tp->ptid) == -1)
c906108c 377 return 0;
39f77062 378 if (!target_thread_alive (tp->ptid))
c906108c 379 {
39f77062 380 tp->ptid = pid_to_ptid (-1); /* Mark it as dead */
c906108c
SS
381 return 0;
382 }
383 return 1;
384}
385
386static void
fba45db2 387prune_threads (void)
c906108c 388{
d4f3574e 389 struct thread_info *tp, *next;
c906108c 390
c906108c
SS
391 for (tp = thread_list; tp; tp = next)
392 {
393 next = tp->next;
394 if (!thread_alive (tp))
39f77062 395 delete_thread (tp->ptid);
c906108c
SS
396 }
397}
398
399/* Print information about currently known threads
c5aa993b 400
c906108c
SS
401 * Note: this has the drawback that it _really_ switches
402 * threads, which frees the frame cache. A no-side
403 * effects info-threads command would be nicer.
404 */
405
406static void
fba45db2 407info_threads_command (char *arg, int from_tty)
c906108c
SS
408{
409 struct thread_info *tp;
39f77062 410 ptid_t current_ptid;
c5aa993b 411 struct frame_info *cur_frame;
99b3d574
DP
412 struct cleanup *old_chain;
413 struct frame_id saved_frame_id;
0d06e24b 414 char *extra_info;
c906108c 415
99b3d574
DP
416 /* Backup current thread and selected frame. */
417 saved_frame_id = get_frame_id (get_selected_frame (NULL));
418 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
419
c906108c 420 prune_threads ();
b83266a0 421 target_find_new_threads ();
39f77062 422 current_ptid = inferior_ptid;
c906108c
SS
423 for (tp = thread_list; tp; tp = tp->next)
424 {
39f77062 425 if (ptid_equal (tp->ptid, current_ptid))
c906108c
SS
426 printf_filtered ("* ");
427 else
428 printf_filtered (" ");
429
39f77062 430 printf_filtered ("%d %s", tp->num, target_tid_to_str (tp->ptid));
0d06e24b
JM
431
432 extra_info = target_extra_thread_info (tp);
433 if (extra_info)
434 printf_filtered (" (%s)", extra_info);
435 puts_filtered (" ");
99b3d574 436 /* That switch put us at the top of the stack (leaf frame). */
39f77062 437 switch_to_thread (tp->ptid);
b04f3ab4 438 print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
c906108c
SS
439 }
440
99b3d574
DP
441 /* Restores the current thread and the frame selected before
442 the "info threads" command. */
443 do_cleanups (old_chain);
c906108c 444
99b3d574
DP
445 /* If case we were not able to find the original frame, print the
446 new selected frame. */
447 if (frame_find_by_id (saved_frame_id) == NULL)
c906108c 448 {
8a3fe4f8 449 warning (_("Couldn't restore frame in current thread, at frame 0"));
b04f3ab4 450 print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
c906108c 451 }
c906108c
SS
452}
453
454/* Switch from one thread to another. */
455
6a6b96b9 456void
39f77062 457switch_to_thread (ptid_t ptid)
c906108c 458{
39f77062 459 if (ptid_equal (ptid, inferior_ptid))
c906108c
SS
460 return;
461
39f77062 462 inferior_ptid = ptid;
35f196d9 463 reinit_frame_cache ();
c906108c 464 registers_changed ();
c5aa993b 465 stop_pc = read_pc ();
c906108c
SS
466}
467
468static void
39f77062 469restore_current_thread (ptid_t ptid)
c906108c 470{
6949171e 471 if (!ptid_equal (ptid, inferior_ptid))
c906108c 472 {
39f77062 473 switch_to_thread (ptid);
99b3d574
DP
474 }
475}
476
477static void
478restore_selected_frame (struct frame_id a_frame_id)
479{
480 struct frame_info *selected_frame_info = NULL;
481
482 if (frame_id_eq (a_frame_id, null_frame_id))
483 return;
484
485 if ((selected_frame_info = frame_find_by_id (a_frame_id)) != NULL)
486 {
487 select_frame (selected_frame_info);
c906108c
SS
488 }
489}
490
6ecce94d
AC
491struct current_thread_cleanup
492{
39f77062 493 ptid_t inferior_ptid;
99b3d574 494 struct frame_id selected_frame_id;
6ecce94d
AC
495};
496
497static void
498do_restore_current_thread_cleanup (void *arg)
499{
500 struct current_thread_cleanup *old = arg;
39f77062 501 restore_current_thread (old->inferior_ptid);
99b3d574 502 restore_selected_frame (old->selected_frame_id);
b8c9b27d 503 xfree (old);
6ecce94d
AC
504}
505
506static struct cleanup *
99b3d574
DP
507make_cleanup_restore_current_thread (ptid_t inferior_ptid,
508 struct frame_id a_frame_id)
6ecce94d
AC
509{
510 struct current_thread_cleanup *old
511 = xmalloc (sizeof (struct current_thread_cleanup));
39f77062 512 old->inferior_ptid = inferior_ptid;
99b3d574 513 old->selected_frame_id = a_frame_id;
6ecce94d
AC
514 return make_cleanup (do_restore_current_thread_cleanup, old);
515}
516
c906108c
SS
517/* Apply a GDB command to a list of threads. List syntax is a whitespace
518 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
519 of two numbers seperated by a hyphen. Examples:
520
c5aa993b
JM
521 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
522 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
523 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
524 */
c906108c
SS
525
526static void
fba45db2 527thread_apply_all_command (char *cmd, int from_tty)
c906108c
SS
528{
529 struct thread_info *tp;
530 struct cleanup *old_chain;
e35ce267
CF
531 struct cleanup *saved_cmd_cleanup_chain;
532 char *saved_cmd;
99b3d574
DP
533 struct frame_id saved_frame_id;
534 ptid_t current_ptid;
535 int thread_has_changed = 0;
c906108c
SS
536
537 if (cmd == NULL || *cmd == '\000')
8a3fe4f8 538 error (_("Please specify a command following the thread ID list"));
99b3d574
DP
539
540 current_ptid = inferior_ptid;
541 saved_frame_id = get_frame_id (get_selected_frame (NULL));
542 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 543
e9d196c5
MS
544 /* It is safe to update the thread list now, before
545 traversing it for "thread apply all". MVS */
546 target_find_new_threads ();
547
e35ce267
CF
548 /* Save a copy of the command in case it is clobbered by
549 execute_command */
5b616ba1 550 saved_cmd = xstrdup (cmd);
b8c9b27d 551 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
552 for (tp = thread_list; tp; tp = tp->next)
553 if (thread_alive (tp))
554 {
39f77062 555 switch_to_thread (tp->ptid);
a3f17187 556 printf_filtered (_("\nThread %d (%s):\n"),
6949171e 557 tp->num, target_tid_to_str (inferior_ptid));
c906108c 558 execute_command (cmd, from_tty);
6949171e 559 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c 560 }
6ecce94d 561
99b3d574
DP
562 if (!ptid_equal (current_ptid, inferior_ptid))
563 thread_has_changed = 1;
564
e35ce267 565 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 566 do_cleanups (old_chain);
99b3d574
DP
567 /* Print stack frame only if we changed thread. */
568 if (thread_has_changed)
569 print_stack_frame (get_current_frame (), 1, SRC_LINE);
570
c906108c
SS
571}
572
573static void
fba45db2 574thread_apply_command (char *tidlist, int from_tty)
c906108c
SS
575{
576 char *cmd;
577 char *p;
578 struct cleanup *old_chain;
e35ce267
CF
579 struct cleanup *saved_cmd_cleanup_chain;
580 char *saved_cmd;
99b3d574
DP
581 struct frame_id saved_frame_id;
582 ptid_t current_ptid;
583 int thread_has_changed = 0;
c906108c
SS
584
585 if (tidlist == NULL || *tidlist == '\000')
8a3fe4f8 586 error (_("Please specify a thread ID list"));
c906108c 587
c5aa993b 588 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
589
590 if (*cmd == '\000')
8a3fe4f8 591 error (_("Please specify a command following the thread ID list"));
c906108c 592
99b3d574
DP
593 current_ptid = inferior_ptid;
594 saved_frame_id = get_frame_id (get_selected_frame (NULL));
595 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 596
e35ce267
CF
597 /* Save a copy of the command in case it is clobbered by
598 execute_command */
5b616ba1 599 saved_cmd = xstrdup (cmd);
b8c9b27d 600 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
601 while (tidlist < cmd)
602 {
603 struct thread_info *tp;
604 int start, end;
605
606 start = strtol (tidlist, &p, 10);
607 if (p == tidlist)
8a3fe4f8 608 error (_("Error parsing %s"), tidlist);
c906108c
SS
609 tidlist = p;
610
611 while (*tidlist == ' ' || *tidlist == '\t')
612 tidlist++;
613
614 if (*tidlist == '-') /* Got a range of IDs? */
615 {
c5aa993b 616 tidlist++; /* Skip the - */
c906108c
SS
617 end = strtol (tidlist, &p, 10);
618 if (p == tidlist)
8a3fe4f8 619 error (_("Error parsing %s"), tidlist);
c906108c
SS
620 tidlist = p;
621
622 while (*tidlist == ' ' || *tidlist == '\t')
623 tidlist++;
624 }
625 else
626 end = start;
627
628 for (; start <= end; start++)
629 {
630 tp = find_thread_id (start);
631
632 if (!tp)
8a3fe4f8 633 warning (_("Unknown thread %d."), start);
c906108c 634 else if (!thread_alive (tp))
8a3fe4f8 635 warning (_("Thread %d has terminated."), start);
c906108c
SS
636 else
637 {
39f77062 638 switch_to_thread (tp->ptid);
a3f17187 639 printf_filtered (_("\nThread %d (%s):\n"), tp->num,
39f77062 640 target_tid_to_str (inferior_ptid));
c906108c 641 execute_command (cmd, from_tty);
e35ce267 642 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c
SS
643 }
644 }
645 }
6ecce94d 646
99b3d574
DP
647 if (!ptid_equal (current_ptid, inferior_ptid))
648 thread_has_changed = 1;
649
e35ce267 650 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 651 do_cleanups (old_chain);
99b3d574
DP
652 /* Print stack frame only if we changed thread. */
653 if (thread_has_changed)
654 print_stack_frame (get_current_frame (), 1, SRC_LINE);
c906108c
SS
655}
656
657/* Switch to the specified thread. Will dispatch off to thread_apply_command
658 if prefix of arg is `apply'. */
659
660static void
fba45db2 661thread_command (char *tidstr, int from_tty)
c906108c 662{
c906108c
SS
663 if (!tidstr)
664 {
665 /* Don't generate an error, just say which thread is current. */
666 if (target_has_stack)
a3f17187 667 printf_filtered (_("[Current thread is %d (%s)]\n"),
39f77062 668 pid_to_thread_id (inferior_ptid),
007d08bb 669 target_tid_to_str (inferior_ptid));
c906108c 670 else
8a3fe4f8 671 error (_("No stack."));
c906108c
SS
672 return;
673 }
c5394b80 674
ce43223b 675 gdb_thread_select (uiout, tidstr, NULL);
c5394b80
JM
676}
677
678static int
6949171e 679do_captured_thread_select (struct ui_out *uiout, void *tidstr)
c5394b80
JM
680{
681 int num;
682 struct thread_info *tp;
683
81490ea1 684 num = value_as_long (parse_and_eval (tidstr));
c906108c
SS
685
686 tp = find_thread_id (num);
687
8b93c638 688 if (!tp)
8a3fe4f8 689 error (_("Thread ID %d not known."), num);
c906108c
SS
690
691 if (!thread_alive (tp))
8a3fe4f8 692 error (_("Thread ID %d has terminated."), num);
c906108c 693
39f77062 694 switch_to_thread (tp->ptid);
c906108c 695
8b93c638 696 ui_out_text (uiout, "[Switching to thread ");
39f77062 697 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
8b93c638 698 ui_out_text (uiout, " (");
39f77062 699 ui_out_text (uiout, target_tid_to_str (inferior_ptid));
8b93c638 700 ui_out_text (uiout, ")]");
c5394b80 701
b04f3ab4 702 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
c5394b80
JM
703 return GDB_RC_OK;
704}
705
706enum gdb_rc
ce43223b 707gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
c5394b80 708{
b0b13bb4
DJ
709 if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr,
710 error_message, RETURN_MASK_ALL) < 0)
711 return GDB_RC_FAIL;
712 return GDB_RC_OK;
c906108c
SS
713}
714
715/* Commands with a prefix of `thread'. */
716struct cmd_list_element *thread_cmd_list = NULL;
717
718void
fba45db2 719_initialize_thread (void)
c906108c
SS
720{
721 static struct cmd_list_element *thread_apply_list = NULL;
c906108c
SS
722
723 add_info ("threads", info_threads_command,
1bedd215 724 _("IDs of currently known threads."));
c906108c 725
1bedd215
AC
726 add_prefix_cmd ("thread", class_run, thread_command, _("\
727Use this command to switch between threads.\n\
728The new thread ID must be currently known."),
729 &thread_cmd_list, "thread ", 1, &cmdlist);
c906108c
SS
730
731 add_prefix_cmd ("apply", class_run, thread_apply_command,
1bedd215 732 _("Apply a command to a list of threads."),
ad21ceb0 733 &thread_apply_list, "thread apply ", 1, &thread_cmd_list);
c906108c
SS
734
735 add_cmd ("all", class_run, thread_apply_all_command,
1a966eab 736 _("Apply a command to all threads."), &thread_apply_list);
c906108c
SS
737
738 if (!xdb_commands)
739 add_com_alias ("t", "thread", class_run, 1);
740}