* score-tdep.c (score_print_insn): Get the current endianess from
[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
8e8901c5
VP
417/* Prints the list of threads and their details on UIOUT.
418 This is a version of 'info_thread_command' suitable for
419 use from MI.
420 If REQESTED_THREAD is not -1, it's the GDB id of the thread
421 that should be printed. Otherwise, all threads are
422 printed. */
423void
424print_thread_info (struct ui_out *uiout, int requested_thread)
c906108c
SS
425{
426 struct thread_info *tp;
39f77062 427 ptid_t current_ptid;
c5aa993b 428 struct frame_info *cur_frame;
99b3d574
DP
429 struct cleanup *old_chain;
430 struct frame_id saved_frame_id;
0d06e24b 431 char *extra_info;
8e8901c5 432 int current_thread = -1;
c906108c 433
99b3d574
DP
434 /* Backup current thread and selected frame. */
435 saved_frame_id = get_frame_id (get_selected_frame (NULL));
436 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
437
8e8901c5
VP
438 make_cleanup_ui_out_list_begin_end (uiout, "threads");
439
c906108c 440 prune_threads ();
b83266a0 441 target_find_new_threads ();
39f77062 442 current_ptid = inferior_ptid;
c906108c
SS
443 for (tp = thread_list; tp; tp = tp->next)
444 {
8e8901c5
VP
445 struct cleanup *chain2;
446
447 if (requested_thread != -1 && tp->num != requested_thread)
448 continue;
449
450 chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
451
39f77062 452 if (ptid_equal (tp->ptid, current_ptid))
8e8901c5
VP
453 {
454 current_thread = tp->num;
455 ui_out_text (uiout, "* ");
456 }
c906108c 457 else
8e8901c5 458 ui_out_text (uiout, " ");
c906108c 459
8e8901c5
VP
460 ui_out_field_int (uiout, "id", tp->num);
461 ui_out_text (uiout, " ");
462 ui_out_field_string (uiout, "target-id", target_tid_to_str (tp->ptid));
0d06e24b
JM
463
464 extra_info = target_extra_thread_info (tp);
465 if (extra_info)
8e8901c5
VP
466 {
467 ui_out_text (uiout, " (");
468 ui_out_field_string (uiout, "details", extra_info);
469 ui_out_text (uiout, ")");
470 }
471 ui_out_text (uiout, " ");
99b3d574 472 /* That switch put us at the top of the stack (leaf frame). */
39f77062 473 switch_to_thread (tp->ptid);
8e8901c5
VP
474 print_stack_frame (get_selected_frame (NULL),
475 /* For MI output, print frame level. */
476 ui_out_is_mi_like_p (uiout),
477 LOCATION);
478
479 do_cleanups (chain2);
c906108c
SS
480 }
481
99b3d574
DP
482 /* Restores the current thread and the frame selected before
483 the "info threads" command. */
484 do_cleanups (old_chain);
c906108c 485
8e8901c5
VP
486 if (requested_thread == -1)
487 {
0bcd3e20
VP
488 gdb_assert (current_thread != -1 || !thread_list);
489 if (current_thread != -1 && ui_out_is_mi_like_p (uiout))
8e8901c5
VP
490 ui_out_field_int (uiout, "current-thread-id", current_thread);
491 }
492
99b3d574
DP
493 /* If case we were not able to find the original frame, print the
494 new selected frame. */
495 if (frame_find_by_id (saved_frame_id) == NULL)
c906108c 496 {
8a3fe4f8 497 warning (_("Couldn't restore frame in current thread, at frame 0"));
8e8901c5
VP
498 /* For MI, we should probably have a notification about
499 current frame change. But this error is not very likely, so
500 don't bother for now. */
501 if (!ui_out_is_mi_like_p (uiout))
502 print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
c906108c 503 }
c906108c
SS
504}
505
8e8901c5
VP
506
507/* Print information about currently known threads
508
509 * Note: this has the drawback that it _really_ switches
510 * threads, which frees the frame cache. A no-side
511 * effects info-threads command would be nicer.
512 */
513
514static void
515info_threads_command (char *arg, int from_tty)
516{
517 print_thread_info (uiout, -1);
518}
519
c906108c
SS
520/* Switch from one thread to another. */
521
6a6b96b9 522void
39f77062 523switch_to_thread (ptid_t ptid)
c906108c 524{
39f77062 525 if (ptid_equal (ptid, inferior_ptid))
c906108c
SS
526 return;
527
39f77062 528 inferior_ptid = ptid;
35f196d9 529 reinit_frame_cache ();
c906108c 530 registers_changed ();
c5aa993b 531 stop_pc = read_pc ();
c906108c
SS
532}
533
534static void
39f77062 535restore_current_thread (ptid_t ptid)
c906108c 536{
6949171e 537 if (!ptid_equal (ptid, inferior_ptid))
c906108c 538 {
39f77062 539 switch_to_thread (ptid);
99b3d574
DP
540 }
541}
542
543static void
544restore_selected_frame (struct frame_id a_frame_id)
545{
546 struct frame_info *selected_frame_info = NULL;
547
548 if (frame_id_eq (a_frame_id, null_frame_id))
549 return;
550
551 if ((selected_frame_info = frame_find_by_id (a_frame_id)) != NULL)
552 {
553 select_frame (selected_frame_info);
c906108c
SS
554 }
555}
556
6ecce94d
AC
557struct current_thread_cleanup
558{
39f77062 559 ptid_t inferior_ptid;
99b3d574 560 struct frame_id selected_frame_id;
6ecce94d
AC
561};
562
563static void
564do_restore_current_thread_cleanup (void *arg)
565{
566 struct current_thread_cleanup *old = arg;
39f77062 567 restore_current_thread (old->inferior_ptid);
99b3d574 568 restore_selected_frame (old->selected_frame_id);
b8c9b27d 569 xfree (old);
6ecce94d
AC
570}
571
6208b47d 572struct cleanup *
99b3d574
DP
573make_cleanup_restore_current_thread (ptid_t inferior_ptid,
574 struct frame_id a_frame_id)
6ecce94d
AC
575{
576 struct current_thread_cleanup *old
577 = xmalloc (sizeof (struct current_thread_cleanup));
39f77062 578 old->inferior_ptid = inferior_ptid;
99b3d574 579 old->selected_frame_id = a_frame_id;
6ecce94d
AC
580 return make_cleanup (do_restore_current_thread_cleanup, old);
581}
582
c906108c
SS
583/* Apply a GDB command to a list of threads. List syntax is a whitespace
584 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
585 of two numbers seperated by a hyphen. Examples:
586
c5aa993b
JM
587 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
588 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
589 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
590 */
c906108c
SS
591
592static void
fba45db2 593thread_apply_all_command (char *cmd, int from_tty)
c906108c
SS
594{
595 struct thread_info *tp;
596 struct cleanup *old_chain;
e35ce267
CF
597 struct cleanup *saved_cmd_cleanup_chain;
598 char *saved_cmd;
99b3d574
DP
599 struct frame_id saved_frame_id;
600 ptid_t current_ptid;
601 int thread_has_changed = 0;
c906108c
SS
602
603 if (cmd == NULL || *cmd == '\000')
8a3fe4f8 604 error (_("Please specify a command following the thread ID list"));
99b3d574
DP
605
606 current_ptid = inferior_ptid;
607 saved_frame_id = get_frame_id (get_selected_frame (NULL));
608 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 609
e9d196c5
MS
610 /* It is safe to update the thread list now, before
611 traversing it for "thread apply all". MVS */
612 target_find_new_threads ();
613
e35ce267
CF
614 /* Save a copy of the command in case it is clobbered by
615 execute_command */
5b616ba1 616 saved_cmd = xstrdup (cmd);
b8c9b27d 617 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
618 for (tp = thread_list; tp; tp = tp->next)
619 if (thread_alive (tp))
620 {
39f77062 621 switch_to_thread (tp->ptid);
a3f17187 622 printf_filtered (_("\nThread %d (%s):\n"),
6949171e 623 tp->num, target_tid_to_str (inferior_ptid));
c906108c 624 execute_command (cmd, from_tty);
6949171e 625 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c 626 }
6ecce94d 627
99b3d574
DP
628 if (!ptid_equal (current_ptid, inferior_ptid))
629 thread_has_changed = 1;
630
e35ce267 631 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 632 do_cleanups (old_chain);
99b3d574
DP
633 /* Print stack frame only if we changed thread. */
634 if (thread_has_changed)
635 print_stack_frame (get_current_frame (), 1, SRC_LINE);
636
c906108c
SS
637}
638
639static void
fba45db2 640thread_apply_command (char *tidlist, int from_tty)
c906108c
SS
641{
642 char *cmd;
643 char *p;
644 struct cleanup *old_chain;
e35ce267
CF
645 struct cleanup *saved_cmd_cleanup_chain;
646 char *saved_cmd;
99b3d574
DP
647 struct frame_id saved_frame_id;
648 ptid_t current_ptid;
649 int thread_has_changed = 0;
c906108c
SS
650
651 if (tidlist == NULL || *tidlist == '\000')
8a3fe4f8 652 error (_("Please specify a thread ID list"));
c906108c 653
c5aa993b 654 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
655
656 if (*cmd == '\000')
8a3fe4f8 657 error (_("Please specify a command following the thread ID list"));
c906108c 658
99b3d574
DP
659 current_ptid = inferior_ptid;
660 saved_frame_id = get_frame_id (get_selected_frame (NULL));
661 old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
c906108c 662
e35ce267
CF
663 /* Save a copy of the command in case it is clobbered by
664 execute_command */
5b616ba1 665 saved_cmd = xstrdup (cmd);
b8c9b27d 666 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
667 while (tidlist < cmd)
668 {
669 struct thread_info *tp;
670 int start, end;
671
672 start = strtol (tidlist, &p, 10);
673 if (p == tidlist)
8a3fe4f8 674 error (_("Error parsing %s"), tidlist);
c906108c
SS
675 tidlist = p;
676
677 while (*tidlist == ' ' || *tidlist == '\t')
678 tidlist++;
679
680 if (*tidlist == '-') /* Got a range of IDs? */
681 {
c5aa993b 682 tidlist++; /* Skip the - */
c906108c
SS
683 end = strtol (tidlist, &p, 10);
684 if (p == tidlist)
8a3fe4f8 685 error (_("Error parsing %s"), tidlist);
c906108c
SS
686 tidlist = p;
687
688 while (*tidlist == ' ' || *tidlist == '\t')
689 tidlist++;
690 }
691 else
692 end = start;
693
694 for (; start <= end; start++)
695 {
696 tp = find_thread_id (start);
697
698 if (!tp)
8a3fe4f8 699 warning (_("Unknown thread %d."), start);
c906108c 700 else if (!thread_alive (tp))
8a3fe4f8 701 warning (_("Thread %d has terminated."), start);
c906108c
SS
702 else
703 {
39f77062 704 switch_to_thread (tp->ptid);
a3f17187 705 printf_filtered (_("\nThread %d (%s):\n"), tp->num,
39f77062 706 target_tid_to_str (inferior_ptid));
c906108c 707 execute_command (cmd, from_tty);
e35ce267 708 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c
SS
709 }
710 }
711 }
6ecce94d 712
99b3d574
DP
713 if (!ptid_equal (current_ptid, inferior_ptid))
714 thread_has_changed = 1;
715
e35ce267 716 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 717 do_cleanups (old_chain);
99b3d574
DP
718 /* Print stack frame only if we changed thread. */
719 if (thread_has_changed)
720 print_stack_frame (get_current_frame (), 1, SRC_LINE);
c906108c
SS
721}
722
723/* Switch to the specified thread. Will dispatch off to thread_apply_command
724 if prefix of arg is `apply'. */
725
726static void
fba45db2 727thread_command (char *tidstr, int from_tty)
c906108c 728{
c906108c
SS
729 if (!tidstr)
730 {
731 /* Don't generate an error, just say which thread is current. */
732 if (target_has_stack)
a3f17187 733 printf_filtered (_("[Current thread is %d (%s)]\n"),
39f77062 734 pid_to_thread_id (inferior_ptid),
007d08bb 735 target_tid_to_str (inferior_ptid));
c906108c 736 else
8a3fe4f8 737 error (_("No stack."));
c906108c
SS
738 return;
739 }
c5394b80 740
ce43223b 741 gdb_thread_select (uiout, tidstr, NULL);
c5394b80
JM
742}
743
93815fbf
VP
744/* Print notices when new threads are attached and detached. */
745int print_thread_events = 1;
746static void
747show_print_thread_events (struct ui_file *file, int from_tty,
748 struct cmd_list_element *c, const char *value)
749{
750 fprintf_filtered (file, _("\
751Printing of thread events is %s.\n"),
752 value);
753}
754
c5394b80 755static int
6949171e 756do_captured_thread_select (struct ui_out *uiout, void *tidstr)
c5394b80
JM
757{
758 int num;
759 struct thread_info *tp;
760
81490ea1 761 num = value_as_long (parse_and_eval (tidstr));
c906108c
SS
762
763 tp = find_thread_id (num);
764
8b93c638 765 if (!tp)
8a3fe4f8 766 error (_("Thread ID %d not known."), num);
c906108c
SS
767
768 if (!thread_alive (tp))
8a3fe4f8 769 error (_("Thread ID %d has terminated."), num);
c906108c 770
39f77062 771 switch_to_thread (tp->ptid);
c906108c 772
8b93c638 773 ui_out_text (uiout, "[Switching to thread ");
39f77062 774 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
8b93c638 775 ui_out_text (uiout, " (");
39f77062 776 ui_out_text (uiout, target_tid_to_str (inferior_ptid));
8b93c638 777 ui_out_text (uiout, ")]");
c5394b80 778
b04f3ab4 779 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
c5394b80
JM
780 return GDB_RC_OK;
781}
782
783enum gdb_rc
ce43223b 784gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
c5394b80 785{
b0b13bb4
DJ
786 if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr,
787 error_message, RETURN_MASK_ALL) < 0)
788 return GDB_RC_FAIL;
789 return GDB_RC_OK;
c906108c
SS
790}
791
792/* Commands with a prefix of `thread'. */
793struct cmd_list_element *thread_cmd_list = NULL;
794
795void
fba45db2 796_initialize_thread (void)
c906108c
SS
797{
798 static struct cmd_list_element *thread_apply_list = NULL;
c906108c
SS
799
800 add_info ("threads", info_threads_command,
1bedd215 801 _("IDs of currently known threads."));
c906108c 802
1bedd215
AC
803 add_prefix_cmd ("thread", class_run, thread_command, _("\
804Use this command to switch between threads.\n\
805The new thread ID must be currently known."),
806 &thread_cmd_list, "thread ", 1, &cmdlist);
c906108c
SS
807
808 add_prefix_cmd ("apply", class_run, thread_apply_command,
1bedd215 809 _("Apply a command to a list of threads."),
ad21ceb0 810 &thread_apply_list, "thread apply ", 1, &thread_cmd_list);
c906108c
SS
811
812 add_cmd ("all", class_run, thread_apply_all_command,
1a966eab 813 _("Apply a command to all threads."), &thread_apply_list);
c906108c
SS
814
815 if (!xdb_commands)
816 add_com_alias ("t", "thread", class_run, 1);
93815fbf
VP
817
818 add_setshow_boolean_cmd ("thread-events", no_class,
819 &print_thread_events, _("\
11c68c47
EZ
820Set printing of thread events (such as thread start and exit)."), _("\
821Show printing of thread events (such as thread start and exit)."), NULL,
93815fbf
VP
822 NULL,
823 show_print_thread_events,
824 &setprintlist, &showprintlist);
c906108c 825}
This page took 0.84967 seconds and 4 git commands to generate.