2004-08-02 Andrew Cagney <cagney@gnu.org>
[deliverable/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,
6c0d3f6a 304 int *stepping_through_sigtramp,
6949171e 305 int *current_line,
f2c9ca08 306 struct symtab **current_symtab)
c906108c
SS
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. */
39f77062 312 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
313 if (tp == NULL)
314 return;
315
316 *prev_pc = tp->prev_pc;
6c0d3f6a 317 *trap_expected = tp->trap_expected;
c906108c
SS
318 *step_resume_breakpoint = tp->step_resume_breakpoint;
319 *step_range_start = tp->step_range_start;
320 *step_range_end = tp->step_range_end;
aa0cd9c1 321 *step_frame_id = tp->step_frame_id;
c906108c 322 *handling_longjmp = tp->handling_longjmp;
c906108c 323 *another_trap = tp->another_trap;
6949171e
JJ
324 *stepping_through_solib_after_catch =
325 tp->stepping_through_solib_after_catch;
326 *stepping_through_solib_catchpoints =
327 tp->stepping_through_solib_catchpoints;
c906108c 328 *stepping_through_sigtramp = tp->stepping_through_sigtramp;
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,
6949171e 347 int stepping_through_sigtramp,
6c0d3f6a 348 int current_line,
f2c9ca08 349 struct symtab *current_symtab)
c906108c
SS
350{
351 struct thread_info *tp;
352
353 /* If we can't find the thread, then we're debugging a single-threaded
354 process. Nothing to do in that case. */
39f77062 355 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
356 if (tp == NULL)
357 return;
358
359 tp->prev_pc = prev_pc;
6c0d3f6a 360 tp->trap_expected = trap_expected;
c906108c
SS
361 tp->step_resume_breakpoint = step_resume_breakpoint;
362 tp->step_range_start = step_range_start;
363 tp->step_range_end = step_range_end;
aa0cd9c1 364 tp->step_frame_id = (*step_frame_id);
c906108c 365 tp->handling_longjmp = handling_longjmp;
c906108c
SS
366 tp->another_trap = another_trap;
367 tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
368 tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
369 tp->stepping_through_sigtramp = stepping_through_sigtramp;
6c0d3f6a
MS
370 tp->current_line = current_line;
371 tp->current_symtab = current_symtab;
c906108c
SS
372}
373
374/* Return true if TP is an active thread. */
375static int
fba45db2 376thread_alive (struct thread_info *tp)
c906108c 377{
39f77062 378 if (PIDGET (tp->ptid) == -1)
c906108c 379 return 0;
39f77062 380 if (!target_thread_alive (tp->ptid))
c906108c 381 {
39f77062 382 tp->ptid = pid_to_ptid (-1); /* Mark it as dead */
c906108c
SS
383 return 0;
384 }
385 return 1;
386}
387
388static void
fba45db2 389prune_threads (void)
c906108c 390{
d4f3574e 391 struct thread_info *tp, *next;
c906108c 392
c906108c
SS
393 for (tp = thread_list; tp; tp = next)
394 {
395 next = tp->next;
396 if (!thread_alive (tp))
39f77062 397 delete_thread (tp->ptid);
c906108c
SS
398 }
399}
400
401/* Print information about currently known threads
c5aa993b 402
c906108c
SS
403 * Note: this has the drawback that it _really_ switches
404 * threads, which frees the frame cache. A no-side
405 * effects info-threads command would be nicer.
406 */
407
408static void
fba45db2 409info_threads_command (char *arg, int from_tty)
c906108c
SS
410{
411 struct thread_info *tp;
39f77062 412 ptid_t current_ptid;
c5aa993b 413 struct frame_info *cur_frame;
7789d0fa 414 struct frame_id saved_frame_id = get_frame_id (get_selected_frame ());
0d06e24b 415 char *extra_info;
c906108c 416
c906108c 417 prune_threads ();
b83266a0 418 target_find_new_threads ();
39f77062 419 current_ptid = inferior_ptid;
c906108c
SS
420 for (tp = thread_list; tp; tp = tp->next)
421 {
39f77062 422 if (ptid_equal (tp->ptid, current_ptid))
c906108c
SS
423 printf_filtered ("* ");
424 else
425 printf_filtered (" ");
426
39f77062 427 printf_filtered ("%d %s", tp->num, target_tid_to_str (tp->ptid));
0d06e24b
JM
428
429 extra_info = target_extra_thread_info (tp);
430 if (extra_info)
431 printf_filtered (" (%s)", extra_info);
432 puts_filtered (" ");
433
39f77062 434 switch_to_thread (tp->ptid);
0faf0076 435 print_stack_frame (get_selected_frame (), 0, LOCATION);
c906108c
SS
436 }
437
39f77062 438 switch_to_thread (current_ptid);
c906108c 439
7789d0fa
AC
440 /* Restores the frame set by the user before the "info threads"
441 command. We have finished the info-threads display by switching
442 back to the current thread. That switch has put us at the top of
443 the stack (leaf frame). */
444 cur_frame = frame_find_by_id (saved_frame_id);
445 if (cur_frame == NULL)
c906108c 446 {
7789d0fa 447 /* Ooops, can't restore, tell user where we are. */
c906108c 448 warning ("Couldn't restore frame in current thread, at frame 0");
0faf0076 449 print_stack_frame (get_selected_frame (), 0, LOCATION);
c906108c
SS
450 }
451 else
452 {
0f7d239c 453 select_frame (cur_frame);
7789d0fa
AC
454 /* re-show current frame. */
455 show_stack_frame (cur_frame);
c906108c 456 }
c906108c
SS
457}
458
459/* Switch from one thread to another. */
460
461static void
39f77062 462switch_to_thread (ptid_t ptid)
c906108c 463{
39f77062 464 if (ptid_equal (ptid, inferior_ptid))
c906108c
SS
465 return;
466
39f77062 467 inferior_ptid = ptid;
c906108c
SS
468 flush_cached_frames ();
469 registers_changed ();
c5aa993b 470 stop_pc = read_pc ();
0f7d239c 471 select_frame (get_current_frame ());
c906108c
SS
472}
473
474static void
39f77062 475restore_current_thread (ptid_t ptid)
c906108c 476{
6949171e 477 if (!ptid_equal (ptid, inferior_ptid))
c906108c 478 {
39f77062 479 switch_to_thread (ptid);
0faf0076 480 print_stack_frame (get_current_frame (), 1, SRC_LINE);
c906108c
SS
481 }
482}
483
6ecce94d
AC
484struct current_thread_cleanup
485{
39f77062 486 ptid_t inferior_ptid;
6ecce94d
AC
487};
488
489static void
490do_restore_current_thread_cleanup (void *arg)
491{
492 struct current_thread_cleanup *old = arg;
39f77062 493 restore_current_thread (old->inferior_ptid);
b8c9b27d 494 xfree (old);
6ecce94d
AC
495}
496
497static struct cleanup *
39f77062 498make_cleanup_restore_current_thread (ptid_t inferior_ptid)
6ecce94d
AC
499{
500 struct current_thread_cleanup *old
501 = xmalloc (sizeof (struct current_thread_cleanup));
39f77062 502 old->inferior_ptid = inferior_ptid;
6ecce94d
AC
503 return make_cleanup (do_restore_current_thread_cleanup, old);
504}
505
c906108c
SS
506/* Apply a GDB command to a list of threads. List syntax is a whitespace
507 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
508 of two numbers seperated by a hyphen. Examples:
509
c5aa993b
JM
510 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
511 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
512 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
513 */
c906108c
SS
514
515static void
fba45db2 516thread_apply_all_command (char *cmd, int from_tty)
c906108c
SS
517{
518 struct thread_info *tp;
519 struct cleanup *old_chain;
e35ce267
CF
520 struct cleanup *saved_cmd_cleanup_chain;
521 char *saved_cmd;
c906108c
SS
522
523 if (cmd == NULL || *cmd == '\000')
524 error ("Please specify a command following the thread ID list");
525
39f77062 526 old_chain = make_cleanup_restore_current_thread (inferior_ptid);
c906108c 527
e9d196c5
MS
528 /* It is safe to update the thread list now, before
529 traversing it for "thread apply all". MVS */
530 target_find_new_threads ();
531
e35ce267
CF
532 /* Save a copy of the command in case it is clobbered by
533 execute_command */
5b616ba1 534 saved_cmd = xstrdup (cmd);
b8c9b27d 535 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
536 for (tp = thread_list; tp; tp = tp->next)
537 if (thread_alive (tp))
538 {
39f77062 539 switch_to_thread (tp->ptid);
c906108c 540 printf_filtered ("\nThread %d (%s):\n",
6949171e 541 tp->num, target_tid_to_str (inferior_ptid));
c906108c 542 execute_command (cmd, from_tty);
6949171e 543 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c 544 }
6ecce94d 545
e35ce267 546 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 547 do_cleanups (old_chain);
c906108c
SS
548}
549
550static void
fba45db2 551thread_apply_command (char *tidlist, int from_tty)
c906108c
SS
552{
553 char *cmd;
554 char *p;
555 struct cleanup *old_chain;
e35ce267
CF
556 struct cleanup *saved_cmd_cleanup_chain;
557 char *saved_cmd;
c906108c
SS
558
559 if (tidlist == NULL || *tidlist == '\000')
560 error ("Please specify a thread ID list");
561
c5aa993b 562 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
563
564 if (*cmd == '\000')
565 error ("Please specify a command following the thread ID list");
566
39f77062 567 old_chain = make_cleanup_restore_current_thread (inferior_ptid);
c906108c 568
e35ce267
CF
569 /* Save a copy of the command in case it is clobbered by
570 execute_command */
5b616ba1 571 saved_cmd = xstrdup (cmd);
b8c9b27d 572 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
573 while (tidlist < cmd)
574 {
575 struct thread_info *tp;
576 int start, end;
577
578 start = strtol (tidlist, &p, 10);
579 if (p == tidlist)
580 error ("Error parsing %s", tidlist);
581 tidlist = p;
582
583 while (*tidlist == ' ' || *tidlist == '\t')
584 tidlist++;
585
586 if (*tidlist == '-') /* Got a range of IDs? */
587 {
c5aa993b 588 tidlist++; /* Skip the - */
c906108c
SS
589 end = strtol (tidlist, &p, 10);
590 if (p == tidlist)
591 error ("Error parsing %s", tidlist);
592 tidlist = p;
593
594 while (*tidlist == ' ' || *tidlist == '\t')
595 tidlist++;
596 }
597 else
598 end = start;
599
600 for (; start <= end; start++)
601 {
602 tp = find_thread_id (start);
603
604 if (!tp)
605 warning ("Unknown thread %d.", start);
606 else if (!thread_alive (tp))
607 warning ("Thread %d has terminated.", start);
608 else
609 {
39f77062 610 switch_to_thread (tp->ptid);
c906108c 611 printf_filtered ("\nThread %d (%s):\n", tp->num,
39f77062 612 target_tid_to_str (inferior_ptid));
c906108c 613 execute_command (cmd, from_tty);
e35ce267 614 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c
SS
615 }
616 }
617 }
6ecce94d 618
e35ce267 619 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 620 do_cleanups (old_chain);
c906108c
SS
621}
622
623/* Switch to the specified thread. Will dispatch off to thread_apply_command
624 if prefix of arg is `apply'. */
625
626static void
fba45db2 627thread_command (char *tidstr, int from_tty)
c906108c 628{
c906108c
SS
629 if (!tidstr)
630 {
631 /* Don't generate an error, just say which thread is current. */
632 if (target_has_stack)
633 printf_filtered ("[Current thread is %d (%s)]\n",
39f77062 634 pid_to_thread_id (inferior_ptid),
007d08bb 635 target_tid_to_str (inferior_ptid));
c906108c
SS
636 else
637 error ("No stack.");
638 return;
639 }
c5394b80 640
2b65245e 641 gdb_thread_select (uiout, tidstr);
c5394b80
JM
642}
643
644static int
6949171e 645do_captured_thread_select (struct ui_out *uiout, void *tidstr)
c5394b80
JM
646{
647 int num;
648 struct thread_info *tp;
649
81490ea1 650 num = value_as_long (parse_and_eval (tidstr));
c906108c
SS
651
652 tp = find_thread_id (num);
653
8b93c638
JM
654 if (!tp)
655 error ("Thread ID %d not known.", num);
c906108c
SS
656
657 if (!thread_alive (tp))
658 error ("Thread ID %d has terminated.\n", num);
659
39f77062 660 switch_to_thread (tp->ptid);
c906108c 661
8b93c638 662 ui_out_text (uiout, "[Switching to thread ");
39f77062 663 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
8b93c638 664 ui_out_text (uiout, " (");
39f77062 665 ui_out_text (uiout, target_tid_to_str (inferior_ptid));
8b93c638 666 ui_out_text (uiout, ")]");
c5394b80 667
0faf0076 668 print_stack_frame (get_selected_frame (), 1, SRC_AND_LOC);
c5394b80
JM
669 return GDB_RC_OK;
670}
671
672enum gdb_rc
6949171e 673gdb_thread_select (struct ui_out *uiout, char *tidstr)
c5394b80 674{
2b65245e
AC
675 return catch_exceptions (uiout, do_captured_thread_select, tidstr,
676 NULL, RETURN_MASK_ALL);
c906108c
SS
677}
678
679/* Commands with a prefix of `thread'. */
680struct cmd_list_element *thread_cmd_list = NULL;
681
682void
fba45db2 683_initialize_thread (void)
c906108c
SS
684{
685 static struct cmd_list_element *thread_apply_list = NULL;
c906108c
SS
686
687 add_info ("threads", info_threads_command,
688 "IDs of currently known threads.");
689
690 add_prefix_cmd ("thread", class_run, thread_command,
691 "Use this command to switch between threads.\n\
6949171e 692The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1, &cmdlist);
c906108c
SS
693
694 add_prefix_cmd ("apply", class_run, thread_apply_command,
695 "Apply a command to a list of threads.",
696 &thread_apply_list, "apply ", 1, &thread_cmd_list);
697
698 add_cmd ("all", class_run, thread_apply_all_command,
6949171e 699 "Apply a command to all threads.", &thread_apply_list);
c906108c
SS
700
701 if (!xdb_commands)
702 add_com_alias ("t", "thread", class_run, 1);
703}
This page took 0.543184 seconds and 4 git commands to generate.