2008-06-21 Hui Zhu <teawater@gmail.com>
[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
20874c92
VP
232int
233thread_count (void)
234{
235 int result = 0;
236 struct thread_info *tp;
237
238 for (tp = thread_list; tp; tp = tp->next)
239 ++result;
240
241 return result;
242}
243
c906108c 244int
fba45db2 245valid_thread_id (int num)
c906108c
SS
246{
247 struct thread_info *tp;
248
249 for (tp = thread_list; tp; tp = tp->next)
250 if (tp->num == num)
251 return 1;
252
253 return 0;
254}
255
256int
39f77062 257pid_to_thread_id (ptid_t ptid)
c906108c
SS
258{
259 struct thread_info *tp;
260
261 for (tp = thread_list; tp; tp = tp->next)
39f77062 262 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
263 return tp->num;
264
265 return 0;
266}
267
39f77062 268ptid_t
fba45db2 269thread_id_to_pid (int num)
c906108c
SS
270{
271 struct thread_info *thread = find_thread_id (num);
272 if (thread)
39f77062 273 return thread->ptid;
c906108c 274 else
39f77062 275 return pid_to_ptid (-1);
c906108c
SS
276}
277
278int
39f77062 279in_thread_list (ptid_t ptid)
c906108c
SS
280{
281 struct thread_info *tp;
282
283 for (tp = thread_list; tp; tp = tp->next)
39f77062 284 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
285 return 1;
286
287 return 0; /* Never heard of 'im */
288}
8926118c 289
8b93c638
JM
290/* Print a list of thread ids currently known, and the total number of
291 threads. To be used from within catch_errors. */
6949171e
JJ
292static int
293do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
8b93c638
JM
294{
295 struct thread_info *tp;
296 int num = 0;
3b31d625 297 struct cleanup *cleanup_chain;
8b93c638 298
7990a578
EZ
299 prune_threads ();
300 target_find_new_threads ();
301
3b31d625 302 cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids");
8b93c638
JM
303
304 for (tp = thread_list; tp; tp = tp->next)
305 {
306 num++;
307 ui_out_field_int (uiout, "thread-id", tp->num);
308 }
309
3b31d625 310 do_cleanups (cleanup_chain);
8b93c638
JM
311 ui_out_field_int (uiout, "number-of-threads", num);
312 return GDB_RC_OK;
313}
314
315/* Official gdblib interface function to get a list of thread ids and
316 the total number. */
317enum gdb_rc
ce43223b 318gdb_list_thread_ids (struct ui_out *uiout, char **error_message)
8b93c638 319{
b0b13bb4
DJ
320 if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL,
321 error_message, RETURN_MASK_ALL) < 0)
322 return GDB_RC_FAIL;
323 return GDB_RC_OK;
8b93c638 324}
c906108c
SS
325
326/* Load infrun state for the thread PID. */
327
c5aa993b 328void
6949171e
JJ
329load_infrun_state (ptid_t ptid,
330 CORE_ADDR *prev_pc,
6c0d3f6a 331 int *trap_expected,
fba45db2 332 struct breakpoint **step_resume_breakpoint,
6949171e 333 CORE_ADDR *step_range_start,
6c0d3f6a 334 CORE_ADDR *step_range_end,
6949171e 335 struct frame_id *step_frame_id,
ca67fcb8 336 int *stepping_over_breakpoint,
6c0d3f6a 337 int *stepping_through_solib_after_catch,
fba45db2 338 bpstat *stepping_through_solib_catchpoints,
6949171e 339 int *current_line,
f2c9ca08 340 struct symtab **current_symtab)
c906108c
SS
341{
342 struct thread_info *tp;
343
344 /* If we can't find the thread, then we're debugging a single threaded
345 process. No need to do anything in that case. */
39f77062 346 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
347 if (tp == NULL)
348 return;
349
350 *prev_pc = tp->prev_pc;
6c0d3f6a 351 *trap_expected = tp->trap_expected;
c906108c
SS
352 *step_resume_breakpoint = tp->step_resume_breakpoint;
353 *step_range_start = tp->step_range_start;
354 *step_range_end = tp->step_range_end;
aa0cd9c1 355 *step_frame_id = tp->step_frame_id;
ca67fcb8 356 *stepping_over_breakpoint = tp->stepping_over_breakpoint;
6949171e
JJ
357 *stepping_through_solib_after_catch =
358 tp->stepping_through_solib_after_catch;
359 *stepping_through_solib_catchpoints =
360 tp->stepping_through_solib_catchpoints;
6c0d3f6a
MS
361 *current_line = tp->current_line;
362 *current_symtab = tp->current_symtab;
c906108c
SS
363}
364
365/* Save infrun state for the thread PID. */
366
c5aa993b 367void
6949171e
JJ
368save_infrun_state (ptid_t ptid,
369 CORE_ADDR prev_pc,
6c0d3f6a 370 int trap_expected,
fba45db2 371 struct breakpoint *step_resume_breakpoint,
6949171e 372 CORE_ADDR step_range_start,
6c0d3f6a 373 CORE_ADDR step_range_end,
6949171e 374 const struct frame_id *step_frame_id,
ca67fcb8 375 int stepping_over_breakpoint,
6c0d3f6a 376 int stepping_through_solib_after_catch,
fba45db2 377 bpstat stepping_through_solib_catchpoints,
6c0d3f6a 378 int current_line,
f2c9ca08 379 struct symtab *current_symtab)
c906108c
SS
380{
381 struct thread_info *tp;
382
383 /* If we can't find the thread, then we're debugging a single-threaded
384 process. Nothing to do in that case. */
39f77062 385 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
386 if (tp == NULL)
387 return;
388
389 tp->prev_pc = prev_pc;
6c0d3f6a 390 tp->trap_expected = trap_expected;
c906108c
SS
391 tp->step_resume_breakpoint = step_resume_breakpoint;
392 tp->step_range_start = step_range_start;
393 tp->step_range_end = step_range_end;
aa0cd9c1 394 tp->step_frame_id = (*step_frame_id);
ca67fcb8 395 tp->stepping_over_breakpoint = stepping_over_breakpoint;
c906108c
SS
396 tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
397 tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
6c0d3f6a
MS
398 tp->current_line = current_line;
399 tp->current_symtab = current_symtab;
c906108c
SS
400}
401
402/* Return true if TP is an active thread. */
403static int
fba45db2 404thread_alive (struct thread_info *tp)
c906108c 405{
39f77062 406 if (PIDGET (tp->ptid) == -1)
c906108c 407 return 0;
39f77062 408 if (!target_thread_alive (tp->ptid))
c906108c 409 {
39f77062 410 tp->ptid = pid_to_ptid (-1); /* Mark it as dead */
c906108c
SS
411 return 0;
412 }
413 return 1;
414}
415
416static void
fba45db2 417prune_threads (void)
c906108c 418{
d4f3574e 419 struct thread_info *tp, *next;
c906108c 420
c906108c
SS
421 for (tp = thread_list; tp; tp = next)
422 {
423 next = tp->next;
424 if (!thread_alive (tp))
39f77062 425 delete_thread (tp->ptid);
c906108c
SS
426 }
427}
428
e1ac3328
VP
429static int main_thread_running = 0;
430
431void
432set_running (ptid_t ptid, int running)
433{
434 struct thread_info *tp;
435
436 if (!thread_list)
437 {
438 /* This is one of the targets that does not add main
439 thread to the thread list. Just use a single
440 global flag to indicate that a thread is running.
441
442 This problem is unique to ST programs. For MT programs,
443 the main thread is always present in the thread list. If it's
444 not, the first call to context_switch will mess up GDB internal
445 state. */
8f6a8e84 446 if (running && !main_thread_running && !suppress_resume_observer)
e1ac3328
VP
447 observer_notify_target_resumed (ptid);
448 main_thread_running = running;
449 return;
450 }
451
452 /* We try not to notify the observer if no thread has actually changed
453 the running state -- merely to reduce the number of messages to
454 frontend. Frontend is supposed to handle multiple *running just fine. */
455 if (PIDGET (ptid) == -1)
456 {
457 int any_started = 0;
458 for (tp = thread_list; tp; tp = tp->next)
459 {
460 if (running && !tp->running_)
461 any_started = 1;
462 tp->running_ = running;
463 }
8f6a8e84 464 if (any_started && !suppress_resume_observer)
e1ac3328
VP
465 observer_notify_target_resumed (ptid);
466 }
467 else
468 {
469 tp = find_thread_pid (ptid);
470 gdb_assert (tp);
8f6a8e84 471 if (running && !tp->running_ && !suppress_resume_observer)
e1ac3328
VP
472 observer_notify_target_resumed (ptid);
473 tp->running_ = running;
474 }
475}
476
477int
478is_running (ptid_t ptid)
479{
480 struct thread_info *tp;
481
482 if (!thread_list)
483 return main_thread_running;
484
485 tp = find_thread_pid (ptid);
486 gdb_assert (tp);
487 return tp->running_;
488}
489
8e8901c5
VP
490/* Prints the list of threads and their details on UIOUT.
491 This is a version of 'info_thread_command' suitable for
492 use from MI.
493 If REQESTED_THREAD is not -1, it's the GDB id of the thread
494 that should be printed. Otherwise, all threads are
495 printed. */
496void
497print_thread_info (struct ui_out *uiout, int requested_thread)
c906108c
SS
498{
499 struct thread_info *tp;
39f77062 500 ptid_t current_ptid;
c5aa993b 501 struct frame_info *cur_frame;
99b3d574
DP
502 struct cleanup *old_chain;
503 struct frame_id saved_frame_id;
0d06e24b 504 char *extra_info;
8e8901c5 505 int current_thread = -1;
c906108c 506
99b3d574
DP
507 /* Backup current thread and selected frame. */
508 saved_frame_id = get_frame_id (get_selected_frame (NULL));
509 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
510
8e8901c5
VP
511 make_cleanup_ui_out_list_begin_end (uiout, "threads");
512
c906108c 513 prune_threads ();
b83266a0 514 target_find_new_threads ();
39f77062 515 current_ptid = inferior_ptid;
c906108c
SS
516 for (tp = thread_list; tp; tp = tp->next)
517 {
8e8901c5
VP
518 struct cleanup *chain2;
519
520 if (requested_thread != -1 && tp->num != requested_thread)
521 continue;
522
523 chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
524
39f77062 525 if (ptid_equal (tp->ptid, current_ptid))
8e8901c5
VP
526 {
527 current_thread = tp->num;
528 ui_out_text (uiout, "* ");
529 }
c906108c 530 else
8e8901c5 531 ui_out_text (uiout, " ");
c906108c 532
8e8901c5
VP
533 ui_out_field_int (uiout, "id", tp->num);
534 ui_out_text (uiout, " ");
535 ui_out_field_string (uiout, "target-id", target_tid_to_str (tp->ptid));
0d06e24b
JM
536
537 extra_info = target_extra_thread_info (tp);
538 if (extra_info)
8e8901c5
VP
539 {
540 ui_out_text (uiout, " (");
541 ui_out_field_string (uiout, "details", extra_info);
542 ui_out_text (uiout, ")");
543 }
544 ui_out_text (uiout, " ");
99b3d574 545 /* That switch put us at the top of the stack (leaf frame). */
39f77062 546 switch_to_thread (tp->ptid);
8e8901c5
VP
547 print_stack_frame (get_selected_frame (NULL),
548 /* For MI output, print frame level. */
549 ui_out_is_mi_like_p (uiout),
550 LOCATION);
551
552 do_cleanups (chain2);
c906108c
SS
553 }
554
99b3d574
DP
555 /* Restores the current thread and the frame selected before
556 the "info threads" command. */
557 do_cleanups (old_chain);
c906108c 558
8e8901c5
VP
559 if (requested_thread == -1)
560 {
0bcd3e20
VP
561 gdb_assert (current_thread != -1 || !thread_list);
562 if (current_thread != -1 && ui_out_is_mi_like_p (uiout))
8e8901c5
VP
563 ui_out_field_int (uiout, "current-thread-id", current_thread);
564 }
565
99b3d574
DP
566 /* If case we were not able to find the original frame, print the
567 new selected frame. */
568 if (frame_find_by_id (saved_frame_id) == NULL)
c906108c 569 {
8a3fe4f8 570 warning (_("Couldn't restore frame in current thread, at frame 0"));
8e8901c5
VP
571 /* For MI, we should probably have a notification about
572 current frame change. But this error is not very likely, so
573 don't bother for now. */
574 if (!ui_out_is_mi_like_p (uiout))
575 print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
c906108c 576 }
c906108c
SS
577}
578
8e8901c5
VP
579
580/* Print information about currently known threads
581
582 * Note: this has the drawback that it _really_ switches
583 * threads, which frees the frame cache. A no-side
584 * effects info-threads command would be nicer.
585 */
586
587static void
588info_threads_command (char *arg, int from_tty)
589{
590 print_thread_info (uiout, -1);
591}
592
c906108c
SS
593/* Switch from one thread to another. */
594
6a6b96b9 595void
39f77062 596switch_to_thread (ptid_t ptid)
c906108c 597{
39f77062 598 if (ptid_equal (ptid, inferior_ptid))
c906108c
SS
599 return;
600
39f77062 601 inferior_ptid = ptid;
35f196d9 602 reinit_frame_cache ();
c906108c 603 registers_changed ();
c5aa993b 604 stop_pc = read_pc ();
c906108c
SS
605}
606
607static void
39f77062 608restore_current_thread (ptid_t ptid)
c906108c 609{
6949171e 610 if (!ptid_equal (ptid, inferior_ptid))
c906108c 611 {
39f77062 612 switch_to_thread (ptid);
99b3d574
DP
613 }
614}
615
616static void
617restore_selected_frame (struct frame_id a_frame_id)
618{
619 struct frame_info *selected_frame_info = NULL;
620
621 if (frame_id_eq (a_frame_id, null_frame_id))
622 return;
623
624 if ((selected_frame_info = frame_find_by_id (a_frame_id)) != NULL)
625 {
626 select_frame (selected_frame_info);
c906108c
SS
627 }
628}
629
6ecce94d
AC
630struct current_thread_cleanup
631{
39f77062 632 ptid_t inferior_ptid;
99b3d574 633 struct frame_id selected_frame_id;
6ecce94d
AC
634};
635
636static void
637do_restore_current_thread_cleanup (void *arg)
638{
639 struct current_thread_cleanup *old = arg;
39f77062 640 restore_current_thread (old->inferior_ptid);
99b3d574 641 restore_selected_frame (old->selected_frame_id);
b8c9b27d 642 xfree (old);
6ecce94d
AC
643}
644
6208b47d 645struct cleanup *
99b3d574
DP
646make_cleanup_restore_current_thread (ptid_t inferior_ptid,
647 struct frame_id a_frame_id)
6ecce94d
AC
648{
649 struct current_thread_cleanup *old
650 = xmalloc (sizeof (struct current_thread_cleanup));
39f77062 651 old->inferior_ptid = inferior_ptid;
99b3d574 652 old->selected_frame_id = a_frame_id;
6ecce94d
AC
653 return make_cleanup (do_restore_current_thread_cleanup, old);
654}
655
c906108c
SS
656/* Apply a GDB command to a list of threads. List syntax is a whitespace
657 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
658 of two numbers seperated by a hyphen. Examples:
659
c5aa993b
JM
660 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
661 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
662 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
663 */
c906108c
SS
664
665static void
fba45db2 666thread_apply_all_command (char *cmd, int from_tty)
c906108c
SS
667{
668 struct thread_info *tp;
669 struct cleanup *old_chain;
e35ce267
CF
670 struct cleanup *saved_cmd_cleanup_chain;
671 char *saved_cmd;
99b3d574
DP
672 struct frame_id saved_frame_id;
673 ptid_t current_ptid;
674 int thread_has_changed = 0;
c906108c
SS
675
676 if (cmd == NULL || *cmd == '\000')
8a3fe4f8 677 error (_("Please specify a command following the thread ID list"));
99b3d574
DP
678
679 current_ptid = inferior_ptid;
680 saved_frame_id = get_frame_id (get_selected_frame (NULL));
681 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 682
e9d196c5
MS
683 /* It is safe to update the thread list now, before
684 traversing it for "thread apply all". MVS */
685 target_find_new_threads ();
686
e35ce267
CF
687 /* Save a copy of the command in case it is clobbered by
688 execute_command */
5b616ba1 689 saved_cmd = xstrdup (cmd);
b8c9b27d 690 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
691 for (tp = thread_list; tp; tp = tp->next)
692 if (thread_alive (tp))
693 {
39f77062 694 switch_to_thread (tp->ptid);
a3f17187 695 printf_filtered (_("\nThread %d (%s):\n"),
6949171e 696 tp->num, target_tid_to_str (inferior_ptid));
c906108c 697 execute_command (cmd, from_tty);
6949171e 698 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c 699 }
6ecce94d 700
99b3d574
DP
701 if (!ptid_equal (current_ptid, inferior_ptid))
702 thread_has_changed = 1;
703
e35ce267 704 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 705 do_cleanups (old_chain);
99b3d574
DP
706 /* Print stack frame only if we changed thread. */
707 if (thread_has_changed)
708 print_stack_frame (get_current_frame (), 1, SRC_LINE);
709
c906108c
SS
710}
711
712static void
fba45db2 713thread_apply_command (char *tidlist, int from_tty)
c906108c
SS
714{
715 char *cmd;
716 char *p;
717 struct cleanup *old_chain;
e35ce267
CF
718 struct cleanup *saved_cmd_cleanup_chain;
719 char *saved_cmd;
99b3d574
DP
720 struct frame_id saved_frame_id;
721 ptid_t current_ptid;
722 int thread_has_changed = 0;
c906108c
SS
723
724 if (tidlist == NULL || *tidlist == '\000')
8a3fe4f8 725 error (_("Please specify a thread ID list"));
c906108c 726
c5aa993b 727 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
728
729 if (*cmd == '\000')
8a3fe4f8 730 error (_("Please specify a command following the thread ID list"));
c906108c 731
99b3d574
DP
732 current_ptid = inferior_ptid;
733 saved_frame_id = get_frame_id (get_selected_frame (NULL));
734 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 735
e35ce267
CF
736 /* Save a copy of the command in case it is clobbered by
737 execute_command */
5b616ba1 738 saved_cmd = xstrdup (cmd);
b8c9b27d 739 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
740 while (tidlist < cmd)
741 {
742 struct thread_info *tp;
743 int start, end;
744
745 start = strtol (tidlist, &p, 10);
746 if (p == tidlist)
8a3fe4f8 747 error (_("Error parsing %s"), tidlist);
c906108c
SS
748 tidlist = p;
749
750 while (*tidlist == ' ' || *tidlist == '\t')
751 tidlist++;
752
753 if (*tidlist == '-') /* Got a range of IDs? */
754 {
c5aa993b 755 tidlist++; /* Skip the - */
c906108c
SS
756 end = strtol (tidlist, &p, 10);
757 if (p == tidlist)
8a3fe4f8 758 error (_("Error parsing %s"), tidlist);
c906108c
SS
759 tidlist = p;
760
761 while (*tidlist == ' ' || *tidlist == '\t')
762 tidlist++;
763 }
764 else
765 end = start;
766
767 for (; start <= end; start++)
768 {
769 tp = find_thread_id (start);
770
771 if (!tp)
8a3fe4f8 772 warning (_("Unknown thread %d."), start);
c906108c 773 else if (!thread_alive (tp))
8a3fe4f8 774 warning (_("Thread %d has terminated."), start);
c906108c
SS
775 else
776 {
39f77062 777 switch_to_thread (tp->ptid);
a3f17187 778 printf_filtered (_("\nThread %d (%s):\n"), tp->num,
39f77062 779 target_tid_to_str (inferior_ptid));
c906108c 780 execute_command (cmd, from_tty);
e35ce267 781 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c
SS
782 }
783 }
784 }
6ecce94d 785
99b3d574
DP
786 if (!ptid_equal (current_ptid, inferior_ptid))
787 thread_has_changed = 1;
788
e35ce267 789 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 790 do_cleanups (old_chain);
99b3d574
DP
791 /* Print stack frame only if we changed thread. */
792 if (thread_has_changed)
793 print_stack_frame (get_current_frame (), 1, SRC_LINE);
c906108c
SS
794}
795
796/* Switch to the specified thread. Will dispatch off to thread_apply_command
797 if prefix of arg is `apply'. */
798
799static void
fba45db2 800thread_command (char *tidstr, int from_tty)
c906108c 801{
c906108c
SS
802 if (!tidstr)
803 {
804 /* Don't generate an error, just say which thread is current. */
805 if (target_has_stack)
a3f17187 806 printf_filtered (_("[Current thread is %d (%s)]\n"),
39f77062 807 pid_to_thread_id (inferior_ptid),
007d08bb 808 target_tid_to_str (inferior_ptid));
c906108c 809 else
8a3fe4f8 810 error (_("No stack."));
c906108c
SS
811 return;
812 }
c5394b80 813
b8fa951a 814 annotate_thread_changed ();
ce43223b 815 gdb_thread_select (uiout, tidstr, NULL);
c5394b80
JM
816}
817
93815fbf
VP
818/* Print notices when new threads are attached and detached. */
819int print_thread_events = 1;
820static void
821show_print_thread_events (struct ui_file *file, int from_tty,
822 struct cmd_list_element *c, const char *value)
823{
824 fprintf_filtered (file, _("\
825Printing of thread events is %s.\n"),
826 value);
827}
828
c5394b80 829static int
6949171e 830do_captured_thread_select (struct ui_out *uiout, void *tidstr)
c5394b80
JM
831{
832 int num;
833 struct thread_info *tp;
834
81490ea1 835 num = value_as_long (parse_and_eval (tidstr));
c906108c
SS
836
837 tp = find_thread_id (num);
838
8b93c638 839 if (!tp)
8a3fe4f8 840 error (_("Thread ID %d not known."), num);
c906108c
SS
841
842 if (!thread_alive (tp))
8a3fe4f8 843 error (_("Thread ID %d has terminated."), num);
c906108c 844
39f77062 845 switch_to_thread (tp->ptid);
c906108c 846
8b93c638 847 ui_out_text (uiout, "[Switching to thread ");
39f77062 848 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
8b93c638 849 ui_out_text (uiout, " (");
39f77062 850 ui_out_text (uiout, target_tid_to_str (inferior_ptid));
8b93c638 851 ui_out_text (uiout, ")]");
c5394b80 852
b04f3ab4 853 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
c5394b80
JM
854 return GDB_RC_OK;
855}
856
857enum gdb_rc
ce43223b 858gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
c5394b80 859{
b0b13bb4
DJ
860 if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr,
861 error_message, RETURN_MASK_ALL) < 0)
862 return GDB_RC_FAIL;
863 return GDB_RC_OK;
c906108c
SS
864}
865
866/* Commands with a prefix of `thread'. */
867struct cmd_list_element *thread_cmd_list = NULL;
868
869void
fba45db2 870_initialize_thread (void)
c906108c
SS
871{
872 static struct cmd_list_element *thread_apply_list = NULL;
c906108c
SS
873
874 add_info ("threads", info_threads_command,
1bedd215 875 _("IDs of currently known threads."));
c906108c 876
1bedd215
AC
877 add_prefix_cmd ("thread", class_run, thread_command, _("\
878Use this command to switch between threads.\n\
879The new thread ID must be currently known."),
880 &thread_cmd_list, "thread ", 1, &cmdlist);
c906108c
SS
881
882 add_prefix_cmd ("apply", class_run, thread_apply_command,
1bedd215 883 _("Apply a command to a list of threads."),
ad21ceb0 884 &thread_apply_list, "thread apply ", 1, &thread_cmd_list);
c906108c
SS
885
886 add_cmd ("all", class_run, thread_apply_all_command,
1a966eab 887 _("Apply a command to all threads."), &thread_apply_list);
c906108c
SS
888
889 if (!xdb_commands)
890 add_com_alias ("t", "thread", class_run, 1);
93815fbf
VP
891
892 add_setshow_boolean_cmd ("thread-events", no_class,
893 &print_thread_events, _("\
11c68c47
EZ
894Set printing of thread events (such as thread start and exit)."), _("\
895Show printing of thread events (such as thread start and exit)."), NULL,
93815fbf
VP
896 NULL,
897 show_print_thread_events,
898 &setprintlist, &showprintlist);
c906108c 899}
This page took 0.826053 seconds and 4 git commands to generate.