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