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