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