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