* Makefile.in (copying.c): Use the top-level COPYING3 as the 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
a9762ec7 12 the Free Software Foundation; either version 3 of the License, or
c5aa993b 13 (at your option) any later version.
c906108c 14
c5aa993b
JM
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
c906108c 19
c5aa993b 20 You should have received a copy of the GNU General Public License
a9762ec7 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
22
23#include "defs.h"
24#include "symtab.h"
25#include "frame.h"
26#include "inferior.h"
27#include "environ.h"
28#include "value.h"
29#include "target.h"
30#include "gdbthread.h"
60250e8b 31#include "exceptions.h"
c906108c
SS
32#include "command.h"
33#include "gdbcmd.h"
4e052eda 34#include "regcache.h"
5b7f31a4 35#include "gdb.h"
b66d6d2e 36#include "gdb_string.h"
c906108c
SS
37
38#include <ctype.h>
39#include <sys/types.h>
40#include <signal.h>
8b93c638 41#include "ui-out.h"
c906108c 42
0d06e24b 43/* Definition of struct thread_info exported to gdbthread.h */
c906108c
SS
44
45/* Prototypes for exported functions. */
46
a14ed312 47void _initialize_thread (void);
c906108c
SS
48
49/* Prototypes for local functions. */
50
c906108c
SS
51static struct thread_info *thread_list = NULL;
52static int highest_thread_num;
53
a14ed312 54static struct thread_info *find_thread_id (int num);
c906108c 55
a14ed312
KB
56static void thread_command (char *tidstr, int from_tty);
57static void thread_apply_all_command (char *, int);
58static int thread_alive (struct thread_info *);
59static void info_threads_command (char *, int);
60static void thread_apply_command (char *, int);
39f77062
KB
61static void restore_current_thread (ptid_t);
62static void switch_to_thread (ptid_t ptid);
a14ed312 63static void prune_threads (void);
99b3d574
DP
64static struct cleanup *make_cleanup_restore_current_thread (ptid_t,
65 struct frame_id);
c906108c 66
8601f500
MS
67void
68delete_step_resume_breakpoint (void *arg)
69{
70 struct breakpoint **breakpointp = (struct breakpoint **) arg;
71 struct thread_info *tp;
72
73 if (*breakpointp != NULL)
74 {
75 delete_breakpoint (*breakpointp);
76 for (tp = thread_list; tp; tp = tp->next)
77 if (tp->step_resume_breakpoint == *breakpointp)
78 tp->step_resume_breakpoint = NULL;
79
80 *breakpointp = NULL;
81 }
82}
83
7c952b6d
ND
84static void
85free_thread (struct thread_info *tp)
86{
87 /* NOTE: this will take care of any left-over step_resume breakpoints,
88 but not any user-specified thread-specific breakpoints. */
89 if (tp->step_resume_breakpoint)
90 delete_breakpoint (tp->step_resume_breakpoint);
91
92 /* FIXME: do I ever need to call the back-end to give it a
93 chance at this private data before deleting the thread? */
94 if (tp->private)
b8c9b27d 95 xfree (tp->private);
7c952b6d 96
b8c9b27d 97 xfree (tp);
7c952b6d
ND
98}
99
c906108c 100void
fba45db2 101init_thread_list (void)
c906108c
SS
102{
103 struct thread_info *tp, *tpnext;
104
7c952b6d 105 highest_thread_num = 0;
c906108c
SS
106 if (!thread_list)
107 return;
108
109 for (tp = thread_list; tp; tp = tpnext)
110 {
111 tpnext = tp->next;
7c952b6d 112 free_thread (tp);
c906108c
SS
113 }
114
115 thread_list = NULL;
c906108c
SS
116}
117
0d06e24b
JM
118/* add_thread now returns a pointer to the new thread_info,
119 so that back_ends can initialize their private data. */
120
121struct thread_info *
39f77062 122add_thread (ptid_t ptid)
c906108c
SS
123{
124 struct thread_info *tp;
125
6c0d3f6a
MS
126 tp = (struct thread_info *) xmalloc (sizeof (*tp));
127 memset (tp, 0, sizeof (*tp));
39f77062 128 tp->ptid = ptid;
c906108c 129 tp->num = ++highest_thread_num;
c906108c
SS
130 tp->next = thread_list;
131 thread_list = tp;
0d06e24b 132 return tp;
c906108c
SS
133}
134
135void
39f77062 136delete_thread (ptid_t ptid)
c906108c
SS
137{
138 struct thread_info *tp, *tpprev;
139
140 tpprev = NULL;
141
142 for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
39f77062 143 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
144 break;
145
146 if (!tp)
147 return;
148
149 if (tpprev)
150 tpprev->next = tp->next;
151 else
152 thread_list = tp->next;
153
7c952b6d 154 free_thread (tp);
c906108c
SS
155}
156
157static struct thread_info *
fba45db2 158find_thread_id (int num)
c906108c
SS
159{
160 struct thread_info *tp;
161
162 for (tp = thread_list; tp; tp = tp->next)
163 if (tp->num == num)
164 return tp;
165
166 return NULL;
167}
168
39f77062 169/* Find a thread_info by matching PTID. */
0d06e24b 170struct thread_info *
39f77062 171find_thread_pid (ptid_t ptid)
0d06e24b
JM
172{
173 struct thread_info *tp;
174
175 for (tp = thread_list; tp; tp = tp->next)
39f77062 176 if (ptid_equal (tp->ptid, ptid))
0d06e24b
JM
177 return tp;
178
179 return NULL;
180}
181
182/*
183 * Thread iterator function.
184 *
185 * Calls a callback function once for each thread, so long as
186 * the callback function returns false. If the callback function
187 * returns true, the iteration will end and the current thread
188 * will be returned. This can be useful for implementing a
189 * search for a thread with arbitrary attributes, or for applying
190 * some operation to every thread.
191 *
192 * FIXME: some of the existing functionality, such as
193 * "Thread apply all", might be rewritten using this functionality.
194 */
195
196struct thread_info *
fd118b61
KB
197iterate_over_threads (int (*callback) (struct thread_info *, void *),
198 void *data)
0d06e24b
JM
199{
200 struct thread_info *tp;
201
202 for (tp = thread_list; tp; tp = tp->next)
203 if ((*callback) (tp, data))
204 return tp;
205
206 return NULL;
207}
208
c906108c 209int
fba45db2 210valid_thread_id (int num)
c906108c
SS
211{
212 struct thread_info *tp;
213
214 for (tp = thread_list; tp; tp = tp->next)
215 if (tp->num == num)
216 return 1;
217
218 return 0;
219}
220
221int
39f77062 222pid_to_thread_id (ptid_t ptid)
c906108c
SS
223{
224 struct thread_info *tp;
225
226 for (tp = thread_list; tp; tp = tp->next)
39f77062 227 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
228 return tp->num;
229
230 return 0;
231}
232
39f77062 233ptid_t
fba45db2 234thread_id_to_pid (int num)
c906108c
SS
235{
236 struct thread_info *thread = find_thread_id (num);
237 if (thread)
39f77062 238 return thread->ptid;
c906108c 239 else
39f77062 240 return pid_to_ptid (-1);
c906108c
SS
241}
242
243int
39f77062 244in_thread_list (ptid_t ptid)
c906108c
SS
245{
246 struct thread_info *tp;
247
248 for (tp = thread_list; tp; tp = tp->next)
39f77062 249 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
250 return 1;
251
252 return 0; /* Never heard of 'im */
253}
8926118c 254
8b93c638
JM
255/* Print a list of thread ids currently known, and the total number of
256 threads. To be used from within catch_errors. */
6949171e
JJ
257static int
258do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
8b93c638
JM
259{
260 struct thread_info *tp;
261 int num = 0;
3b31d625 262 struct cleanup *cleanup_chain;
8b93c638 263
7990a578
EZ
264 prune_threads ();
265 target_find_new_threads ();
266
3b31d625 267 cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids");
8b93c638
JM
268
269 for (tp = thread_list; tp; tp = tp->next)
270 {
271 num++;
272 ui_out_field_int (uiout, "thread-id", tp->num);
273 }
274
3b31d625 275 do_cleanups (cleanup_chain);
8b93c638
JM
276 ui_out_field_int (uiout, "number-of-threads", num);
277 return GDB_RC_OK;
278}
279
280/* Official gdblib interface function to get a list of thread ids and
281 the total number. */
282enum gdb_rc
ce43223b 283gdb_list_thread_ids (struct ui_out *uiout, char **error_message)
8b93c638 284{
b0b13bb4
DJ
285 if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL,
286 error_message, RETURN_MASK_ALL) < 0)
287 return GDB_RC_FAIL;
288 return GDB_RC_OK;
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;
99b3d574
DP
411 struct cleanup *old_chain;
412 struct frame_id saved_frame_id;
0d06e24b 413 char *extra_info;
c906108c 414
99b3d574
DP
415 /* Backup current thread and selected frame. */
416 saved_frame_id = get_frame_id (get_selected_frame (NULL));
417 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
418
c906108c 419 prune_threads ();
b83266a0 420 target_find_new_threads ();
39f77062 421 current_ptid = inferior_ptid;
c906108c
SS
422 for (tp = thread_list; tp; tp = tp->next)
423 {
39f77062 424 if (ptid_equal (tp->ptid, current_ptid))
c906108c
SS
425 printf_filtered ("* ");
426 else
427 printf_filtered (" ");
428
39f77062 429 printf_filtered ("%d %s", tp->num, target_tid_to_str (tp->ptid));
0d06e24b
JM
430
431 extra_info = target_extra_thread_info (tp);
432 if (extra_info)
433 printf_filtered (" (%s)", extra_info);
434 puts_filtered (" ");
99b3d574 435 /* That switch put us at the top of the stack (leaf frame). */
39f77062 436 switch_to_thread (tp->ptid);
b04f3ab4 437 print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
c906108c
SS
438 }
439
99b3d574
DP
440 /* Restores the current thread and the frame selected before
441 the "info threads" command. */
442 do_cleanups (old_chain);
c906108c 443
99b3d574
DP
444 /* If case we were not able to find the original frame, print the
445 new selected frame. */
446 if (frame_find_by_id (saved_frame_id) == NULL)
c906108c 447 {
8a3fe4f8 448 warning (_("Couldn't restore frame in current thread, at frame 0"));
b04f3ab4 449 print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
c906108c 450 }
c906108c
SS
451}
452
453/* Switch from one thread to another. */
454
455static void
39f77062 456switch_to_thread (ptid_t ptid)
c906108c 457{
39f77062 458 if (ptid_equal (ptid, inferior_ptid))
c906108c
SS
459 return;
460
39f77062 461 inferior_ptid = ptid;
35f196d9 462 reinit_frame_cache ();
c906108c 463 registers_changed ();
c5aa993b 464 stop_pc = read_pc ();
c906108c
SS
465}
466
467static void
39f77062 468restore_current_thread (ptid_t ptid)
c906108c 469{
6949171e 470 if (!ptid_equal (ptid, inferior_ptid))
c906108c 471 {
39f77062 472 switch_to_thread (ptid);
99b3d574
DP
473 }
474}
475
476static void
477restore_selected_frame (struct frame_id a_frame_id)
478{
479 struct frame_info *selected_frame_info = NULL;
480
481 if (frame_id_eq (a_frame_id, null_frame_id))
482 return;
483
484 if ((selected_frame_info = frame_find_by_id (a_frame_id)) != NULL)
485 {
486 select_frame (selected_frame_info);
c906108c
SS
487 }
488}
489
6ecce94d
AC
490struct current_thread_cleanup
491{
39f77062 492 ptid_t inferior_ptid;
99b3d574 493 struct frame_id selected_frame_id;
6ecce94d
AC
494};
495
496static void
497do_restore_current_thread_cleanup (void *arg)
498{
499 struct current_thread_cleanup *old = arg;
39f77062 500 restore_current_thread (old->inferior_ptid);
99b3d574 501 restore_selected_frame (old->selected_frame_id);
b8c9b27d 502 xfree (old);
6ecce94d
AC
503}
504
505static struct cleanup *
99b3d574
DP
506make_cleanup_restore_current_thread (ptid_t inferior_ptid,
507 struct frame_id a_frame_id)
6ecce94d
AC
508{
509 struct current_thread_cleanup *old
510 = xmalloc (sizeof (struct current_thread_cleanup));
39f77062 511 old->inferior_ptid = inferior_ptid;
99b3d574 512 old->selected_frame_id = a_frame_id;
6ecce94d
AC
513 return make_cleanup (do_restore_current_thread_cleanup, old);
514}
515
c906108c
SS
516/* Apply a GDB command to a list of threads. List syntax is a whitespace
517 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
518 of two numbers seperated by a hyphen. Examples:
519
c5aa993b
JM
520 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
521 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
522 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
523 */
c906108c
SS
524
525static void
fba45db2 526thread_apply_all_command (char *cmd, int from_tty)
c906108c
SS
527{
528 struct thread_info *tp;
529 struct cleanup *old_chain;
e35ce267
CF
530 struct cleanup *saved_cmd_cleanup_chain;
531 char *saved_cmd;
99b3d574
DP
532 struct frame_id saved_frame_id;
533 ptid_t current_ptid;
534 int thread_has_changed = 0;
c906108c
SS
535
536 if (cmd == NULL || *cmd == '\000')
8a3fe4f8 537 error (_("Please specify a command following the thread ID list"));
99b3d574
DP
538
539 current_ptid = inferior_ptid;
540 saved_frame_id = get_frame_id (get_selected_frame (NULL));
541 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 542
e9d196c5
MS
543 /* It is safe to update the thread list now, before
544 traversing it for "thread apply all". MVS */
545 target_find_new_threads ();
546
e35ce267
CF
547 /* Save a copy of the command in case it is clobbered by
548 execute_command */
5b616ba1 549 saved_cmd = xstrdup (cmd);
b8c9b27d 550 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
551 for (tp = thread_list; tp; tp = tp->next)
552 if (thread_alive (tp))
553 {
39f77062 554 switch_to_thread (tp->ptid);
a3f17187 555 printf_filtered (_("\nThread %d (%s):\n"),
6949171e 556 tp->num, target_tid_to_str (inferior_ptid));
c906108c 557 execute_command (cmd, from_tty);
6949171e 558 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c 559 }
6ecce94d 560
99b3d574
DP
561 if (!ptid_equal (current_ptid, inferior_ptid))
562 thread_has_changed = 1;
563
e35ce267 564 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 565 do_cleanups (old_chain);
99b3d574
DP
566 /* Print stack frame only if we changed thread. */
567 if (thread_has_changed)
568 print_stack_frame (get_current_frame (), 1, SRC_LINE);
569
c906108c
SS
570}
571
572static void
fba45db2 573thread_apply_command (char *tidlist, int from_tty)
c906108c
SS
574{
575 char *cmd;
576 char *p;
577 struct cleanup *old_chain;
e35ce267
CF
578 struct cleanup *saved_cmd_cleanup_chain;
579 char *saved_cmd;
99b3d574
DP
580 struct frame_id saved_frame_id;
581 ptid_t current_ptid;
582 int thread_has_changed = 0;
c906108c
SS
583
584 if (tidlist == NULL || *tidlist == '\000')
8a3fe4f8 585 error (_("Please specify a thread ID list"));
c906108c 586
c5aa993b 587 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
588
589 if (*cmd == '\000')
8a3fe4f8 590 error (_("Please specify a command following the thread ID list"));
c906108c 591
99b3d574
DP
592 current_ptid = inferior_ptid;
593 saved_frame_id = get_frame_id (get_selected_frame (NULL));
594 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 595
e35ce267
CF
596 /* Save a copy of the command in case it is clobbered by
597 execute_command */
5b616ba1 598 saved_cmd = xstrdup (cmd);
b8c9b27d 599 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
600 while (tidlist < cmd)
601 {
602 struct thread_info *tp;
603 int start, end;
604
605 start = strtol (tidlist, &p, 10);
606 if (p == tidlist)
8a3fe4f8 607 error (_("Error parsing %s"), tidlist);
c906108c
SS
608 tidlist = p;
609
610 while (*tidlist == ' ' || *tidlist == '\t')
611 tidlist++;
612
613 if (*tidlist == '-') /* Got a range of IDs? */
614 {
c5aa993b 615 tidlist++; /* Skip the - */
c906108c
SS
616 end = strtol (tidlist, &p, 10);
617 if (p == tidlist)
8a3fe4f8 618 error (_("Error parsing %s"), tidlist);
c906108c
SS
619 tidlist = p;
620
621 while (*tidlist == ' ' || *tidlist == '\t')
622 tidlist++;
623 }
624 else
625 end = start;
626
627 for (; start <= end; start++)
628 {
629 tp = find_thread_id (start);
630
631 if (!tp)
8a3fe4f8 632 warning (_("Unknown thread %d."), start);
c906108c 633 else if (!thread_alive (tp))
8a3fe4f8 634 warning (_("Thread %d has terminated."), start);
c906108c
SS
635 else
636 {
39f77062 637 switch_to_thread (tp->ptid);
a3f17187 638 printf_filtered (_("\nThread %d (%s):\n"), tp->num,
39f77062 639 target_tid_to_str (inferior_ptid));
c906108c 640 execute_command (cmd, from_tty);
e35ce267 641 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c
SS
642 }
643 }
644 }
6ecce94d 645
99b3d574
DP
646 if (!ptid_equal (current_ptid, inferior_ptid))
647 thread_has_changed = 1;
648
e35ce267 649 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 650 do_cleanups (old_chain);
99b3d574
DP
651 /* Print stack frame only if we changed thread. */
652 if (thread_has_changed)
653 print_stack_frame (get_current_frame (), 1, SRC_LINE);
c906108c
SS
654}
655
656/* Switch to the specified thread. Will dispatch off to thread_apply_command
657 if prefix of arg is `apply'. */
658
659static void
fba45db2 660thread_command (char *tidstr, int from_tty)
c906108c 661{
c906108c
SS
662 if (!tidstr)
663 {
664 /* Don't generate an error, just say which thread is current. */
665 if (target_has_stack)
a3f17187 666 printf_filtered (_("[Current thread is %d (%s)]\n"),
39f77062 667 pid_to_thread_id (inferior_ptid),
007d08bb 668 target_tid_to_str (inferior_ptid));
c906108c 669 else
8a3fe4f8 670 error (_("No stack."));
c906108c
SS
671 return;
672 }
c5394b80 673
ce43223b 674 gdb_thread_select (uiout, tidstr, NULL);
c5394b80
JM
675}
676
677static int
6949171e 678do_captured_thread_select (struct ui_out *uiout, void *tidstr)
c5394b80
JM
679{
680 int num;
681 struct thread_info *tp;
682
81490ea1 683 num = value_as_long (parse_and_eval (tidstr));
c906108c
SS
684
685 tp = find_thread_id (num);
686
8b93c638 687 if (!tp)
8a3fe4f8 688 error (_("Thread ID %d not known."), num);
c906108c
SS
689
690 if (!thread_alive (tp))
8a3fe4f8 691 error (_("Thread ID %d has terminated."), num);
c906108c 692
39f77062 693 switch_to_thread (tp->ptid);
c906108c 694
8b93c638 695 ui_out_text (uiout, "[Switching to thread ");
39f77062 696 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
8b93c638 697 ui_out_text (uiout, " (");
39f77062 698 ui_out_text (uiout, target_tid_to_str (inferior_ptid));
8b93c638 699 ui_out_text (uiout, ")]");
c5394b80 700
b04f3ab4 701 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
c5394b80
JM
702 return GDB_RC_OK;
703}
704
705enum gdb_rc
ce43223b 706gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
c5394b80 707{
b0b13bb4
DJ
708 if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr,
709 error_message, RETURN_MASK_ALL) < 0)
710 return GDB_RC_FAIL;
711 return GDB_RC_OK;
c906108c
SS
712}
713
714/* Commands with a prefix of `thread'. */
715struct cmd_list_element *thread_cmd_list = NULL;
716
717void
fba45db2 718_initialize_thread (void)
c906108c
SS
719{
720 static struct cmd_list_element *thread_apply_list = NULL;
c906108c
SS
721
722 add_info ("threads", info_threads_command,
1bedd215 723 _("IDs of currently known threads."));
c906108c 724
1bedd215
AC
725 add_prefix_cmd ("thread", class_run, thread_command, _("\
726Use this command to switch between threads.\n\
727The new thread ID must be currently known."),
728 &thread_cmd_list, "thread ", 1, &cmdlist);
c906108c
SS
729
730 add_prefix_cmd ("apply", class_run, thread_apply_command,
1bedd215 731 _("Apply a command to a list of threads."),
ad21ceb0 732 &thread_apply_list, "thread apply ", 1, &thread_cmd_list);
c906108c
SS
733
734 add_cmd ("all", class_run, thread_apply_all_command,
1a966eab 735 _("Apply a command to all threads."), &thread_apply_list);
c906108c
SS
736
737 if (!xdb_commands)
738 add_com_alias ("t", "thread", class_run, 1);
739}
This page took 0.740276 seconds and 4 git commands to generate.