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