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