*** empty log message ***
[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,
7b6bb8da 4 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009, 2010, 2011
0fb0cc75 5 Free Software Foundation, Inc.
8926118c 6
b6ba6518 7 Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
c906108c 8
c5aa993b 9 This file is part of GDB.
c906108c 10
c5aa993b
JM
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
a9762ec7 13 the Free Software Foundation; either version 3 of the License, or
c5aa993b 14 (at your option) any later version.
c906108c 15
c5aa993b
JM
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
c906108c 20
c5aa993b 21 You should have received a copy of the GNU General Public License
a9762ec7 22 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
23
24#include "defs.h"
25#include "symtab.h"
26#include "frame.h"
27#include "inferior.h"
28#include "environ.h"
29#include "value.h"
30#include "target.h"
31#include "gdbthread.h"
60250e8b 32#include "exceptions.h"
c906108c
SS
33#include "command.h"
34#include "gdbcmd.h"
4e052eda 35#include "regcache.h"
5b7f31a4 36#include "gdb.h"
b66d6d2e 37#include "gdb_string.h"
c906108c
SS
38
39#include <ctype.h>
40#include <sys/types.h>
41#include <signal.h>
8b93c638 42#include "ui-out.h"
683f2885 43#include "observer.h"
d4fc5b1e 44#include "annotate.h"
94cc34af
PA
45#include "cli/cli-decode.h"
46
0d06e24b 47/* Definition of struct thread_info exported to gdbthread.h */
c906108c
SS
48
49/* Prototypes for exported functions. */
50
a14ed312 51void _initialize_thread (void);
c906108c
SS
52
53/* Prototypes for local functions. */
54
c906108c
SS
55static struct thread_info *thread_list = NULL;
56static int highest_thread_num;
57
a14ed312
KB
58static void thread_command (char *tidstr, int from_tty);
59static void thread_apply_all_command (char *, int);
60static int thread_alive (struct thread_info *);
61static void info_threads_command (char *, int);
62static void thread_apply_command (char *, int);
39f77062 63static void restore_current_thread (ptid_t);
a14ed312 64static void prune_threads (void);
c906108c 65
4f8d22e3
PA
66/* Frontend view of the thread state. Possible extensions: stepping,
67 finishing, until(ling),... */
68enum thread_state
69{
70 THREAD_STOPPED,
71 THREAD_RUNNING,
72 THREAD_EXITED,
73};
74
a5321aa4 75struct thread_info*
4e1c45ea 76inferior_thread (void)
8601f500 77{
e09875d4 78 struct thread_info *tp = find_thread_ptid (inferior_ptid);
4e1c45ea
PA
79 gdb_assert (tp);
80 return tp;
81}
8601f500 82
4e1c45ea
PA
83void
84delete_step_resume_breakpoint (struct thread_info *tp)
85{
8358c15c 86 if (tp && tp->control.step_resume_breakpoint)
8601f500 87 {
8358c15c
JK
88 delete_breakpoint (tp->control.step_resume_breakpoint);
89 tp->control.step_resume_breakpoint = NULL;
8601f500
MS
90 }
91}
92
186c406b
TT
93void
94delete_exception_resume_breakpoint (struct thread_info *tp)
95{
96 if (tp && tp->control.exception_resume_breakpoint)
97 {
98 delete_breakpoint (tp->control.exception_resume_breakpoint);
99 tp->control.exception_resume_breakpoint = NULL;
100 }
101}
102
7c952b6d 103static void
4f8d22e3 104clear_thread_inferior_resources (struct thread_info *tp)
7c952b6d
ND
105{
106 /* NOTE: this will take care of any left-over step_resume breakpoints,
4d8453a5
DJ
107 but not any user-specified thread-specific breakpoints. We can not
108 delete the breakpoint straight-off, because the inferior might not
109 be stopped at the moment. */
8358c15c 110 if (tp->control.step_resume_breakpoint)
4f8d22e3 111 {
8358c15c
JK
112 tp->control.step_resume_breakpoint->disposition = disp_del_at_next_stop;
113 tp->control.step_resume_breakpoint = NULL;
4f8d22e3 114 }
7c952b6d 115
186c406b
TT
116 if (tp->control.exception_resume_breakpoint)
117 {
118 tp->control.exception_resume_breakpoint->disposition
119 = disp_del_at_next_stop;
120 tp->control.exception_resume_breakpoint = NULL;
121 }
122
16c381f0 123 bpstat_clear (&tp->control.stop_bpstat);
95e54da7
PA
124
125 discard_all_intermediate_continuations_thread (tp);
126 discard_all_continuations_thread (tp);
186c406b
TT
127
128 delete_longjmp_breakpoint (tp->num);
4f8d22e3
PA
129}
130
131static void
132free_thread (struct thread_info *tp)
133{
134 clear_thread_inferior_resources (tp);
a474d7c2 135
7c952b6d 136 if (tp->private)
dc146f7c
VP
137 {
138 if (tp->private_dtor)
139 tp->private_dtor (tp->private);
140 else
141 xfree (tp->private);
142 }
7c952b6d 143
b8c9b27d 144 xfree (tp);
7c952b6d
ND
145}
146
c906108c 147void
fba45db2 148init_thread_list (void)
c906108c
SS
149{
150 struct thread_info *tp, *tpnext;
151
7c952b6d 152 highest_thread_num = 0;
8ea051c5 153
c906108c
SS
154 if (!thread_list)
155 return;
156
157 for (tp = thread_list; tp; tp = tpnext)
158 {
159 tpnext = tp->next;
7c952b6d 160 free_thread (tp);
c906108c
SS
161 }
162
163 thread_list = NULL;
c906108c
SS
164}
165
e58b0e63
PA
166/* Allocate a new thread with target id PTID and add it to the thread
167 list. */
168
169static struct thread_info *
170new_thread (ptid_t ptid)
171{
172 struct thread_info *tp;
173
174 tp = xcalloc (1, sizeof (*tp));
175
176 tp->ptid = ptid;
177 tp->num = ++highest_thread_num;
178 tp->next = thread_list;
179 thread_list = tp;
180
181 /* Nothing to follow yet. */
182 tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
183 tp->state_ = THREAD_STOPPED;
184
185 return tp;
186}
187
0d06e24b 188struct thread_info *
93815fbf 189add_thread_silent (ptid_t ptid)
c906108c
SS
190{
191 struct thread_info *tp;
192
e09875d4 193 tp = find_thread_ptid (ptid);
4f8d22e3
PA
194 if (tp)
195 /* Found an old thread with the same id. It has to be dead,
196 otherwise we wouldn't be adding a new thread with the same id.
197 The OS is reusing this id --- delete it, and recreate a new
198 one. */
199 {
200 /* In addition to deleting the thread, if this is the current
dcf4fbde
PA
201 thread, then we need to take care that delete_thread doesn't
202 really delete the thread if it is inferior_ptid. Create a
203 new template thread in the list with an invalid ptid, switch
204 to it, delete the original thread, reset the new thread's
205 ptid, and switch to it. */
4f8d22e3
PA
206
207 if (ptid_equal (inferior_ptid, ptid))
208 {
c820c52a 209 tp = new_thread (null_ptid);
dcf4fbde
PA
210
211 /* Make switch_to_thread not read from the thread. */
212 tp->state_ = THREAD_EXITED;
c820c52a 213 switch_to_thread (null_ptid);
4f8d22e3
PA
214
215 /* Now we can delete it. */
216 delete_thread (ptid);
217
dcf4fbde 218 /* Now reset its ptid, and reswitch inferior_ptid to it. */
4f8d22e3 219 tp->ptid = ptid;
dcf4fbde 220 tp->state_ = THREAD_STOPPED;
4f8d22e3
PA
221 switch_to_thread (ptid);
222
223 observer_notify_new_thread (tp);
224
225 /* All done. */
226 return tp;
227 }
228 else
229 /* Just go ahead and delete it. */
230 delete_thread (ptid);
231 }
232
e58b0e63 233 tp = new_thread (ptid);
cfc01461
VP
234 observer_notify_new_thread (tp);
235
0d06e24b 236 return tp;
c906108c
SS
237}
238
93815fbf 239struct thread_info *
17faa917 240add_thread_with_info (ptid_t ptid, struct private_thread_info *private)
93815fbf
VP
241{
242 struct thread_info *result = add_thread_silent (ptid);
243
17faa917
DJ
244 result->private = private;
245
93815fbf 246 if (print_thread_events)
fd532e2e 247 printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid));
d4fc5b1e
NR
248
249 annotate_new_thread ();
93815fbf
VP
250 return result;
251}
252
17faa917
DJ
253struct thread_info *
254add_thread (ptid_t ptid)
255{
256 return add_thread_with_info (ptid, NULL);
257}
258
5e0b29c1
PA
259/* Delete thread PTID. If SILENT, don't notify the observer of this
260 exit. */
261static void
262delete_thread_1 (ptid_t ptid, int silent)
c906108c
SS
263{
264 struct thread_info *tp, *tpprev;
265
266 tpprev = NULL;
267
268 for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
39f77062 269 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
270 break;
271
272 if (!tp)
273 return;
274
4f8d22e3
PA
275 /* If this is the current thread, or there's code out there that
276 relies on it existing (refcount > 0) we can't delete yet. Mark
277 it as exited, and notify it. */
278 if (tp->refcount > 0
279 || ptid_equal (tp->ptid, inferior_ptid))
280 {
281 if (tp->state_ != THREAD_EXITED)
282 {
a07daef3 283 observer_notify_thread_exit (tp, silent);
4f8d22e3
PA
284
285 /* Tag it as exited. */
286 tp->state_ = THREAD_EXITED;
287
288 /* Clear breakpoints, etc. associated with this thread. */
289 clear_thread_inferior_resources (tp);
290 }
291
292 /* Will be really deleted some other time. */
293 return;
294 }
295
c906108c
SS
296 if (tpprev)
297 tpprev->next = tp->next;
298 else
299 thread_list = tp->next;
300
4f8d22e3 301 /* Notify thread exit, but only if we haven't already. */
a07daef3
PA
302 if (tp->state_ != THREAD_EXITED)
303 observer_notify_thread_exit (tp, silent);
063bfe2e 304
7c952b6d 305 free_thread (tp);
c906108c
SS
306}
307
4f8d22e3
PA
308/* Delete thread PTID and notify of thread exit. If this is
309 inferior_ptid, don't actually delete it, but tag it as exited and
310 do the notification. If PTID is the user selected thread, clear
311 it. */
5e0b29c1
PA
312void
313delete_thread (ptid_t ptid)
314{
315 delete_thread_1 (ptid, 0 /* not silent */);
316}
317
318void
319delete_thread_silent (ptid_t ptid)
320{
321 delete_thread_1 (ptid, 1 /* silent */);
322}
323
1e92afda 324struct thread_info *
fba45db2 325find_thread_id (int num)
c906108c
SS
326{
327 struct thread_info *tp;
328
329 for (tp = thread_list; tp; tp = tp->next)
330 if (tp->num == num)
331 return tp;
332
333 return NULL;
334}
335
39f77062 336/* Find a thread_info by matching PTID. */
0d06e24b 337struct thread_info *
e09875d4 338find_thread_ptid (ptid_t ptid)
0d06e24b
JM
339{
340 struct thread_info *tp;
341
342 for (tp = thread_list; tp; tp = tp->next)
39f77062 343 if (ptid_equal (tp->ptid, ptid))
0d06e24b
JM
344 return tp;
345
346 return NULL;
347}
348
349/*
350 * Thread iterator function.
351 *
352 * Calls a callback function once for each thread, so long as
353 * the callback function returns false. If the callback function
354 * returns true, the iteration will end and the current thread
355 * will be returned. This can be useful for implementing a
356 * search for a thread with arbitrary attributes, or for applying
357 * some operation to every thread.
358 *
359 * FIXME: some of the existing functionality, such as
360 * "Thread apply all", might be rewritten using this functionality.
361 */
362
363struct thread_info *
fd118b61
KB
364iterate_over_threads (int (*callback) (struct thread_info *, void *),
365 void *data)
0d06e24b 366{
4f8d22e3 367 struct thread_info *tp, *next;
0d06e24b 368
4f8d22e3
PA
369 for (tp = thread_list; tp; tp = next)
370 {
371 next = tp->next;
372 if ((*callback) (tp, data))
373 return tp;
374 }
0d06e24b
JM
375
376 return NULL;
377}
378
20874c92
VP
379int
380thread_count (void)
381{
382 int result = 0;
383 struct thread_info *tp;
384
385 for (tp = thread_list; tp; tp = tp->next)
386 ++result;
387
388 return result;
389}
390
c906108c 391int
fba45db2 392valid_thread_id (int num)
c906108c
SS
393{
394 struct thread_info *tp;
395
396 for (tp = thread_list; tp; tp = tp->next)
397 if (tp->num == num)
398 return 1;
399
400 return 0;
401}
402
403int
39f77062 404pid_to_thread_id (ptid_t ptid)
c906108c
SS
405{
406 struct thread_info *tp;
407
408 for (tp = thread_list; tp; tp = tp->next)
39f77062 409 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
410 return tp->num;
411
412 return 0;
413}
414
39f77062 415ptid_t
fba45db2 416thread_id_to_pid (int num)
c906108c
SS
417{
418 struct thread_info *thread = find_thread_id (num);
5d502164 419
c906108c 420 if (thread)
39f77062 421 return thread->ptid;
c906108c 422 else
39f77062 423 return pid_to_ptid (-1);
c906108c
SS
424}
425
426int
39f77062 427in_thread_list (ptid_t ptid)
c906108c
SS
428{
429 struct thread_info *tp;
430
431 for (tp = thread_list; tp; tp = tp->next)
39f77062 432 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
433 return 1;
434
435 return 0; /* Never heard of 'im */
436}
8926118c 437
bad34192
PA
438/* Finds the first thread of the inferior given by PID. If PID is -1,
439 return the first thread in the list. */
440
441struct thread_info *
442first_thread_of_process (int pid)
443{
444 struct thread_info *tp, *ret = NULL;
445
446 for (tp = thread_list; tp; tp = tp->next)
447 if (pid == -1 || ptid_get_pid (tp->ptid) == pid)
448 if (ret == NULL || tp->num < ret->num)
449 ret = tp;
450
451 return ret;
452}
453
2277426b
PA
454struct thread_info *
455any_thread_of_process (int pid)
456{
457 struct thread_info *tp;
458
459 for (tp = thread_list; tp; tp = tp->next)
460 if (ptid_get_pid (tp->ptid) == pid)
461 return tp;
462
463 return NULL;
464}
465
6c95b8df
PA
466struct thread_info *
467any_live_thread_of_process (int pid)
468{
469 struct thread_info *tp;
470 struct thread_info *tp_running = NULL;
471
472 for (tp = thread_list; tp; tp = tp->next)
473 if (ptid_get_pid (tp->ptid) == pid)
474 {
475 if (tp->state_ == THREAD_STOPPED)
476 return tp;
477 else if (tp->state_ == THREAD_RUNNING)
478 tp_running = tp;
479 }
480
481 return tp_running;
482}
483
8b93c638
JM
484/* Print a list of thread ids currently known, and the total number of
485 threads. To be used from within catch_errors. */
6949171e
JJ
486static int
487do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
8b93c638
JM
488{
489 struct thread_info *tp;
490 int num = 0;
3b31d625 491 struct cleanup *cleanup_chain;
592375cd 492 int current_thread = -1;
8b93c638 493
dc146f7c 494 update_thread_list ();
7990a578 495
3b31d625 496 cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids");
8b93c638
JM
497
498 for (tp = thread_list; tp; tp = tp->next)
499 {
4f8d22e3
PA
500 if (tp->state_ == THREAD_EXITED)
501 continue;
592375cd
VP
502
503 if (ptid_equal (tp->ptid, inferior_ptid))
504 current_thread = tp->num;
505
8b93c638
JM
506 num++;
507 ui_out_field_int (uiout, "thread-id", tp->num);
508 }
509
3b31d625 510 do_cleanups (cleanup_chain);
592375cd
VP
511
512 if (current_thread != -1)
513 ui_out_field_int (uiout, "current-thread-id", current_thread);
8b93c638
JM
514 ui_out_field_int (uiout, "number-of-threads", num);
515 return GDB_RC_OK;
516}
517
518/* Official gdblib interface function to get a list of thread ids and
519 the total number. */
520enum gdb_rc
ce43223b 521gdb_list_thread_ids (struct ui_out *uiout, char **error_message)
8b93c638 522{
b0b13bb4
DJ
523 if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL,
524 error_message, RETURN_MASK_ALL) < 0)
525 return GDB_RC_FAIL;
526 return GDB_RC_OK;
8b93c638 527}
c906108c 528
c906108c
SS
529/* Return true if TP is an active thread. */
530static int
fba45db2 531thread_alive (struct thread_info *tp)
c906108c 532{
4f8d22e3 533 if (tp->state_ == THREAD_EXITED)
c906108c 534 return 0;
39f77062 535 if (!target_thread_alive (tp->ptid))
4f8d22e3 536 return 0;
c906108c
SS
537 return 1;
538}
539
540static void
fba45db2 541prune_threads (void)
c906108c 542{
d4f3574e 543 struct thread_info *tp, *next;
c906108c 544
c906108c
SS
545 for (tp = thread_list; tp; tp = next)
546 {
547 next = tp->next;
548 if (!thread_alive (tp))
39f77062 549 delete_thread (tp->ptid);
c906108c
SS
550 }
551}
552
5231c1fd
PA
553void
554thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid)
555{
82f73884
PA
556 struct inferior *inf;
557 struct thread_info *tp;
558
559 /* It can happen that what we knew as the target inferior id
560 changes. E.g, target remote may only discover the remote process
561 pid after adding the inferior to GDB's list. */
562 inf = find_inferior_pid (ptid_get_pid (old_ptid));
563 inf->pid = ptid_get_pid (new_ptid);
564
e09875d4 565 tp = find_thread_ptid (old_ptid);
5231c1fd
PA
566 tp->ptid = new_ptid;
567
568 observer_notify_thread_ptid_changed (old_ptid, new_ptid);
569}
570
e1ac3328
VP
571void
572set_running (ptid_t ptid, int running)
573{
574 struct thread_info *tp;
d90e17a7 575 int all = ptid_equal (ptid, minus_one_ptid);
e1ac3328 576
e1ac3328
VP
577 /* We try not to notify the observer if no thread has actually changed
578 the running state -- merely to reduce the number of messages to
579 frontend. Frontend is supposed to handle multiple *running just fine. */
d90e17a7 580 if (all || ptid_is_pid (ptid))
e1ac3328
VP
581 {
582 int any_started = 0;
5d502164 583
e1ac3328 584 for (tp = thread_list; tp; tp = tp->next)
d90e17a7
PA
585 if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid))
586 {
587 if (tp->state_ == THREAD_EXITED)
588 continue;
589 if (running && tp->state_ == THREAD_STOPPED)
590 any_started = 1;
591 tp->state_ = running ? THREAD_RUNNING : THREAD_STOPPED;
592 }
c5a4d20b
PA
593 if (any_started)
594 observer_notify_target_resumed (ptid);
e1ac3328
VP
595 }
596 else
597 {
4f8d22e3 598 int started = 0;
5d502164 599
e09875d4 600 tp = find_thread_ptid (ptid);
e1ac3328 601 gdb_assert (tp);
4f8d22e3
PA
602 gdb_assert (tp->state_ != THREAD_EXITED);
603 if (running && tp->state_ == THREAD_STOPPED)
604 started = 1;
605 tp->state_ = running ? THREAD_RUNNING : THREAD_STOPPED;
c5a4d20b 606 if (started)
4f8d22e3
PA
607 observer_notify_target_resumed (ptid);
608 }
e1ac3328
VP
609}
610
4f8d22e3
PA
611static int
612is_thread_state (ptid_t ptid, enum thread_state state)
e1ac3328
VP
613{
614 struct thread_info *tp;
615
e09875d4 616 tp = find_thread_ptid (ptid);
e1ac3328 617 gdb_assert (tp);
4f8d22e3
PA
618 return tp->state_ == state;
619}
620
621int
622is_stopped (ptid_t ptid)
623{
4f8d22e3
PA
624 return is_thread_state (ptid, THREAD_STOPPED);
625}
626
627int
628is_exited (ptid_t ptid)
629{
4f8d22e3
PA
630 return is_thread_state (ptid, THREAD_EXITED);
631}
632
633int
634is_running (ptid_t ptid)
635{
4f8d22e3 636 return is_thread_state (ptid, THREAD_RUNNING);
e1ac3328
VP
637}
638
8ea051c5
PA
639int
640any_running (void)
641{
642 struct thread_info *tp;
643
8ea051c5 644 for (tp = thread_list; tp; tp = tp->next)
4f8d22e3 645 if (tp->state_ == THREAD_RUNNING)
8ea051c5
PA
646 return 1;
647
648 return 0;
649}
650
651int
652is_executing (ptid_t ptid)
653{
654 struct thread_info *tp;
655
e09875d4 656 tp = find_thread_ptid (ptid);
8ea051c5
PA
657 gdb_assert (tp);
658 return tp->executing_;
659}
660
661void
662set_executing (ptid_t ptid, int executing)
663{
664 struct thread_info *tp;
d90e17a7 665 int all = ptid_equal (ptid, minus_one_ptid);
8ea051c5 666
d90e17a7 667 if (all || ptid_is_pid (ptid))
8ea051c5
PA
668 {
669 for (tp = thread_list; tp; tp = tp->next)
d90e17a7
PA
670 if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid))
671 tp->executing_ = executing;
8ea051c5
PA
672 }
673 else
674 {
e09875d4 675 tp = find_thread_ptid (ptid);
8ea051c5
PA
676 gdb_assert (tp);
677 tp->executing_ = executing;
678 }
679}
680
252fbfc8
PA
681void
682set_stop_requested (ptid_t ptid, int stop)
683{
684 struct thread_info *tp;
685 int all = ptid_equal (ptid, minus_one_ptid);
686
687 if (all || ptid_is_pid (ptid))
688 {
689 for (tp = thread_list; tp; tp = tp->next)
690 if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid))
691 tp->stop_requested = stop;
692 }
693 else
694 {
e09875d4 695 tp = find_thread_ptid (ptid);
252fbfc8
PA
696 gdb_assert (tp);
697 tp->stop_requested = stop;
698 }
699
700 /* Call the stop requested observer so other components of GDB can
701 react to this request. */
702 if (stop)
703 observer_notify_thread_stop_requested (ptid);
704}
705
29f49a6a
PA
706void
707finish_thread_state (ptid_t ptid)
708{
709 struct thread_info *tp;
710 int all;
711 int any_started = 0;
712
713 all = ptid_equal (ptid, minus_one_ptid);
714
715 if (all || ptid_is_pid (ptid))
716 {
717 for (tp = thread_list; tp; tp = tp->next)
718 {
719 if (tp->state_ == THREAD_EXITED)
720 continue;
721 if (all || ptid_get_pid (ptid) == ptid_get_pid (tp->ptid))
722 {
723 if (tp->executing_ && tp->state_ == THREAD_STOPPED)
724 any_started = 1;
725 tp->state_ = tp->executing_ ? THREAD_RUNNING : THREAD_STOPPED;
726 }
727 }
728 }
729 else
730 {
e09875d4 731 tp = find_thread_ptid (ptid);
29f49a6a
PA
732 gdb_assert (tp);
733 if (tp->state_ != THREAD_EXITED)
734 {
735 if (tp->executing_ && tp->state_ == THREAD_STOPPED)
736 any_started = 1;
737 tp->state_ = tp->executing_ ? THREAD_RUNNING : THREAD_STOPPED;
738 }
739 }
740
741 if (any_started)
742 observer_notify_target_resumed (ptid);
743}
744
745void
746finish_thread_state_cleanup (void *arg)
747{
748 ptid_t *ptid_p = arg;
749
750 gdb_assert (arg);
751
752 finish_thread_state (*ptid_p);
753}
754
8e8901c5
VP
755/* Prints the list of threads and their details on UIOUT.
756 This is a version of 'info_thread_command' suitable for
757 use from MI.
4f8d22e3 758 If REQUESTED_THREAD is not -1, it's the GDB id of the thread
8e8901c5 759 that should be printed. Otherwise, all threads are
3ee1c036
VP
760 printed.
761 If PID is not -1, only print threads from the process PID.
762 Otherwise, threads from all attached PIDs are printed.
763 If both REQUESTED_THREAD and PID are not -1, then the thread
764 is printed if it belongs to the specified process. Otherwise,
765 an error is raised. */
8e8901c5 766void
3ee1c036 767print_thread_info (struct ui_out *uiout, int requested_thread, int pid)
c906108c
SS
768{
769 struct thread_info *tp;
39f77062 770 ptid_t current_ptid;
99b3d574 771 struct cleanup *old_chain;
0d06e24b 772 char *extra_info;
8e8901c5 773 int current_thread = -1;
c906108c 774
dc146f7c 775 update_thread_list ();
39f77062 776 current_ptid = inferior_ptid;
4f8d22e3
PA
777
778 /* We'll be switching threads temporarily. */
779 old_chain = make_cleanup_restore_current_thread ();
780
a7658b96
TT
781 /* For backward compatibility, we make a list for MI. A table is
782 preferable for the CLI, though, because it shows table
783 headers. */
784 if (ui_out_is_mi_like_p (uiout))
785 make_cleanup_ui_out_list_begin_end (uiout, "threads");
786 else
787 {
788 int n_threads = 0;
789
790 for (tp = thread_list; tp; tp = tp->next)
791 {
792 if (requested_thread != -1 && tp->num != requested_thread)
793 continue;
794
795 if (pid != -1 && PIDGET (tp->ptid) != pid)
796 continue;
797
798 if (tp->state_ == THREAD_EXITED)
799 continue;
800
801 ++n_threads;
802 }
803
804 if (n_threads == 0)
805 {
806 if (requested_thread == -1)
807 ui_out_message (uiout, 0, _("No threads.\n"));
808 else
809 ui_out_message (uiout, 0, _("No thread %d.\n"), requested_thread);
810 do_cleanups (old_chain);
811 return;
812 }
813
814 make_cleanup_ui_out_table_begin_end (uiout, 5, n_threads, "threads");
815
816 ui_out_table_header (uiout, 1, ui_left, "current", "");
817 ui_out_table_header (uiout, 4, ui_left, "id", "Id");
818 ui_out_table_header (uiout, 17, ui_left, "target-id", "Target Id");
819 ui_out_table_header (uiout, 1, ui_noalign, "details", "");
820 ui_out_table_header (uiout, 1, ui_left, "frame", "Frame");
821 ui_out_table_body (uiout);
822 }
823
c906108c
SS
824 for (tp = thread_list; tp; tp = tp->next)
825 {
8e8901c5 826 struct cleanup *chain2;
dc146f7c 827 int core;
8e8901c5
VP
828
829 if (requested_thread != -1 && tp->num != requested_thread)
830 continue;
831
3ee1c036
VP
832 if (pid != -1 && PIDGET (tp->ptid) != pid)
833 {
834 if (requested_thread != -1)
835 error (_("Requested thread not found in requested process"));
836 continue;
837 }
838
4f8d22e3
PA
839 if (ptid_equal (tp->ptid, current_ptid))
840 current_thread = tp->num;
841
842 if (tp->state_ == THREAD_EXITED)
843 continue;
844
8e8901c5
VP
845 chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
846
a7658b96
TT
847 if (ui_out_is_mi_like_p (uiout))
848 {
849 /* Compatibility. */
850 if (ptid_equal (tp->ptid, current_ptid))
851 ui_out_text (uiout, "* ");
852 else
853 ui_out_text (uiout, " ");
854 }
c906108c 855 else
a7658b96
TT
856 {
857 if (ptid_equal (tp->ptid, current_ptid))
858 ui_out_field_string (uiout, "current", "*");
859 else
860 ui_out_field_skip (uiout, "current");
861 }
c906108c 862
8e8901c5 863 ui_out_field_int (uiout, "id", tp->num);
54ba13f7 864 ui_out_field_string (uiout, "target-id", target_pid_to_str (tp->ptid));
0d06e24b 865
ed406532
VP
866 extra_info = target_extra_thread_info (tp);
867 if (extra_info)
8e8901c5 868 {
ed406532
VP
869 ui_out_text (uiout, " (");
870 ui_out_field_string (uiout, "details", extra_info);
871 ui_out_text (uiout, ")");
8e8901c5 872 }
a7658b96
TT
873 else if (! ui_out_is_mi_like_p (uiout))
874 ui_out_field_skip (uiout, "details");
4f8d22e3
PA
875
876 if (tp->state_ == THREAD_RUNNING)
94cc34af
PA
877 ui_out_text (uiout, "(running)\n");
878 else
879 {
880 /* The switch below puts us at the top of the stack (leaf
881 frame). */
882 switch_to_thread (tp->ptid);
883 print_stack_frame (get_selected_frame (NULL),
884 /* For MI output, print frame level. */
885 ui_out_is_mi_like_p (uiout),
886 LOCATION);
887 }
8e8901c5 888
90139f7d
VP
889 if (ui_out_is_mi_like_p (uiout))
890 {
891 char *state = "stopped";
5d502164 892
ed406532 893 if (tp->state_ == THREAD_RUNNING)
90139f7d
VP
894 state = "running";
895 ui_out_field_string (uiout, "state", state);
896 }
897
dc146f7c
VP
898 core = target_core_of_thread (tp->ptid);
899 if (ui_out_is_mi_like_p (uiout) && core != -1)
900 ui_out_field_int (uiout, "core", core);
901
8e8901c5 902 do_cleanups (chain2);
c906108c
SS
903 }
904
99b3d574
DP
905 /* Restores the current thread and the frame selected before
906 the "info threads" command. */
907 do_cleanups (old_chain);
c906108c 908
d729566a 909 if (pid == -1 && requested_thread == -1)
8e8901c5 910 {
4f8d22e3 911 gdb_assert (current_thread != -1
d729566a
PA
912 || !thread_list
913 || ptid_equal (inferior_ptid, null_ptid));
0bcd3e20 914 if (current_thread != -1 && ui_out_is_mi_like_p (uiout))
8e8901c5 915 ui_out_field_int (uiout, "current-thread-id", current_thread);
94cc34af 916
4f8d22e3
PA
917 if (current_thread != -1 && is_exited (current_ptid))
918 ui_out_message (uiout, 0, "\n\
919The current thread <Thread ID %d> has terminated. See `help thread'.\n",
920 current_thread);
d729566a
PA
921 else if (thread_list
922 && current_thread == -1
923 && ptid_equal (current_ptid, null_ptid))
924 ui_out_message (uiout, 0, "\n\
925No selected thread. See `help thread'.\n");
c906108c 926 }
c906108c
SS
927}
928
8e8901c5
VP
929
930/* Print information about currently known threads
931
932 * Note: this has the drawback that it _really_ switches
933 * threads, which frees the frame cache. A no-side
934 * effects info-threads command would be nicer.
935 */
936
937static void
938info_threads_command (char *arg, int from_tty)
939{
3ee1c036 940 print_thread_info (uiout, -1, -1);
8e8901c5
VP
941}
942
c906108c
SS
943/* Switch from one thread to another. */
944
6a6b96b9 945void
39f77062 946switch_to_thread (ptid_t ptid)
c906108c 947{
6c95b8df
PA
948 /* Switch the program space as well, if we can infer it from the now
949 current thread. Otherwise, it's up to the caller to select the
950 space it wants. */
951 if (!ptid_equal (ptid, null_ptid))
952 {
953 struct inferior *inf;
954
955 inf = find_inferior_pid (ptid_get_pid (ptid));
956 gdb_assert (inf != NULL);
957 set_current_program_space (inf->pspace);
958 set_current_inferior (inf);
959 }
960
39f77062 961 if (ptid_equal (ptid, inferior_ptid))
c906108c
SS
962 return;
963
39f77062 964 inferior_ptid = ptid;
35f196d9 965 reinit_frame_cache ();
c906108c 966 registers_changed ();
94cc34af 967
4f8d22e3
PA
968 /* We don't check for is_stopped, because we're called at times
969 while in the TARGET_RUNNING state, e.g., while handling an
970 internal event. */
d729566a
PA
971 if (!ptid_equal (inferior_ptid, null_ptid)
972 && !is_exited (ptid)
973 && !is_executing (ptid))
fb14de7b 974 stop_pc = regcache_read_pc (get_thread_regcache (ptid));
94cc34af
PA
975 else
976 stop_pc = ~(CORE_ADDR) 0;
c906108c
SS
977}
978
979static void
39f77062 980restore_current_thread (ptid_t ptid)
c906108c 981{
dcf4fbde 982 switch_to_thread (ptid);
99b3d574
DP
983}
984
985static void
4f8d22e3 986restore_selected_frame (struct frame_id a_frame_id, int frame_level)
99b3d574 987{
4f8d22e3
PA
988 struct frame_info *frame = NULL;
989 int count;
990
991 gdb_assert (frame_level >= 0);
992
993 /* Restore by level first, check if the frame id is the same as
994 expected. If that fails, try restoring by frame id. If that
995 fails, nothing to do, just warn the user. */
996
997 count = frame_level;
998 frame = find_relative_frame (get_current_frame (), &count);
999 if (count == 0
1000 && frame != NULL
005ca36a
JB
1001 /* The frame ids must match - either both valid or both outer_frame_id.
1002 The latter case is not failsafe, but since it's highly unlikely
4f8d22e3
PA
1003 the search by level finds the wrong frame, it's 99.9(9)% of
1004 the time (for all practical purposes) safe. */
005ca36a 1005 && frame_id_eq (get_frame_id (frame), a_frame_id))
4f8d22e3
PA
1006 {
1007 /* Cool, all is fine. */
1008 select_frame (frame);
1009 return;
1010 }
99b3d574 1011
4f8d22e3
PA
1012 frame = frame_find_by_id (a_frame_id);
1013 if (frame != NULL)
1014 {
1015 /* Cool, refound it. */
1016 select_frame (frame);
1017 return;
1018 }
99b3d574 1019
0c501536
PA
1020 /* Nothing else to do, the frame layout really changed. Select the
1021 innermost stack frame. */
1022 select_frame (get_current_frame ());
1023
1024 /* Warn the user. */
6c95b8df 1025 if (frame_level > 0 && !ui_out_is_mi_like_p (uiout))
99b3d574 1026 {
3e43a32a
MS
1027 warning (_("Couldn't restore frame #%d in "
1028 "current thread, at reparsed frame #0\n"),
4f8d22e3
PA
1029 frame_level);
1030 /* For MI, we should probably have a notification about
1031 current frame change. But this error is not very
1032 likely, so don't bother for now. */
0c501536 1033 print_stack_frame (get_selected_frame (NULL), 1, SRC_LINE);
c906108c
SS
1034 }
1035}
1036
6ecce94d
AC
1037struct current_thread_cleanup
1038{
39f77062 1039 ptid_t inferior_ptid;
99b3d574 1040 struct frame_id selected_frame_id;
4f8d22e3
PA
1041 int selected_frame_level;
1042 int was_stopped;
6c95b8df 1043 int inf_id;
6ecce94d
AC
1044};
1045
1046static void
1047do_restore_current_thread_cleanup (void *arg)
1048{
4f8d22e3 1049 struct thread_info *tp;
6ecce94d 1050 struct current_thread_cleanup *old = arg;
d729566a 1051
e09875d4 1052 tp = find_thread_ptid (old->inferior_ptid);
d729566a
PA
1053
1054 /* If the previously selected thread belonged to a process that has
1055 in the mean time been deleted (due to normal exit, detach, etc.),
1056 then don't revert back to it, but instead simply drop back to no
1057 thread selected. */
1058 if (tp
88fc996f 1059 && find_inferior_pid (ptid_get_pid (tp->ptid)) != NULL)
d729566a 1060 restore_current_thread (old->inferior_ptid);
88fc996f 1061 else
6c95b8df
PA
1062 {
1063 restore_current_thread (null_ptid);
1064 set_current_inferior (find_inferior_id (old->inf_id));
1065 }
94cc34af 1066
4f8d22e3
PA
1067 /* The running state of the originally selected thread may have
1068 changed, so we have to recheck it here. */
d729566a
PA
1069 if (!ptid_equal (inferior_ptid, null_ptid)
1070 && old->was_stopped
4f8d22e3
PA
1071 && is_stopped (inferior_ptid)
1072 && target_has_registers
1073 && target_has_stack
1074 && target_has_memory)
1075 restore_selected_frame (old->selected_frame_id,
1076 old->selected_frame_level);
1077}
1078
1079static void
1080restore_current_thread_cleanup_dtor (void *arg)
1081{
1082 struct current_thread_cleanup *old = arg;
1083 struct thread_info *tp;
5d502164 1084
e09875d4 1085 tp = find_thread_ptid (old->inferior_ptid);
4f8d22e3
PA
1086 if (tp)
1087 tp->refcount--;
b8c9b27d 1088 xfree (old);
6ecce94d
AC
1089}
1090
6208b47d 1091struct cleanup *
4f8d22e3 1092make_cleanup_restore_current_thread (void)
6ecce94d 1093{
4f8d22e3
PA
1094 struct thread_info *tp;
1095 struct frame_info *frame;
1096 struct current_thread_cleanup *old;
1097
1098 old = xmalloc (sizeof (struct current_thread_cleanup));
39f77062 1099 old->inferior_ptid = inferior_ptid;
6c95b8df 1100 old->inf_id = current_inferior ()->num;
4f8d22e3 1101
d729566a
PA
1102 if (!ptid_equal (inferior_ptid, null_ptid))
1103 {
1104 old->was_stopped = is_stopped (inferior_ptid);
1105 if (old->was_stopped
1106 && target_has_registers
1107 && target_has_stack
1108 && target_has_memory)
1109 frame = get_selected_frame (NULL);
1110 else
1111 frame = NULL;
4f8d22e3 1112
d729566a
PA
1113 old->selected_frame_id = get_frame_id (frame);
1114 old->selected_frame_level = frame_relative_level (frame);
1115
e09875d4 1116 tp = find_thread_ptid (inferior_ptid);
d729566a
PA
1117 if (tp)
1118 tp->refcount++;
1119 }
4f8d22e3
PA
1120
1121 return make_cleanup_dtor (do_restore_current_thread_cleanup, old,
1122 restore_current_thread_cleanup_dtor);
6ecce94d
AC
1123}
1124
c906108c
SS
1125/* Apply a GDB command to a list of threads. List syntax is a whitespace
1126 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
1127 of two numbers seperated by a hyphen. Examples:
1128
c5aa993b
JM
1129 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
1130 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
1131 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
1132 */
c906108c
SS
1133
1134static void
fba45db2 1135thread_apply_all_command (char *cmd, int from_tty)
c906108c
SS
1136{
1137 struct thread_info *tp;
4f8d22e3 1138 struct cleanup *old_chain;
e35ce267 1139 char *saved_cmd;
c906108c
SS
1140
1141 if (cmd == NULL || *cmd == '\000')
8a3fe4f8 1142 error (_("Please specify a command following the thread ID list"));
94cc34af 1143
dc146f7c 1144 update_thread_list ();
e9d196c5 1145
4f8d22e3
PA
1146 old_chain = make_cleanup_restore_current_thread ();
1147
e35ce267
CF
1148 /* Save a copy of the command in case it is clobbered by
1149 execute_command */
5b616ba1 1150 saved_cmd = xstrdup (cmd);
94cc34af 1151 make_cleanup (xfree, saved_cmd);
c906108c
SS
1152 for (tp = thread_list; tp; tp = tp->next)
1153 if (thread_alive (tp))
1154 {
dcf4fbde 1155 switch_to_thread (tp->ptid);
94cc34af 1156
a3f17187 1157 printf_filtered (_("\nThread %d (%s):\n"),
54ba13f7 1158 tp->num, target_pid_to_str (inferior_ptid));
c906108c 1159 execute_command (cmd, from_tty);
3e43a32a
MS
1160 strcpy (cmd, saved_cmd); /* Restore exact command used
1161 previously. */
c906108c 1162 }
6ecce94d
AC
1163
1164 do_cleanups (old_chain);
c906108c
SS
1165}
1166
1167static void
fba45db2 1168thread_apply_command (char *tidlist, int from_tty)
c906108c
SS
1169{
1170 char *cmd;
1171 char *p;
1172 struct cleanup *old_chain;
e35ce267 1173 char *saved_cmd;
c906108c
SS
1174
1175 if (tidlist == NULL || *tidlist == '\000')
8a3fe4f8 1176 error (_("Please specify a thread ID list"));
c906108c 1177
c5aa993b 1178 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
1179
1180 if (*cmd == '\000')
8a3fe4f8 1181 error (_("Please specify a command following the thread ID list"));
c906108c 1182
e35ce267
CF
1183 /* Save a copy of the command in case it is clobbered by
1184 execute_command */
5b616ba1 1185 saved_cmd = xstrdup (cmd);
4f8d22e3 1186 old_chain = make_cleanup (xfree, saved_cmd);
c906108c
SS
1187 while (tidlist < cmd)
1188 {
1189 struct thread_info *tp;
1190 int start, end;
1191
1192 start = strtol (tidlist, &p, 10);
1193 if (p == tidlist)
8a3fe4f8 1194 error (_("Error parsing %s"), tidlist);
c906108c
SS
1195 tidlist = p;
1196
1197 while (*tidlist == ' ' || *tidlist == '\t')
1198 tidlist++;
1199
1200 if (*tidlist == '-') /* Got a range of IDs? */
1201 {
c5aa993b 1202 tidlist++; /* Skip the - */
c906108c
SS
1203 end = strtol (tidlist, &p, 10);
1204 if (p == tidlist)
8a3fe4f8 1205 error (_("Error parsing %s"), tidlist);
c906108c
SS
1206 tidlist = p;
1207
1208 while (*tidlist == ' ' || *tidlist == '\t')
1209 tidlist++;
1210 }
1211 else
1212 end = start;
1213
65fc9b77
PA
1214 make_cleanup_restore_current_thread ();
1215
c906108c
SS
1216 for (; start <= end; start++)
1217 {
1218 tp = find_thread_id (start);
1219
1220 if (!tp)
8a3fe4f8 1221 warning (_("Unknown thread %d."), start);
c906108c 1222 else if (!thread_alive (tp))
8a3fe4f8 1223 warning (_("Thread %d has terminated."), start);
c906108c
SS
1224 else
1225 {
dcf4fbde 1226 switch_to_thread (tp->ptid);
4f8d22e3 1227
a3f17187 1228 printf_filtered (_("\nThread %d (%s):\n"), tp->num,
54ba13f7 1229 target_pid_to_str (inferior_ptid));
c906108c 1230 execute_command (cmd, from_tty);
4f8d22e3
PA
1231
1232 /* Restore exact command used previously. */
1233 strcpy (cmd, saved_cmd);
c906108c
SS
1234 }
1235 }
1236 }
6ecce94d
AC
1237
1238 do_cleanups (old_chain);
c906108c
SS
1239}
1240
1241/* Switch to the specified thread. Will dispatch off to thread_apply_command
1242 if prefix of arg is `apply'. */
1243
1244static void
fba45db2 1245thread_command (char *tidstr, int from_tty)
c906108c 1246{
c906108c
SS
1247 if (!tidstr)
1248 {
d729566a
PA
1249 if (ptid_equal (inferior_ptid, null_ptid))
1250 error (_("No thread selected"));
1251
c906108c 1252 if (target_has_stack)
4f8d22e3
PA
1253 {
1254 if (is_exited (inferior_ptid))
1255 printf_filtered (_("[Current thread is %d (%s) (exited)]\n"),
1256 pid_to_thread_id (inferior_ptid),
54ba13f7 1257 target_pid_to_str (inferior_ptid));
4f8d22e3
PA
1258 else
1259 printf_filtered (_("[Current thread is %d (%s)]\n"),
1260 pid_to_thread_id (inferior_ptid),
54ba13f7 1261 target_pid_to_str (inferior_ptid));
4f8d22e3 1262 }
c906108c 1263 else
8a3fe4f8 1264 error (_("No stack."));
c906108c
SS
1265 return;
1266 }
c5394b80 1267
ce43223b 1268 gdb_thread_select (uiout, tidstr, NULL);
c5394b80
JM
1269}
1270
93815fbf
VP
1271/* Print notices when new threads are attached and detached. */
1272int print_thread_events = 1;
1273static void
1274show_print_thread_events (struct ui_file *file, int from_tty,
1275 struct cmd_list_element *c, const char *value)
1276{
3e43a32a
MS
1277 fprintf_filtered (file,
1278 _("Printing of thread events is %s.\n"),
93815fbf
VP
1279 value);
1280}
1281
c5394b80 1282static int
6949171e 1283do_captured_thread_select (struct ui_out *uiout, void *tidstr)
c5394b80
JM
1284{
1285 int num;
1286 struct thread_info *tp;
1287
81490ea1 1288 num = value_as_long (parse_and_eval (tidstr));
c906108c
SS
1289
1290 tp = find_thread_id (num);
1291
8b93c638 1292 if (!tp)
8a3fe4f8 1293 error (_("Thread ID %d not known."), num);
c906108c
SS
1294
1295 if (!thread_alive (tp))
8a3fe4f8 1296 error (_("Thread ID %d has terminated."), num);
c906108c 1297
dcf4fbde 1298 switch_to_thread (tp->ptid);
c906108c 1299
db5a7484
NR
1300 annotate_thread_changed ();
1301
8b93c638 1302 ui_out_text (uiout, "[Switching to thread ");
39f77062 1303 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
8b93c638 1304 ui_out_text (uiout, " (");
54ba13f7 1305 ui_out_text (uiout, target_pid_to_str (inferior_ptid));
8b93c638 1306 ui_out_text (uiout, ")]");
c5394b80 1307
4f8d22e3
PA
1308 /* Note that we can't reach this with an exited thread, due to the
1309 thread_alive check above. */
1310 if (tp->state_ == THREAD_RUNNING)
94cc34af 1311 ui_out_text (uiout, "(running)\n");
4f8d22e3
PA
1312 else
1313 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
1314
1315 /* Since the current thread may have changed, see if there is any
1316 exited thread we can now delete. */
1317 prune_threads ();
94cc34af 1318
c5394b80
JM
1319 return GDB_RC_OK;
1320}
1321
1322enum gdb_rc
ce43223b 1323gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
c5394b80 1324{
b0b13bb4
DJ
1325 if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr,
1326 error_message, RETURN_MASK_ALL) < 0)
1327 return GDB_RC_FAIL;
1328 return GDB_RC_OK;
c906108c
SS
1329}
1330
dc146f7c
VP
1331void
1332update_thread_list (void)
1333{
1334 prune_threads ();
1335 target_find_new_threads ();
1336}
1337
6aed2dbc
SS
1338/* Return a new value for the selected thread's id. Return a value of 0 if
1339 no thread is selected, or no threads exist. */
1340
1341static struct value *
1342thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var)
1343{
1344 struct thread_info *tp = find_thread_ptid (inferior_ptid);
1345
1346 return value_from_longest (builtin_type (gdbarch)->builtin_int,
1347 (tp ? tp->num : 0));
1348}
1349
c906108c
SS
1350/* Commands with a prefix of `thread'. */
1351struct cmd_list_element *thread_cmd_list = NULL;
1352
1353void
fba45db2 1354_initialize_thread (void)
c906108c
SS
1355{
1356 static struct cmd_list_element *thread_apply_list = NULL;
c906108c 1357
d729566a
PA
1358 add_info ("threads", info_threads_command,
1359 _("IDs of currently known threads."));
c906108c 1360
d729566a 1361 add_prefix_cmd ("thread", class_run, thread_command, _("\
1bedd215
AC
1362Use this command to switch between threads.\n\
1363The new thread ID must be currently known."),
d729566a 1364 &thread_cmd_list, "thread ", 1, &cmdlist);
c906108c 1365
d729566a
PA
1366 add_prefix_cmd ("apply", class_run, thread_apply_command,
1367 _("Apply a command to a list of threads."),
1368 &thread_apply_list, "thread apply ", 1, &thread_cmd_list);
c906108c 1369
d729566a
PA
1370 add_cmd ("all", class_run, thread_apply_all_command,
1371 _("Apply a command to all threads."), &thread_apply_list);
c906108c
SS
1372
1373 if (!xdb_commands)
1374 add_com_alias ("t", "thread", class_run, 1);
93815fbf
VP
1375
1376 add_setshow_boolean_cmd ("thread-events", no_class,
1377 &print_thread_events, _("\
11c68c47
EZ
1378Set printing of thread events (such as thread start and exit)."), _("\
1379Show printing of thread events (such as thread start and exit)."), NULL,
93815fbf
VP
1380 NULL,
1381 show_print_thread_events,
1382 &setprintlist, &showprintlist);
6aed2dbc
SS
1383
1384 create_internalvar_type_lazy ("_thread", thread_id_make_value);
c906108c 1385}
This page took 1.095507 seconds and 4 git commands to generate.