* core-aout.c: Delete file.
[deliverable/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
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
197e01b6
EZ
22 Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 Boston, MA 02110-1301, 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
0d06e24b 45/* Definition of struct thread_info exported to gdbthread.h */
c906108c
SS
46
47/* Prototypes for exported functions. */
48
a14ed312 49void _initialize_thread (void);
c906108c
SS
50
51/* Prototypes for local functions. */
52
c906108c
SS
53static struct thread_info *thread_list = NULL;
54static int highest_thread_num;
55
a14ed312 56static struct thread_info *find_thread_id (int num);
c906108c 57
a14ed312
KB
58static void thread_command (char *tidstr, int from_tty);
59static void thread_apply_all_command (char *, int);
60static int thread_alive (struct thread_info *);
61static void info_threads_command (char *, int);
62static void thread_apply_command (char *, int);
39f77062
KB
63static void restore_current_thread (ptid_t);
64static void switch_to_thread (ptid_t ptid);
a14ed312 65static void prune_threads (void);
99b3d574
DP
66static struct cleanup *make_cleanup_restore_current_thread (ptid_t,
67 struct frame_id);
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{
b0b13bb4
DJ
287 if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL,
288 error_message, RETURN_MASK_ALL) < 0)
289 return GDB_RC_FAIL;
290 return GDB_RC_OK;
8b93c638 291}
c906108c
SS
292
293/* Load infrun state for the thread PID. */
294
c5aa993b 295void
6949171e
JJ
296load_infrun_state (ptid_t ptid,
297 CORE_ADDR *prev_pc,
6c0d3f6a 298 int *trap_expected,
fba45db2 299 struct breakpoint **step_resume_breakpoint,
6949171e 300 CORE_ADDR *step_range_start,
6c0d3f6a 301 CORE_ADDR *step_range_end,
6949171e 302 struct frame_id *step_frame_id,
6c0d3f6a 303 int *handling_longjmp,
6949171e 304 int *another_trap,
6c0d3f6a 305 int *stepping_through_solib_after_catch,
fba45db2 306 bpstat *stepping_through_solib_catchpoints,
6949171e 307 int *current_line,
f2c9ca08 308 struct symtab **current_symtab)
c906108c
SS
309{
310 struct thread_info *tp;
311
312 /* If we can't find the thread, then we're debugging a single threaded
313 process. No need to do anything in that case. */
39f77062 314 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
315 if (tp == NULL)
316 return;
317
318 *prev_pc = tp->prev_pc;
6c0d3f6a 319 *trap_expected = tp->trap_expected;
c906108c
SS
320 *step_resume_breakpoint = tp->step_resume_breakpoint;
321 *step_range_start = tp->step_range_start;
322 *step_range_end = tp->step_range_end;
aa0cd9c1 323 *step_frame_id = tp->step_frame_id;
c906108c 324 *handling_longjmp = tp->handling_longjmp;
c906108c 325 *another_trap = tp->another_trap;
6949171e
JJ
326 *stepping_through_solib_after_catch =
327 tp->stepping_through_solib_after_catch;
328 *stepping_through_solib_catchpoints =
329 tp->stepping_through_solib_catchpoints;
6c0d3f6a
MS
330 *current_line = tp->current_line;
331 *current_symtab = tp->current_symtab;
c906108c
SS
332}
333
334/* Save infrun state for the thread PID. */
335
c5aa993b 336void
6949171e
JJ
337save_infrun_state (ptid_t ptid,
338 CORE_ADDR prev_pc,
6c0d3f6a 339 int trap_expected,
fba45db2 340 struct breakpoint *step_resume_breakpoint,
6949171e 341 CORE_ADDR step_range_start,
6c0d3f6a 342 CORE_ADDR step_range_end,
6949171e 343 const struct frame_id *step_frame_id,
6c0d3f6a 344 int handling_longjmp,
6949171e 345 int another_trap,
6c0d3f6a 346 int stepping_through_solib_after_catch,
fba45db2 347 bpstat stepping_through_solib_catchpoints,
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;
6c0d3f6a
MS
369 tp->current_line = current_line;
370 tp->current_symtab = current_symtab;
c906108c
SS
371}
372
373/* Return true if TP is an active thread. */
374static int
fba45db2 375thread_alive (struct thread_info *tp)
c906108c 376{
39f77062 377 if (PIDGET (tp->ptid) == -1)
c906108c 378 return 0;
39f77062 379 if (!target_thread_alive (tp->ptid))
c906108c 380 {
39f77062 381 tp->ptid = pid_to_ptid (-1); /* Mark it as dead */
c906108c
SS
382 return 0;
383 }
384 return 1;
385}
386
387static void
fba45db2 388prune_threads (void)
c906108c 389{
d4f3574e 390 struct thread_info *tp, *next;
c906108c 391
c906108c
SS
392 for (tp = thread_list; tp; tp = next)
393 {
394 next = tp->next;
395 if (!thread_alive (tp))
39f77062 396 delete_thread (tp->ptid);
c906108c
SS
397 }
398}
399
400/* Print information about currently known threads
c5aa993b 401
c906108c
SS
402 * Note: this has the drawback that it _really_ switches
403 * threads, which frees the frame cache. A no-side
404 * effects info-threads command would be nicer.
405 */
406
407static void
fba45db2 408info_threads_command (char *arg, int from_tty)
c906108c
SS
409{
410 struct thread_info *tp;
39f77062 411 ptid_t current_ptid;
c5aa993b 412 struct frame_info *cur_frame;
99b3d574
DP
413 struct cleanup *old_chain;
414 struct frame_id saved_frame_id;
0d06e24b 415 char *extra_info;
c906108c 416
99b3d574
DP
417 /* Backup current thread and selected frame. */
418 saved_frame_id = get_frame_id (get_selected_frame (NULL));
419 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
420
c906108c 421 prune_threads ();
b83266a0 422 target_find_new_threads ();
39f77062 423 current_ptid = inferior_ptid;
c906108c
SS
424 for (tp = thread_list; tp; tp = tp->next)
425 {
39f77062 426 if (ptid_equal (tp->ptid, current_ptid))
c906108c
SS
427 printf_filtered ("* ");
428 else
429 printf_filtered (" ");
430
39f77062 431 printf_filtered ("%d %s", tp->num, target_tid_to_str (tp->ptid));
0d06e24b
JM
432
433 extra_info = target_extra_thread_info (tp);
434 if (extra_info)
435 printf_filtered (" (%s)", extra_info);
436 puts_filtered (" ");
99b3d574 437 /* That switch put us at the top of the stack (leaf frame). */
39f77062 438 switch_to_thread (tp->ptid);
b04f3ab4 439 print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
c906108c
SS
440 }
441
99b3d574
DP
442 /* Restores the current thread and the frame selected before
443 the "info threads" command. */
444 do_cleanups (old_chain);
c906108c 445
99b3d574
DP
446 /* If case we were not able to find the original frame, print the
447 new selected frame. */
448 if (frame_find_by_id (saved_frame_id) == NULL)
c906108c 449 {
8a3fe4f8 450 warning (_("Couldn't restore frame in current thread, at frame 0"));
b04f3ab4 451 print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
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;
35f196d9 464 reinit_frame_cache ();
c906108c 465 registers_changed ();
c5aa993b 466 stop_pc = read_pc ();
c906108c
SS
467}
468
469static void
39f77062 470restore_current_thread (ptid_t ptid)
c906108c 471{
6949171e 472 if (!ptid_equal (ptid, inferior_ptid))
c906108c 473 {
39f77062 474 switch_to_thread (ptid);
99b3d574
DP
475 }
476}
477
478static void
479restore_selected_frame (struct frame_id a_frame_id)
480{
481 struct frame_info *selected_frame_info = NULL;
482
483 if (frame_id_eq (a_frame_id, null_frame_id))
484 return;
485
486 if ((selected_frame_info = frame_find_by_id (a_frame_id)) != NULL)
487 {
488 select_frame (selected_frame_info);
c906108c
SS
489 }
490}
491
6ecce94d
AC
492struct current_thread_cleanup
493{
39f77062 494 ptid_t inferior_ptid;
99b3d574 495 struct frame_id selected_frame_id;
6ecce94d
AC
496};
497
498static void
499do_restore_current_thread_cleanup (void *arg)
500{
501 struct current_thread_cleanup *old = arg;
39f77062 502 restore_current_thread (old->inferior_ptid);
99b3d574 503 restore_selected_frame (old->selected_frame_id);
b8c9b27d 504 xfree (old);
6ecce94d
AC
505}
506
507static struct cleanup *
99b3d574
DP
508make_cleanup_restore_current_thread (ptid_t inferior_ptid,
509 struct frame_id a_frame_id)
6ecce94d
AC
510{
511 struct current_thread_cleanup *old
512 = xmalloc (sizeof (struct current_thread_cleanup));
39f77062 513 old->inferior_ptid = inferior_ptid;
99b3d574 514 old->selected_frame_id = a_frame_id;
6ecce94d
AC
515 return make_cleanup (do_restore_current_thread_cleanup, old);
516}
517
c906108c
SS
518/* Apply a GDB command to a list of threads. List syntax is a whitespace
519 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
520 of two numbers seperated by a hyphen. Examples:
521
c5aa993b
JM
522 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
523 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
524 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
525 */
c906108c
SS
526
527static void
fba45db2 528thread_apply_all_command (char *cmd, int from_tty)
c906108c
SS
529{
530 struct thread_info *tp;
531 struct cleanup *old_chain;
e35ce267
CF
532 struct cleanup *saved_cmd_cleanup_chain;
533 char *saved_cmd;
99b3d574
DP
534 struct frame_id saved_frame_id;
535 ptid_t current_ptid;
536 int thread_has_changed = 0;
c906108c
SS
537
538 if (cmd == NULL || *cmd == '\000')
8a3fe4f8 539 error (_("Please specify a command following the thread ID list"));
99b3d574
DP
540
541 current_ptid = inferior_ptid;
542 saved_frame_id = get_frame_id (get_selected_frame (NULL));
543 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 544
e9d196c5
MS
545 /* It is safe to update the thread list now, before
546 traversing it for "thread apply all". MVS */
547 target_find_new_threads ();
548
e35ce267
CF
549 /* Save a copy of the command in case it is clobbered by
550 execute_command */
5b616ba1 551 saved_cmd = xstrdup (cmd);
b8c9b27d 552 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
553 for (tp = thread_list; tp; tp = tp->next)
554 if (thread_alive (tp))
555 {
39f77062 556 switch_to_thread (tp->ptid);
a3f17187 557 printf_filtered (_("\nThread %d (%s):\n"),
6949171e 558 tp->num, target_tid_to_str (inferior_ptid));
c906108c 559 execute_command (cmd, from_tty);
6949171e 560 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c 561 }
6ecce94d 562
99b3d574
DP
563 if (!ptid_equal (current_ptid, inferior_ptid))
564 thread_has_changed = 1;
565
e35ce267 566 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 567 do_cleanups (old_chain);
99b3d574
DP
568 /* Print stack frame only if we changed thread. */
569 if (thread_has_changed)
570 print_stack_frame (get_current_frame (), 1, SRC_LINE);
571
c906108c
SS
572}
573
574static void
fba45db2 575thread_apply_command (char *tidlist, int from_tty)
c906108c
SS
576{
577 char *cmd;
578 char *p;
579 struct cleanup *old_chain;
e35ce267
CF
580 struct cleanup *saved_cmd_cleanup_chain;
581 char *saved_cmd;
99b3d574
DP
582 struct frame_id saved_frame_id;
583 ptid_t current_ptid;
584 int thread_has_changed = 0;
c906108c
SS
585
586 if (tidlist == NULL || *tidlist == '\000')
8a3fe4f8 587 error (_("Please specify a thread ID list"));
c906108c 588
c5aa993b 589 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
590
591 if (*cmd == '\000')
8a3fe4f8 592 error (_("Please specify a command following the thread ID list"));
c906108c 593
99b3d574
DP
594 current_ptid = inferior_ptid;
595 saved_frame_id = get_frame_id (get_selected_frame (NULL));
596 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 597
e35ce267
CF
598 /* Save a copy of the command in case it is clobbered by
599 execute_command */
5b616ba1 600 saved_cmd = xstrdup (cmd);
b8c9b27d 601 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
602 while (tidlist < cmd)
603 {
604 struct thread_info *tp;
605 int start, end;
606
607 start = strtol (tidlist, &p, 10);
608 if (p == tidlist)
8a3fe4f8 609 error (_("Error parsing %s"), tidlist);
c906108c
SS
610 tidlist = p;
611
612 while (*tidlist == ' ' || *tidlist == '\t')
613 tidlist++;
614
615 if (*tidlist == '-') /* Got a range of IDs? */
616 {
c5aa993b 617 tidlist++; /* Skip the - */
c906108c
SS
618 end = strtol (tidlist, &p, 10);
619 if (p == tidlist)
8a3fe4f8 620 error (_("Error parsing %s"), tidlist);
c906108c
SS
621 tidlist = p;
622
623 while (*tidlist == ' ' || *tidlist == '\t')
624 tidlist++;
625 }
626 else
627 end = start;
628
629 for (; start <= end; start++)
630 {
631 tp = find_thread_id (start);
632
633 if (!tp)
8a3fe4f8 634 warning (_("Unknown thread %d."), start);
c906108c 635 else if (!thread_alive (tp))
8a3fe4f8 636 warning (_("Thread %d has terminated."), start);
c906108c
SS
637 else
638 {
39f77062 639 switch_to_thread (tp->ptid);
a3f17187 640 printf_filtered (_("\nThread %d (%s):\n"), tp->num,
39f77062 641 target_tid_to_str (inferior_ptid));
c906108c 642 execute_command (cmd, from_tty);
e35ce267 643 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c
SS
644 }
645 }
646 }
6ecce94d 647
99b3d574
DP
648 if (!ptid_equal (current_ptid, inferior_ptid))
649 thread_has_changed = 1;
650
e35ce267 651 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 652 do_cleanups (old_chain);
99b3d574
DP
653 /* Print stack frame only if we changed thread. */
654 if (thread_has_changed)
655 print_stack_frame (get_current_frame (), 1, SRC_LINE);
c906108c
SS
656}
657
658/* Switch to the specified thread. Will dispatch off to thread_apply_command
659 if prefix of arg is `apply'. */
660
661static void
fba45db2 662thread_command (char *tidstr, int from_tty)
c906108c 663{
c906108c
SS
664 if (!tidstr)
665 {
666 /* Don't generate an error, just say which thread is current. */
667 if (target_has_stack)
a3f17187 668 printf_filtered (_("[Current thread is %d (%s)]\n"),
39f77062 669 pid_to_thread_id (inferior_ptid),
007d08bb 670 target_tid_to_str (inferior_ptid));
c906108c 671 else
8a3fe4f8 672 error (_("No stack."));
c906108c
SS
673 return;
674 }
c5394b80 675
ce43223b 676 gdb_thread_select (uiout, tidstr, NULL);
c5394b80
JM
677}
678
679static int
6949171e 680do_captured_thread_select (struct ui_out *uiout, void *tidstr)
c5394b80
JM
681{
682 int num;
683 struct thread_info *tp;
684
81490ea1 685 num = value_as_long (parse_and_eval (tidstr));
c906108c
SS
686
687 tp = find_thread_id (num);
688
8b93c638 689 if (!tp)
8a3fe4f8 690 error (_("Thread ID %d not known."), num);
c906108c
SS
691
692 if (!thread_alive (tp))
8a3fe4f8 693 error (_("Thread ID %d has terminated."), num);
c906108c 694
39f77062 695 switch_to_thread (tp->ptid);
c906108c 696
8b93c638 697 ui_out_text (uiout, "[Switching to thread ");
39f77062 698 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
8b93c638 699 ui_out_text (uiout, " (");
39f77062 700 ui_out_text (uiout, target_tid_to_str (inferior_ptid));
8b93c638 701 ui_out_text (uiout, ")]");
c5394b80 702
b04f3ab4 703 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
c5394b80
JM
704 return GDB_RC_OK;
705}
706
707enum gdb_rc
ce43223b 708gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
c5394b80 709{
b0b13bb4
DJ
710 if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr,
711 error_message, RETURN_MASK_ALL) < 0)
712 return GDB_RC_FAIL;
713 return GDB_RC_OK;
c906108c
SS
714}
715
716/* Commands with a prefix of `thread'. */
717struct cmd_list_element *thread_cmd_list = NULL;
718
719void
fba45db2 720_initialize_thread (void)
c906108c
SS
721{
722 static struct cmd_list_element *thread_apply_list = NULL;
c906108c
SS
723
724 add_info ("threads", info_threads_command,
1bedd215 725 _("IDs of currently known threads."));
c906108c 726
1bedd215
AC
727 add_prefix_cmd ("thread", class_run, thread_command, _("\
728Use this command to switch between threads.\n\
729The new thread ID must be currently known."),
730 &thread_cmd_list, "thread ", 1, &cmdlist);
c906108c
SS
731
732 add_prefix_cmd ("apply", class_run, thread_apply_command,
1bedd215 733 _("Apply a command to a list of threads."),
ad21ceb0 734 &thread_apply_list, "thread apply ", 1, &thread_cmd_list);
c906108c
SS
735
736 add_cmd ("all", class_run, thread_apply_all_command,
1a966eab 737 _("Apply a command to all threads."), &thread_apply_list);
c906108c
SS
738
739 if (!xdb_commands)
740 add_com_alias ("t", "thread", class_run, 1);
741}
This page took 0.713549 seconds and 4 git commands to generate.