* thread.c (print_thread_info): Don't insist
[deliverable/binutils-gdb.git] / gdb / thread.c
CommitLineData
c906108c 1/* Multi-process/thread control for GDB, the GNU debugger.
8926118c 2
6aba47ca 3 Copyright (C) 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
9b254dd1 4 2000, 2001, 2002, 2003, 2004, 2007, 2008 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"
683f2885 42#include "observer.h"
c906108c 43
0d06e24b 44/* Definition of struct thread_info exported to gdbthread.h */
c906108c
SS
45
46/* Prototypes for exported functions. */
47
a14ed312 48void _initialize_thread (void);
c906108c
SS
49
50/* Prototypes for local functions. */
51
c906108c
SS
52static struct thread_info *thread_list = NULL;
53static int highest_thread_num;
54
a14ed312 55static struct thread_info *find_thread_id (int num);
c906108c 56
a14ed312
KB
57static void thread_command (char *tidstr, int from_tty);
58static void thread_apply_all_command (char *, int);
59static int thread_alive (struct thread_info *);
60static void info_threads_command (char *, int);
61static void thread_apply_command (char *, int);
39f77062 62static void restore_current_thread (ptid_t);
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,
4d8453a5
DJ
88 but not any user-specified thread-specific breakpoints. We can not
89 delete the breakpoint straight-off, because the inferior might not
90 be stopped at the moment. */
7c952b6d 91 if (tp->step_resume_breakpoint)
4d8453a5 92 tp->step_resume_breakpoint->disposition = disp_del_at_next_stop;
7c952b6d
ND
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 120struct thread_info *
93815fbf 121add_thread_silent (ptid_t ptid)
c906108c
SS
122{
123 struct thread_info *tp;
124
6c0d3f6a
MS
125 tp = (struct thread_info *) xmalloc (sizeof (*tp));
126 memset (tp, 0, sizeof (*tp));
39f77062 127 tp->ptid = ptid;
c906108c 128 tp->num = ++highest_thread_num;
c906108c
SS
129 tp->next = thread_list;
130 thread_list = tp;
0d06e24b 131 return tp;
c906108c
SS
132}
133
93815fbf
VP
134struct thread_info *
135add_thread (ptid_t ptid)
136{
137 struct thread_info *result = add_thread_silent (ptid);
138
139 if (print_thread_events)
fd532e2e 140 printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid));
683f2885
VP
141
142 observer_notify_new_thread (result);
93815fbf
VP
143
144 return result;
145}
146
c906108c 147void
39f77062 148delete_thread (ptid_t ptid)
c906108c
SS
149{
150 struct thread_info *tp, *tpprev;
151
152 tpprev = NULL;
153
154 for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
39f77062 155 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
156 break;
157
158 if (!tp)
159 return;
160
161 if (tpprev)
162 tpprev->next = tp->next;
163 else
164 thread_list = tp->next;
165
7c952b6d 166 free_thread (tp);
c906108c
SS
167}
168
169static struct thread_info *
fba45db2 170find_thread_id (int num)
c906108c
SS
171{
172 struct thread_info *tp;
173
174 for (tp = thread_list; tp; tp = tp->next)
175 if (tp->num == num)
176 return tp;
177
178 return NULL;
179}
180
39f77062 181/* Find a thread_info by matching PTID. */
0d06e24b 182struct thread_info *
39f77062 183find_thread_pid (ptid_t ptid)
0d06e24b
JM
184{
185 struct thread_info *tp;
186
187 for (tp = thread_list; tp; tp = tp->next)
39f77062 188 if (ptid_equal (tp->ptid, ptid))
0d06e24b
JM
189 return tp;
190
191 return NULL;
192}
193
194/*
195 * Thread iterator function.
196 *
197 * Calls a callback function once for each thread, so long as
198 * the callback function returns false. If the callback function
199 * returns true, the iteration will end and the current thread
200 * will be returned. This can be useful for implementing a
201 * search for a thread with arbitrary attributes, or for applying
202 * some operation to every thread.
203 *
204 * FIXME: some of the existing functionality, such as
205 * "Thread apply all", might be rewritten using this functionality.
206 */
207
208struct thread_info *
fd118b61
KB
209iterate_over_threads (int (*callback) (struct thread_info *, void *),
210 void *data)
0d06e24b
JM
211{
212 struct thread_info *tp;
213
214 for (tp = thread_list; tp; tp = tp->next)
215 if ((*callback) (tp, data))
216 return tp;
217
218 return NULL;
219}
220
c906108c 221int
fba45db2 222valid_thread_id (int num)
c906108c
SS
223{
224 struct thread_info *tp;
225
226 for (tp = thread_list; tp; tp = tp->next)
227 if (tp->num == num)
228 return 1;
229
230 return 0;
231}
232
233int
39f77062 234pid_to_thread_id (ptid_t ptid)
c906108c
SS
235{
236 struct thread_info *tp;
237
238 for (tp = thread_list; tp; tp = tp->next)
39f77062 239 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
240 return tp->num;
241
242 return 0;
243}
244
39f77062 245ptid_t
fba45db2 246thread_id_to_pid (int num)
c906108c
SS
247{
248 struct thread_info *thread = find_thread_id (num);
249 if (thread)
39f77062 250 return thread->ptid;
c906108c 251 else
39f77062 252 return pid_to_ptid (-1);
c906108c
SS
253}
254
255int
39f77062 256in_thread_list (ptid_t ptid)
c906108c
SS
257{
258 struct thread_info *tp;
259
260 for (tp = thread_list; tp; tp = tp->next)
39f77062 261 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
262 return 1;
263
264 return 0; /* Never heard of 'im */
265}
8926118c 266
8b93c638
JM
267/* Print a list of thread ids currently known, and the total number of
268 threads. To be used from within catch_errors. */
6949171e
JJ
269static int
270do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
8b93c638
JM
271{
272 struct thread_info *tp;
273 int num = 0;
3b31d625 274 struct cleanup *cleanup_chain;
8b93c638 275
7990a578
EZ
276 prune_threads ();
277 target_find_new_threads ();
278
3b31d625 279 cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids");
8b93c638
JM
280
281 for (tp = thread_list; tp; tp = tp->next)
282 {
283 num++;
284 ui_out_field_int (uiout, "thread-id", tp->num);
285 }
286
3b31d625 287 do_cleanups (cleanup_chain);
8b93c638
JM
288 ui_out_field_int (uiout, "number-of-threads", num);
289 return GDB_RC_OK;
290}
291
292/* Official gdblib interface function to get a list of thread ids and
293 the total number. */
294enum gdb_rc
ce43223b 295gdb_list_thread_ids (struct ui_out *uiout, char **error_message)
8b93c638 296{
b0b13bb4
DJ
297 if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL,
298 error_message, RETURN_MASK_ALL) < 0)
299 return GDB_RC_FAIL;
300 return GDB_RC_OK;
8b93c638 301}
c906108c
SS
302
303/* Load infrun state for the thread PID. */
304
c5aa993b 305void
6949171e
JJ
306load_infrun_state (ptid_t ptid,
307 CORE_ADDR *prev_pc,
6c0d3f6a 308 int *trap_expected,
fba45db2 309 struct breakpoint **step_resume_breakpoint,
6949171e 310 CORE_ADDR *step_range_start,
6c0d3f6a 311 CORE_ADDR *step_range_end,
6949171e 312 struct frame_id *step_frame_id,
6c0d3f6a 313 int *handling_longjmp,
ca67fcb8 314 int *stepping_over_breakpoint,
6c0d3f6a 315 int *stepping_through_solib_after_catch,
fba45db2 316 bpstat *stepping_through_solib_catchpoints,
6949171e 317 int *current_line,
f2c9ca08 318 struct symtab **current_symtab)
c906108c
SS
319{
320 struct thread_info *tp;
321
322 /* If we can't find the thread, then we're debugging a single threaded
323 process. No need to do anything in that case. */
39f77062 324 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
325 if (tp == NULL)
326 return;
327
328 *prev_pc = tp->prev_pc;
6c0d3f6a 329 *trap_expected = tp->trap_expected;
c906108c
SS
330 *step_resume_breakpoint = tp->step_resume_breakpoint;
331 *step_range_start = tp->step_range_start;
332 *step_range_end = tp->step_range_end;
aa0cd9c1 333 *step_frame_id = tp->step_frame_id;
c906108c 334 *handling_longjmp = tp->handling_longjmp;
ca67fcb8 335 *stepping_over_breakpoint = tp->stepping_over_breakpoint;
6949171e
JJ
336 *stepping_through_solib_after_catch =
337 tp->stepping_through_solib_after_catch;
338 *stepping_through_solib_catchpoints =
339 tp->stepping_through_solib_catchpoints;
6c0d3f6a
MS
340 *current_line = tp->current_line;
341 *current_symtab = tp->current_symtab;
c906108c
SS
342}
343
344/* Save infrun state for the thread PID. */
345
c5aa993b 346void
6949171e
JJ
347save_infrun_state (ptid_t ptid,
348 CORE_ADDR prev_pc,
6c0d3f6a 349 int trap_expected,
fba45db2 350 struct breakpoint *step_resume_breakpoint,
6949171e 351 CORE_ADDR step_range_start,
6c0d3f6a 352 CORE_ADDR step_range_end,
6949171e 353 const struct frame_id *step_frame_id,
6c0d3f6a 354 int handling_longjmp,
ca67fcb8 355 int stepping_over_breakpoint,
6c0d3f6a 356 int stepping_through_solib_after_catch,
fba45db2 357 bpstat stepping_through_solib_catchpoints,
6c0d3f6a 358 int current_line,
f2c9ca08 359 struct symtab *current_symtab)
c906108c
SS
360{
361 struct thread_info *tp;
362
363 /* If we can't find the thread, then we're debugging a single-threaded
364 process. Nothing to do in that case. */
39f77062 365 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
366 if (tp == NULL)
367 return;
368
369 tp->prev_pc = prev_pc;
6c0d3f6a 370 tp->trap_expected = trap_expected;
c906108c
SS
371 tp->step_resume_breakpoint = step_resume_breakpoint;
372 tp->step_range_start = step_range_start;
373 tp->step_range_end = step_range_end;
aa0cd9c1 374 tp->step_frame_id = (*step_frame_id);
c906108c 375 tp->handling_longjmp = handling_longjmp;
ca67fcb8 376 tp->stepping_over_breakpoint = stepping_over_breakpoint;
c906108c
SS
377 tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
378 tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
6c0d3f6a
MS
379 tp->current_line = current_line;
380 tp->current_symtab = current_symtab;
c906108c
SS
381}
382
383/* Return true if TP is an active thread. */
384static int
fba45db2 385thread_alive (struct thread_info *tp)
c906108c 386{
39f77062 387 if (PIDGET (tp->ptid) == -1)
c906108c 388 return 0;
39f77062 389 if (!target_thread_alive (tp->ptid))
c906108c 390 {
39f77062 391 tp->ptid = pid_to_ptid (-1); /* Mark it as dead */
c906108c
SS
392 return 0;
393 }
394 return 1;
395}
396
397static void
fba45db2 398prune_threads (void)
c906108c 399{
d4f3574e 400 struct thread_info *tp, *next;
c906108c 401
c906108c
SS
402 for (tp = thread_list; tp; tp = next)
403 {
404 next = tp->next;
405 if (!thread_alive (tp))
39f77062 406 delete_thread (tp->ptid);
c906108c
SS
407 }
408}
409
8e8901c5
VP
410/* Prints the list of threads and their details on UIOUT.
411 This is a version of 'info_thread_command' suitable for
412 use from MI.
413 If REQESTED_THREAD is not -1, it's the GDB id of the thread
414 that should be printed. Otherwise, all threads are
415 printed. */
416void
417print_thread_info (struct ui_out *uiout, int requested_thread)
c906108c
SS
418{
419 struct thread_info *tp;
39f77062 420 ptid_t current_ptid;
c5aa993b 421 struct frame_info *cur_frame;
99b3d574
DP
422 struct cleanup *old_chain;
423 struct frame_id saved_frame_id;
0d06e24b 424 char *extra_info;
8e8901c5 425 int current_thread = -1;
c906108c 426
99b3d574
DP
427 /* Backup current thread and selected frame. */
428 saved_frame_id = get_frame_id (get_selected_frame (NULL));
429 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
430
8e8901c5
VP
431 make_cleanup_ui_out_list_begin_end (uiout, "threads");
432
c906108c 433 prune_threads ();
b83266a0 434 target_find_new_threads ();
39f77062 435 current_ptid = inferior_ptid;
c906108c
SS
436 for (tp = thread_list; tp; tp = tp->next)
437 {
8e8901c5
VP
438 struct cleanup *chain2;
439
440 if (requested_thread != -1 && tp->num != requested_thread)
441 continue;
442
443 chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
444
39f77062 445 if (ptid_equal (tp->ptid, current_ptid))
8e8901c5
VP
446 {
447 current_thread = tp->num;
448 ui_out_text (uiout, "* ");
449 }
c906108c 450 else
8e8901c5 451 ui_out_text (uiout, " ");
c906108c 452
8e8901c5
VP
453 ui_out_field_int (uiout, "id", tp->num);
454 ui_out_text (uiout, " ");
455 ui_out_field_string (uiout, "target-id", target_tid_to_str (tp->ptid));
0d06e24b
JM
456
457 extra_info = target_extra_thread_info (tp);
458 if (extra_info)
8e8901c5
VP
459 {
460 ui_out_text (uiout, " (");
461 ui_out_field_string (uiout, "details", extra_info);
462 ui_out_text (uiout, ")");
463 }
464 ui_out_text (uiout, " ");
99b3d574 465 /* That switch put us at the top of the stack (leaf frame). */
39f77062 466 switch_to_thread (tp->ptid);
8e8901c5
VP
467 print_stack_frame (get_selected_frame (NULL),
468 /* For MI output, print frame level. */
469 ui_out_is_mi_like_p (uiout),
470 LOCATION);
471
472 do_cleanups (chain2);
c906108c
SS
473 }
474
99b3d574
DP
475 /* Restores the current thread and the frame selected before
476 the "info threads" command. */
477 do_cleanups (old_chain);
c906108c 478
8e8901c5
VP
479 if (requested_thread == -1)
480 {
0bcd3e20
VP
481 gdb_assert (current_thread != -1 || !thread_list);
482 if (current_thread != -1 && ui_out_is_mi_like_p (uiout))
8e8901c5
VP
483 ui_out_field_int (uiout, "current-thread-id", current_thread);
484 }
485
99b3d574
DP
486 /* If case we were not able to find the original frame, print the
487 new selected frame. */
488 if (frame_find_by_id (saved_frame_id) == NULL)
c906108c 489 {
8a3fe4f8 490 warning (_("Couldn't restore frame in current thread, at frame 0"));
8e8901c5
VP
491 /* For MI, we should probably have a notification about
492 current frame change. But this error is not very likely, so
493 don't bother for now. */
494 if (!ui_out_is_mi_like_p (uiout))
495 print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
c906108c 496 }
c906108c
SS
497}
498
8e8901c5
VP
499
500/* Print information about currently known threads
501
502 * Note: this has the drawback that it _really_ switches
503 * threads, which frees the frame cache. A no-side
504 * effects info-threads command would be nicer.
505 */
506
507static void
508info_threads_command (char *arg, int from_tty)
509{
510 print_thread_info (uiout, -1);
511}
512
c906108c
SS
513/* Switch from one thread to another. */
514
6a6b96b9 515void
39f77062 516switch_to_thread (ptid_t ptid)
c906108c 517{
39f77062 518 if (ptid_equal (ptid, inferior_ptid))
c906108c
SS
519 return;
520
39f77062 521 inferior_ptid = ptid;
35f196d9 522 reinit_frame_cache ();
c906108c 523 registers_changed ();
c5aa993b 524 stop_pc = read_pc ();
c906108c
SS
525}
526
527static void
39f77062 528restore_current_thread (ptid_t ptid)
c906108c 529{
6949171e 530 if (!ptid_equal (ptid, inferior_ptid))
c906108c 531 {
39f77062 532 switch_to_thread (ptid);
99b3d574
DP
533 }
534}
535
536static void
537restore_selected_frame (struct frame_id a_frame_id)
538{
539 struct frame_info *selected_frame_info = NULL;
540
541 if (frame_id_eq (a_frame_id, null_frame_id))
542 return;
543
544 if ((selected_frame_info = frame_find_by_id (a_frame_id)) != NULL)
545 {
546 select_frame (selected_frame_info);
c906108c
SS
547 }
548}
549
6ecce94d
AC
550struct current_thread_cleanup
551{
39f77062 552 ptid_t inferior_ptid;
99b3d574 553 struct frame_id selected_frame_id;
6ecce94d
AC
554};
555
556static void
557do_restore_current_thread_cleanup (void *arg)
558{
559 struct current_thread_cleanup *old = arg;
39f77062 560 restore_current_thread (old->inferior_ptid);
99b3d574 561 restore_selected_frame (old->selected_frame_id);
b8c9b27d 562 xfree (old);
6ecce94d
AC
563}
564
565static struct cleanup *
99b3d574
DP
566make_cleanup_restore_current_thread (ptid_t inferior_ptid,
567 struct frame_id a_frame_id)
6ecce94d
AC
568{
569 struct current_thread_cleanup *old
570 = xmalloc (sizeof (struct current_thread_cleanup));
39f77062 571 old->inferior_ptid = inferior_ptid;
99b3d574 572 old->selected_frame_id = a_frame_id;
6ecce94d
AC
573 return make_cleanup (do_restore_current_thread_cleanup, old);
574}
575
c906108c
SS
576/* Apply a GDB command to a list of threads. List syntax is a whitespace
577 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
578 of two numbers seperated by a hyphen. Examples:
579
c5aa993b
JM
580 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
581 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
582 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
583 */
c906108c
SS
584
585static void
fba45db2 586thread_apply_all_command (char *cmd, int from_tty)
c906108c
SS
587{
588 struct thread_info *tp;
589 struct cleanup *old_chain;
e35ce267
CF
590 struct cleanup *saved_cmd_cleanup_chain;
591 char *saved_cmd;
99b3d574
DP
592 struct frame_id saved_frame_id;
593 ptid_t current_ptid;
594 int thread_has_changed = 0;
c906108c
SS
595
596 if (cmd == NULL || *cmd == '\000')
8a3fe4f8 597 error (_("Please specify a command following the thread ID list"));
99b3d574
DP
598
599 current_ptid = inferior_ptid;
600 saved_frame_id = get_frame_id (get_selected_frame (NULL));
601 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 602
e9d196c5
MS
603 /* It is safe to update the thread list now, before
604 traversing it for "thread apply all". MVS */
605 target_find_new_threads ();
606
e35ce267
CF
607 /* Save a copy of the command in case it is clobbered by
608 execute_command */
5b616ba1 609 saved_cmd = xstrdup (cmd);
b8c9b27d 610 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
611 for (tp = thread_list; tp; tp = tp->next)
612 if (thread_alive (tp))
613 {
39f77062 614 switch_to_thread (tp->ptid);
a3f17187 615 printf_filtered (_("\nThread %d (%s):\n"),
6949171e 616 tp->num, target_tid_to_str (inferior_ptid));
c906108c 617 execute_command (cmd, from_tty);
6949171e 618 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c 619 }
6ecce94d 620
99b3d574
DP
621 if (!ptid_equal (current_ptid, inferior_ptid))
622 thread_has_changed = 1;
623
e35ce267 624 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 625 do_cleanups (old_chain);
99b3d574
DP
626 /* Print stack frame only if we changed thread. */
627 if (thread_has_changed)
628 print_stack_frame (get_current_frame (), 1, SRC_LINE);
629
c906108c
SS
630}
631
632static void
fba45db2 633thread_apply_command (char *tidlist, int from_tty)
c906108c
SS
634{
635 char *cmd;
636 char *p;
637 struct cleanup *old_chain;
e35ce267
CF
638 struct cleanup *saved_cmd_cleanup_chain;
639 char *saved_cmd;
99b3d574
DP
640 struct frame_id saved_frame_id;
641 ptid_t current_ptid;
642 int thread_has_changed = 0;
c906108c
SS
643
644 if (tidlist == NULL || *tidlist == '\000')
8a3fe4f8 645 error (_("Please specify a thread ID list"));
c906108c 646
c5aa993b 647 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
648
649 if (*cmd == '\000')
8a3fe4f8 650 error (_("Please specify a command following the thread ID list"));
c906108c 651
99b3d574
DP
652 current_ptid = inferior_ptid;
653 saved_frame_id = get_frame_id (get_selected_frame (NULL));
654 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 655
e35ce267
CF
656 /* Save a copy of the command in case it is clobbered by
657 execute_command */
5b616ba1 658 saved_cmd = xstrdup (cmd);
b8c9b27d 659 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
660 while (tidlist < cmd)
661 {
662 struct thread_info *tp;
663 int start, end;
664
665 start = strtol (tidlist, &p, 10);
666 if (p == tidlist)
8a3fe4f8 667 error (_("Error parsing %s"), tidlist);
c906108c
SS
668 tidlist = p;
669
670 while (*tidlist == ' ' || *tidlist == '\t')
671 tidlist++;
672
673 if (*tidlist == '-') /* Got a range of IDs? */
674 {
c5aa993b 675 tidlist++; /* Skip the - */
c906108c
SS
676 end = strtol (tidlist, &p, 10);
677 if (p == tidlist)
8a3fe4f8 678 error (_("Error parsing %s"), tidlist);
c906108c
SS
679 tidlist = p;
680
681 while (*tidlist == ' ' || *tidlist == '\t')
682 tidlist++;
683 }
684 else
685 end = start;
686
687 for (; start <= end; start++)
688 {
689 tp = find_thread_id (start);
690
691 if (!tp)
8a3fe4f8 692 warning (_("Unknown thread %d."), start);
c906108c 693 else if (!thread_alive (tp))
8a3fe4f8 694 warning (_("Thread %d has terminated."), start);
c906108c
SS
695 else
696 {
39f77062 697 switch_to_thread (tp->ptid);
a3f17187 698 printf_filtered (_("\nThread %d (%s):\n"), tp->num,
39f77062 699 target_tid_to_str (inferior_ptid));
c906108c 700 execute_command (cmd, from_tty);
e35ce267 701 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c
SS
702 }
703 }
704 }
6ecce94d 705
99b3d574
DP
706 if (!ptid_equal (current_ptid, inferior_ptid))
707 thread_has_changed = 1;
708
e35ce267 709 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 710 do_cleanups (old_chain);
99b3d574
DP
711 /* Print stack frame only if we changed thread. */
712 if (thread_has_changed)
713 print_stack_frame (get_current_frame (), 1, SRC_LINE);
c906108c
SS
714}
715
716/* Switch to the specified thread. Will dispatch off to thread_apply_command
717 if prefix of arg is `apply'. */
718
719static void
fba45db2 720thread_command (char *tidstr, int from_tty)
c906108c 721{
c906108c
SS
722 if (!tidstr)
723 {
724 /* Don't generate an error, just say which thread is current. */
725 if (target_has_stack)
a3f17187 726 printf_filtered (_("[Current thread is %d (%s)]\n"),
39f77062 727 pid_to_thread_id (inferior_ptid),
007d08bb 728 target_tid_to_str (inferior_ptid));
c906108c 729 else
8a3fe4f8 730 error (_("No stack."));
c906108c
SS
731 return;
732 }
c5394b80 733
ce43223b 734 gdb_thread_select (uiout, tidstr, NULL);
c5394b80
JM
735}
736
93815fbf
VP
737/* Print notices when new threads are attached and detached. */
738int print_thread_events = 1;
739static void
740show_print_thread_events (struct ui_file *file, int from_tty,
741 struct cmd_list_element *c, const char *value)
742{
743 fprintf_filtered (file, _("\
744Printing of thread events is %s.\n"),
745 value);
746}
747
c5394b80 748static int
6949171e 749do_captured_thread_select (struct ui_out *uiout, void *tidstr)
c5394b80
JM
750{
751 int num;
752 struct thread_info *tp;
753
81490ea1 754 num = value_as_long (parse_and_eval (tidstr));
c906108c
SS
755
756 tp = find_thread_id (num);
757
8b93c638 758 if (!tp)
8a3fe4f8 759 error (_("Thread ID %d not known."), num);
c906108c
SS
760
761 if (!thread_alive (tp))
8a3fe4f8 762 error (_("Thread ID %d has terminated."), num);
c906108c 763
39f77062 764 switch_to_thread (tp->ptid);
c906108c 765
8b93c638 766 ui_out_text (uiout, "[Switching to thread ");
39f77062 767 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
8b93c638 768 ui_out_text (uiout, " (");
39f77062 769 ui_out_text (uiout, target_tid_to_str (inferior_ptid));
8b93c638 770 ui_out_text (uiout, ")]");
c5394b80 771
b04f3ab4 772 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
c5394b80
JM
773 return GDB_RC_OK;
774}
775
776enum gdb_rc
ce43223b 777gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
c5394b80 778{
b0b13bb4
DJ
779 if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr,
780 error_message, RETURN_MASK_ALL) < 0)
781 return GDB_RC_FAIL;
782 return GDB_RC_OK;
c906108c
SS
783}
784
785/* Commands with a prefix of `thread'. */
786struct cmd_list_element *thread_cmd_list = NULL;
787
788void
fba45db2 789_initialize_thread (void)
c906108c
SS
790{
791 static struct cmd_list_element *thread_apply_list = NULL;
c906108c
SS
792
793 add_info ("threads", info_threads_command,
1bedd215 794 _("IDs of currently known threads."));
c906108c 795
1bedd215
AC
796 add_prefix_cmd ("thread", class_run, thread_command, _("\
797Use this command to switch between threads.\n\
798The new thread ID must be currently known."),
799 &thread_cmd_list, "thread ", 1, &cmdlist);
c906108c
SS
800
801 add_prefix_cmd ("apply", class_run, thread_apply_command,
1bedd215 802 _("Apply a command to a list of threads."),
ad21ceb0 803 &thread_apply_list, "thread apply ", 1, &thread_cmd_list);
c906108c
SS
804
805 add_cmd ("all", class_run, thread_apply_all_command,
1a966eab 806 _("Apply a command to all threads."), &thread_apply_list);
c906108c
SS
807
808 if (!xdb_commands)
809 add_com_alias ("t", "thread", class_run, 1);
93815fbf
VP
810
811 add_setshow_boolean_cmd ("thread-events", no_class,
812 &print_thread_events, _("\
813Set printing of thread events (e.g., thread start and exit)."), _("\
814Show printing of thread events (e.g., thread start and exit)."), NULL,
815 NULL,
816 show_print_thread_events,
817 &setprintlist, &showprintlist);
c906108c 818}
This page took 0.783169 seconds and 4 git commands to generate.