* ldlang.c (lang_size_sections_1): Don't warn on backwards dot
[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
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);
99b3d574
DP
68static struct cleanup *make_cleanup_restore_current_thread (ptid_t,
69 struct frame_id);
c906108c 70
8601f500
MS
71void
72delete_step_resume_breakpoint (void *arg)
73{
74 struct breakpoint **breakpointp = (struct breakpoint **) arg;
75 struct thread_info *tp;
76
77 if (*breakpointp != NULL)
78 {
79 delete_breakpoint (*breakpointp);
80 for (tp = thread_list; tp; tp = tp->next)
81 if (tp->step_resume_breakpoint == *breakpointp)
82 tp->step_resume_breakpoint = NULL;
83
84 *breakpointp = NULL;
85 }
86}
87
7c952b6d
ND
88static void
89free_thread (struct thread_info *tp)
90{
91 /* NOTE: this will take care of any left-over step_resume breakpoints,
92 but not any user-specified thread-specific breakpoints. */
93 if (tp->step_resume_breakpoint)
94 delete_breakpoint (tp->step_resume_breakpoint);
95
96 /* FIXME: do I ever need to call the back-end to give it a
97 chance at this private data before deleting the thread? */
98 if (tp->private)
b8c9b27d 99 xfree (tp->private);
7c952b6d 100
b8c9b27d 101 xfree (tp);
7c952b6d
ND
102}
103
c906108c 104void
fba45db2 105init_thread_list (void)
c906108c
SS
106{
107 struct thread_info *tp, *tpnext;
108
7c952b6d 109 highest_thread_num = 0;
c906108c
SS
110 if (!thread_list)
111 return;
112
113 for (tp = thread_list; tp; tp = tpnext)
114 {
115 tpnext = tp->next;
7c952b6d 116 free_thread (tp);
c906108c
SS
117 }
118
119 thread_list = NULL;
c906108c
SS
120}
121
0d06e24b
JM
122/* add_thread now returns a pointer to the new thread_info,
123 so that back_ends can initialize their private data. */
124
125struct thread_info *
39f77062 126add_thread (ptid_t ptid)
c906108c
SS
127{
128 struct thread_info *tp;
129
6c0d3f6a
MS
130 tp = (struct thread_info *) xmalloc (sizeof (*tp));
131 memset (tp, 0, sizeof (*tp));
39f77062 132 tp->ptid = ptid;
c906108c 133 tp->num = ++highest_thread_num;
c906108c
SS
134 tp->next = thread_list;
135 thread_list = tp;
0d06e24b 136 return tp;
c906108c
SS
137}
138
139void
39f77062 140delete_thread (ptid_t ptid)
c906108c
SS
141{
142 struct thread_info *tp, *tpprev;
143
144 tpprev = NULL;
145
146 for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
39f77062 147 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
148 break;
149
150 if (!tp)
151 return;
152
153 if (tpprev)
154 tpprev->next = tp->next;
155 else
156 thread_list = tp->next;
157
7c952b6d 158 free_thread (tp);
c906108c
SS
159}
160
161static struct thread_info *
fba45db2 162find_thread_id (int num)
c906108c
SS
163{
164 struct thread_info *tp;
165
166 for (tp = thread_list; tp; tp = tp->next)
167 if (tp->num == num)
168 return tp;
169
170 return NULL;
171}
172
39f77062 173/* Find a thread_info by matching PTID. */
0d06e24b 174struct thread_info *
39f77062 175find_thread_pid (ptid_t ptid)
0d06e24b
JM
176{
177 struct thread_info *tp;
178
179 for (tp = thread_list; tp; tp = tp->next)
39f77062 180 if (ptid_equal (tp->ptid, ptid))
0d06e24b
JM
181 return tp;
182
183 return NULL;
184}
185
186/*
187 * Thread iterator function.
188 *
189 * Calls a callback function once for each thread, so long as
190 * the callback function returns false. If the callback function
191 * returns true, the iteration will end and the current thread
192 * will be returned. This can be useful for implementing a
193 * search for a thread with arbitrary attributes, or for applying
194 * some operation to every thread.
195 *
196 * FIXME: some of the existing functionality, such as
197 * "Thread apply all", might be rewritten using this functionality.
198 */
199
200struct thread_info *
fd118b61
KB
201iterate_over_threads (int (*callback) (struct thread_info *, void *),
202 void *data)
0d06e24b
JM
203{
204 struct thread_info *tp;
205
206 for (tp = thread_list; tp; tp = tp->next)
207 if ((*callback) (tp, data))
208 return tp;
209
210 return NULL;
211}
212
c906108c 213int
fba45db2 214valid_thread_id (int num)
c906108c
SS
215{
216 struct thread_info *tp;
217
218 for (tp = thread_list; tp; tp = tp->next)
219 if (tp->num == num)
220 return 1;
221
222 return 0;
223}
224
225int
39f77062 226pid_to_thread_id (ptid_t ptid)
c906108c
SS
227{
228 struct thread_info *tp;
229
230 for (tp = thread_list; tp; tp = tp->next)
39f77062 231 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
232 return tp->num;
233
234 return 0;
235}
236
39f77062 237ptid_t
fba45db2 238thread_id_to_pid (int num)
c906108c
SS
239{
240 struct thread_info *thread = find_thread_id (num);
241 if (thread)
39f77062 242 return thread->ptid;
c906108c 243 else
39f77062 244 return pid_to_ptid (-1);
c906108c
SS
245}
246
247int
39f77062 248in_thread_list (ptid_t ptid)
c906108c
SS
249{
250 struct thread_info *tp;
251
252 for (tp = thread_list; tp; tp = tp->next)
39f77062 253 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
254 return 1;
255
256 return 0; /* Never heard of 'im */
257}
8926118c 258
8b93c638
JM
259/* Print a list of thread ids currently known, and the total number of
260 threads. To be used from within catch_errors. */
6949171e
JJ
261static int
262do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
8b93c638
JM
263{
264 struct thread_info *tp;
265 int num = 0;
3b31d625 266 struct cleanup *cleanup_chain;
8b93c638 267
7990a578
EZ
268 prune_threads ();
269 target_find_new_threads ();
270
3b31d625 271 cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids");
8b93c638
JM
272
273 for (tp = thread_list; tp; tp = tp->next)
274 {
275 num++;
276 ui_out_field_int (uiout, "thread-id", tp->num);
277 }
278
3b31d625 279 do_cleanups (cleanup_chain);
8b93c638
JM
280 ui_out_field_int (uiout, "number-of-threads", num);
281 return GDB_RC_OK;
282}
283
284/* Official gdblib interface function to get a list of thread ids and
285 the total number. */
286enum gdb_rc
ce43223b 287gdb_list_thread_ids (struct ui_out *uiout, char **error_message)
8b93c638 288{
ce43223b 289 return catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL,
1c3c7ee7 290 error_message, RETURN_MASK_ALL);
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;
c906108c
SS
464 flush_cached_frames ();
465 registers_changed ();
c5aa993b 466 stop_pc = read_pc ();
0f7d239c 467 select_frame (get_current_frame ());
c906108c
SS
468}
469
470static void
39f77062 471restore_current_thread (ptid_t ptid)
c906108c 472{
6949171e 473 if (!ptid_equal (ptid, inferior_ptid))
c906108c 474 {
39f77062 475 switch_to_thread (ptid);
99b3d574
DP
476 }
477}
478
479static void
480restore_selected_frame (struct frame_id a_frame_id)
481{
482 struct frame_info *selected_frame_info = NULL;
483
484 if (frame_id_eq (a_frame_id, null_frame_id))
485 return;
486
487 if ((selected_frame_info = frame_find_by_id (a_frame_id)) != NULL)
488 {
489 select_frame (selected_frame_info);
c906108c
SS
490 }
491}
492
6ecce94d
AC
493struct current_thread_cleanup
494{
39f77062 495 ptid_t inferior_ptid;
99b3d574 496 struct frame_id selected_frame_id;
6ecce94d
AC
497};
498
499static void
500do_restore_current_thread_cleanup (void *arg)
501{
502 struct current_thread_cleanup *old = arg;
39f77062 503 restore_current_thread (old->inferior_ptid);
99b3d574 504 restore_selected_frame (old->selected_frame_id);
b8c9b27d 505 xfree (old);
6ecce94d
AC
506}
507
508static struct cleanup *
99b3d574
DP
509make_cleanup_restore_current_thread (ptid_t inferior_ptid,
510 struct frame_id a_frame_id)
6ecce94d
AC
511{
512 struct current_thread_cleanup *old
513 = xmalloc (sizeof (struct current_thread_cleanup));
39f77062 514 old->inferior_ptid = inferior_ptid;
99b3d574 515 old->selected_frame_id = a_frame_id;
6ecce94d
AC
516 return make_cleanup (do_restore_current_thread_cleanup, old);
517}
518
c906108c
SS
519/* Apply a GDB command to a list of threads. List syntax is a whitespace
520 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
521 of two numbers seperated by a hyphen. Examples:
522
c5aa993b
JM
523 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
524 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
525 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
526 */
c906108c
SS
527
528static void
fba45db2 529thread_apply_all_command (char *cmd, int from_tty)
c906108c
SS
530{
531 struct thread_info *tp;
532 struct cleanup *old_chain;
e35ce267
CF
533 struct cleanup *saved_cmd_cleanup_chain;
534 char *saved_cmd;
99b3d574
DP
535 struct frame_id saved_frame_id;
536 ptid_t current_ptid;
537 int thread_has_changed = 0;
c906108c
SS
538
539 if (cmd == NULL || *cmd == '\000')
8a3fe4f8 540 error (_("Please specify a command following the thread ID list"));
99b3d574
DP
541
542 current_ptid = inferior_ptid;
543 saved_frame_id = get_frame_id (get_selected_frame (NULL));
544 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 545
e9d196c5
MS
546 /* It is safe to update the thread list now, before
547 traversing it for "thread apply all". MVS */
548 target_find_new_threads ();
549
e35ce267
CF
550 /* Save a copy of the command in case it is clobbered by
551 execute_command */
5b616ba1 552 saved_cmd = xstrdup (cmd);
b8c9b27d 553 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
554 for (tp = thread_list; tp; tp = tp->next)
555 if (thread_alive (tp))
556 {
39f77062 557 switch_to_thread (tp->ptid);
a3f17187 558 printf_filtered (_("\nThread %d (%s):\n"),
6949171e 559 tp->num, target_tid_to_str (inferior_ptid));
c906108c 560 execute_command (cmd, from_tty);
6949171e 561 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c 562 }
6ecce94d 563
99b3d574
DP
564 if (!ptid_equal (current_ptid, inferior_ptid))
565 thread_has_changed = 1;
566
e35ce267 567 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 568 do_cleanups (old_chain);
99b3d574
DP
569 /* Print stack frame only if we changed thread. */
570 if (thread_has_changed)
571 print_stack_frame (get_current_frame (), 1, SRC_LINE);
572
c906108c
SS
573}
574
575static void
fba45db2 576thread_apply_command (char *tidlist, int from_tty)
c906108c
SS
577{
578 char *cmd;
579 char *p;
580 struct cleanup *old_chain;
e35ce267
CF
581 struct cleanup *saved_cmd_cleanup_chain;
582 char *saved_cmd;
99b3d574
DP
583 struct frame_id saved_frame_id;
584 ptid_t current_ptid;
585 int thread_has_changed = 0;
c906108c
SS
586
587 if (tidlist == NULL || *tidlist == '\000')
8a3fe4f8 588 error (_("Please specify a thread ID list"));
c906108c 589
c5aa993b 590 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
591
592 if (*cmd == '\000')
8a3fe4f8 593 error (_("Please specify a command following the thread ID list"));
c906108c 594
99b3d574
DP
595 current_ptid = inferior_ptid;
596 saved_frame_id = get_frame_id (get_selected_frame (NULL));
597 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 598
e35ce267
CF
599 /* Save a copy of the command in case it is clobbered by
600 execute_command */
5b616ba1 601 saved_cmd = xstrdup (cmd);
b8c9b27d 602 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
603 while (tidlist < cmd)
604 {
605 struct thread_info *tp;
606 int start, end;
607
608 start = strtol (tidlist, &p, 10);
609 if (p == tidlist)
8a3fe4f8 610 error (_("Error parsing %s"), tidlist);
c906108c
SS
611 tidlist = p;
612
613 while (*tidlist == ' ' || *tidlist == '\t')
614 tidlist++;
615
616 if (*tidlist == '-') /* Got a range of IDs? */
617 {
c5aa993b 618 tidlist++; /* Skip the - */
c906108c
SS
619 end = strtol (tidlist, &p, 10);
620 if (p == tidlist)
8a3fe4f8 621 error (_("Error parsing %s"), tidlist);
c906108c
SS
622 tidlist = p;
623
624 while (*tidlist == ' ' || *tidlist == '\t')
625 tidlist++;
626 }
627 else
628 end = start;
629
630 for (; start <= end; start++)
631 {
632 tp = find_thread_id (start);
633
634 if (!tp)
8a3fe4f8 635 warning (_("Unknown thread %d."), start);
c906108c 636 else if (!thread_alive (tp))
8a3fe4f8 637 warning (_("Thread %d has terminated."), start);
c906108c
SS
638 else
639 {
39f77062 640 switch_to_thread (tp->ptid);
a3f17187 641 printf_filtered (_("\nThread %d (%s):\n"), tp->num,
39f77062 642 target_tid_to_str (inferior_ptid));
c906108c 643 execute_command (cmd, from_tty);
e35ce267 644 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c
SS
645 }
646 }
647 }
6ecce94d 648
99b3d574
DP
649 if (!ptid_equal (current_ptid, inferior_ptid))
650 thread_has_changed = 1;
651
e35ce267 652 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 653 do_cleanups (old_chain);
99b3d574
DP
654 /* Print stack frame only if we changed thread. */
655 if (thread_has_changed)
656 print_stack_frame (get_current_frame (), 1, SRC_LINE);
c906108c
SS
657}
658
659/* Switch to the specified thread. Will dispatch off to thread_apply_command
660 if prefix of arg is `apply'. */
661
662static void
fba45db2 663thread_command (char *tidstr, int from_tty)
c906108c 664{
c906108c
SS
665 if (!tidstr)
666 {
667 /* Don't generate an error, just say which thread is current. */
668 if (target_has_stack)
a3f17187 669 printf_filtered (_("[Current thread is %d (%s)]\n"),
39f77062 670 pid_to_thread_id (inferior_ptid),
007d08bb 671 target_tid_to_str (inferior_ptid));
c906108c 672 else
8a3fe4f8 673 error (_("No stack."));
c906108c
SS
674 return;
675 }
c5394b80 676
ce43223b 677 gdb_thread_select (uiout, tidstr, NULL);
c5394b80
JM
678}
679
680static int
6949171e 681do_captured_thread_select (struct ui_out *uiout, void *tidstr)
c5394b80
JM
682{
683 int num;
684 struct thread_info *tp;
685
81490ea1 686 num = value_as_long (parse_and_eval (tidstr));
c906108c
SS
687
688 tp = find_thread_id (num);
689
8b93c638 690 if (!tp)
8a3fe4f8 691 error (_("Thread ID %d not known."), num);
c906108c
SS
692
693 if (!thread_alive (tp))
8a3fe4f8 694 error (_("Thread ID %d has terminated."), num);
c906108c 695
39f77062 696 switch_to_thread (tp->ptid);
c906108c 697
8b93c638 698 ui_out_text (uiout, "[Switching to thread ");
39f77062 699 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
8b93c638 700 ui_out_text (uiout, " (");
39f77062 701 ui_out_text (uiout, target_tid_to_str (inferior_ptid));
8b93c638 702 ui_out_text (uiout, ")]");
c5394b80 703
b04f3ab4 704 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
c5394b80
JM
705 return GDB_RC_OK;
706}
707
708enum gdb_rc
ce43223b 709gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
c5394b80 710{
ce43223b 711 return catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr,
1c3c7ee7 712 error_message, RETURN_MASK_ALL);
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}
This page took 0.671292 seconds and 4 git commands to generate.