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