* config/tc-h8300.c (h8300hmode): Record the machine type
[deliverable/binutils-gdb.git] / gdb / thread.c
CommitLineData
c906108c 1/* Multi-process/thread control for GDB, the GNU debugger.
b6ba6518
KB
2 Copyright 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001
c906108c 4 Free Software Foundation, Inc.
b6ba6518
KB
5 Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
6
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
12 the Free Software Foundation; either version 2 of the License, or
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
JM
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
c906108c
SS
24
25#include "defs.h"
26#include "symtab.h"
27#include "frame.h"
28#include "inferior.h"
29#include "environ.h"
30#include "value.h"
31#include "target.h"
32#include "gdbthread.h"
33#include "command.h"
34#include "gdbcmd.h"
4e052eda 35#include "regcache.h"
5b7f31a4 36#include "gdb.h"
c906108c
SS
37
38#include <ctype.h>
39#include <sys/types.h>
40#include <signal.h>
8b93c638
JM
41#ifdef UI_OUT
42#include "ui-out.h"
43#endif
c906108c 44
c5aa993b 45/*#include "lynxos-core.h" */
c906108c 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 58static struct thread_info *find_thread_id (int num);
c906108c 59
a14ed312
KB
60static void thread_command (char *tidstr, int from_tty);
61static void thread_apply_all_command (char *, int);
62static int thread_alive (struct thread_info *);
63static void info_threads_command (char *, int);
64static void thread_apply_command (char *, int);
39f77062
KB
65static void restore_current_thread (ptid_t);
66static void switch_to_thread (ptid_t ptid);
a14ed312 67static void prune_threads (void);
c906108c 68
8601f500
MS
69void
70delete_step_resume_breakpoint (void *arg)
71{
72 struct breakpoint **breakpointp = (struct breakpoint **) arg;
73 struct thread_info *tp;
74
75 if (*breakpointp != NULL)
76 {
77 delete_breakpoint (*breakpointp);
78 for (tp = thread_list; tp; tp = tp->next)
79 if (tp->step_resume_breakpoint == *breakpointp)
80 tp->step_resume_breakpoint = NULL;
81
82 *breakpointp = NULL;
83 }
84}
85
7c952b6d
ND
86static void
87free_thread (struct thread_info *tp)
88{
89 /* NOTE: this will take care of any left-over step_resume breakpoints,
90 but not any user-specified thread-specific breakpoints. */
91 if (tp->step_resume_breakpoint)
92 delete_breakpoint (tp->step_resume_breakpoint);
93
94 /* FIXME: do I ever need to call the back-end to give it a
95 chance at this private data before deleting the thread? */
96 if (tp->private)
b8c9b27d 97 xfree (tp->private);
7c952b6d 98
b8c9b27d 99 xfree (tp);
7c952b6d
ND
100}
101
c906108c 102void
fba45db2 103init_thread_list (void)
c906108c
SS
104{
105 struct thread_info *tp, *tpnext;
106
7c952b6d 107 highest_thread_num = 0;
c906108c
SS
108 if (!thread_list)
109 return;
110
111 for (tp = thread_list; tp; tp = tpnext)
112 {
113 tpnext = tp->next;
7c952b6d 114 free_thread (tp);
c906108c
SS
115 }
116
117 thread_list = NULL;
c906108c
SS
118}
119
0d06e24b
JM
120/* add_thread now returns a pointer to the new thread_info,
121 so that back_ends can initialize their private data. */
122
123struct thread_info *
39f77062 124add_thread (ptid_t ptid)
c906108c
SS
125{
126 struct thread_info *tp;
127
6c0d3f6a
MS
128 tp = (struct thread_info *) xmalloc (sizeof (*tp));
129 memset (tp, 0, sizeof (*tp));
39f77062 130 tp->ptid = ptid;
c906108c 131 tp->num = ++highest_thread_num;
c906108c
SS
132 tp->next = thread_list;
133 thread_list = tp;
0d06e24b 134 return tp;
c906108c
SS
135}
136
137void
39f77062 138delete_thread (ptid_t ptid)
c906108c
SS
139{
140 struct thread_info *tp, *tpprev;
141
142 tpprev = NULL;
143
144 for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
39f77062 145 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
146 break;
147
148 if (!tp)
149 return;
150
151 if (tpprev)
152 tpprev->next = tp->next;
153 else
154 thread_list = tp->next;
155
7c952b6d 156 free_thread (tp);
c906108c
SS
157}
158
159static struct thread_info *
fba45db2 160find_thread_id (int num)
c906108c
SS
161{
162 struct thread_info *tp;
163
164 for (tp = thread_list; tp; tp = tp->next)
165 if (tp->num == num)
166 return tp;
167
168 return NULL;
169}
170
39f77062 171/* Find a thread_info by matching PTID. */
0d06e24b 172struct thread_info *
39f77062 173find_thread_pid (ptid_t ptid)
0d06e24b
JM
174{
175 struct thread_info *tp;
176
177 for (tp = thread_list; tp; tp = tp->next)
39f77062 178 if (ptid_equal (tp->ptid, ptid))
0d06e24b
JM
179 return tp;
180
181 return NULL;
182}
183
184/*
185 * Thread iterator function.
186 *
187 * Calls a callback function once for each thread, so long as
188 * the callback function returns false. If the callback function
189 * returns true, the iteration will end and the current thread
190 * will be returned. This can be useful for implementing a
191 * search for a thread with arbitrary attributes, or for applying
192 * some operation to every thread.
193 *
194 * FIXME: some of the existing functionality, such as
195 * "Thread apply all", might be rewritten using this functionality.
196 */
197
198struct thread_info *
fd118b61
KB
199iterate_over_threads (int (*callback) (struct thread_info *, void *),
200 void *data)
0d06e24b
JM
201{
202 struct thread_info *tp;
203
204 for (tp = thread_list; tp; tp = tp->next)
205 if ((*callback) (tp, data))
206 return tp;
207
208 return NULL;
209}
210
c906108c 211int
fba45db2 212valid_thread_id (int num)
c906108c
SS
213{
214 struct thread_info *tp;
215
216 for (tp = thread_list; tp; tp = tp->next)
217 if (tp->num == num)
218 return 1;
219
220 return 0;
221}
222
223int
39f77062 224pid_to_thread_id (ptid_t ptid)
c906108c
SS
225{
226 struct thread_info *tp;
227
228 for (tp = thread_list; tp; tp = tp->next)
39f77062 229 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
230 return tp->num;
231
232 return 0;
233}
234
39f77062 235ptid_t
fba45db2 236thread_id_to_pid (int num)
c906108c
SS
237{
238 struct thread_info *thread = find_thread_id (num);
239 if (thread)
39f77062 240 return thread->ptid;
c906108c 241 else
39f77062 242 return pid_to_ptid (-1);
c906108c
SS
243}
244
245int
39f77062 246in_thread_list (ptid_t ptid)
c906108c
SS
247{
248 struct thread_info *tp;
249
250 for (tp = thread_list; tp; tp = tp->next)
39f77062 251 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
252 return 1;
253
254 return 0; /* Never heard of 'im */
255}
8b93c638
JM
256#ifdef UI_OUT
257/* Print a list of thread ids currently known, and the total number of
258 threads. To be used from within catch_errors. */
259static int
260do_captured_list_thread_ids (void *arg)
261{
262 struct thread_info *tp;
263 int num = 0;
264
f8e42d24 265 ui_out_tuple_begin (uiout, "thread-ids");
8b93c638
JM
266
267 for (tp = thread_list; tp; tp = tp->next)
268 {
269 num++;
270 ui_out_field_int (uiout, "thread-id", tp->num);
271 }
272
f8e42d24 273 ui_out_tuple_end (uiout);
8b93c638
JM
274 ui_out_field_int (uiout, "number-of-threads", num);
275 return GDB_RC_OK;
276}
277
278/* Official gdblib interface function to get a list of thread ids and
279 the total number. */
280enum gdb_rc
281gdb_list_thread_ids (/* output object */)
282{
283 return catch_errors (do_captured_list_thread_ids, NULL,
284 NULL, RETURN_MASK_ALL);
285}
286#endif
c906108c
SS
287
288/* Load infrun state for the thread PID. */
289
c5aa993b 290void
6c0d3f6a
MS
291load_infrun_state (ptid_t ptid,
292 CORE_ADDR *prev_pc,
293 CORE_ADDR *prev_func_start,
294 char **prev_func_name,
295 int *trap_expected,
fba45db2
KB
296 struct breakpoint **step_resume_breakpoint,
297 struct breakpoint **through_sigtramp_breakpoint,
6c0d3f6a
MS
298 CORE_ADDR *step_range_start,
299 CORE_ADDR *step_range_end,
300 CORE_ADDR *step_frame_address,
301 int *handling_longjmp,
302 int *another_trap,
303 int *stepping_through_solib_after_catch,
fba45db2 304 bpstat *stepping_through_solib_catchpoints,
6c0d3f6a
MS
305 int *stepping_through_sigtramp,
306 int *current_line,
307 struct symtab **current_symtab,
308 CORE_ADDR *step_sp)
c906108c
SS
309{
310 struct thread_info *tp;
311
312 /* If we can't find the thread, then we're debugging a single threaded
313 process. No need to do anything in that case. */
39f77062 314 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
315 if (tp == NULL)
316 return;
317
318 *prev_pc = tp->prev_pc;
319 *prev_func_start = tp->prev_func_start;
320 *prev_func_name = tp->prev_func_name;
6c0d3f6a 321 *trap_expected = tp->trap_expected;
c906108c 322 *step_resume_breakpoint = tp->step_resume_breakpoint;
6c0d3f6a 323 *through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint;
c906108c
SS
324 *step_range_start = tp->step_range_start;
325 *step_range_end = tp->step_range_end;
326 *step_frame_address = tp->step_frame_address;
c906108c 327 *handling_longjmp = tp->handling_longjmp;
c906108c
SS
328 *another_trap = tp->another_trap;
329 *stepping_through_solib_after_catch = tp->stepping_through_solib_after_catch;
330 *stepping_through_solib_catchpoints = tp->stepping_through_solib_catchpoints;
331 *stepping_through_sigtramp = tp->stepping_through_sigtramp;
6c0d3f6a
MS
332 *current_line = tp->current_line;
333 *current_symtab = tp->current_symtab;
334 *step_sp = tp->step_sp;
c906108c
SS
335}
336
337/* Save infrun state for the thread PID. */
338
c5aa993b 339void
6c0d3f6a
MS
340save_infrun_state (ptid_t ptid,
341 CORE_ADDR prev_pc,
342 CORE_ADDR prev_func_start,
343 char *prev_func_name,
344 int trap_expected,
fba45db2
KB
345 struct breakpoint *step_resume_breakpoint,
346 struct breakpoint *through_sigtramp_breakpoint,
6c0d3f6a
MS
347 CORE_ADDR step_range_start,
348 CORE_ADDR step_range_end,
349 CORE_ADDR step_frame_address,
350 int handling_longjmp,
351 int another_trap,
352 int stepping_through_solib_after_catch,
fba45db2 353 bpstat stepping_through_solib_catchpoints,
6c0d3f6a
MS
354 int stepping_through_sigtramp,
355 int current_line,
356 struct symtab *current_symtab,
357 CORE_ADDR step_sp)
c906108c
SS
358{
359 struct thread_info *tp;
360
361 /* If we can't find the thread, then we're debugging a single-threaded
362 process. Nothing to do in that case. */
39f77062 363 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
364 if (tp == NULL)
365 return;
366
367 tp->prev_pc = prev_pc;
368 tp->prev_func_start = prev_func_start;
369 tp->prev_func_name = prev_func_name;
6c0d3f6a 370 tp->trap_expected = trap_expected;
c906108c 371 tp->step_resume_breakpoint = step_resume_breakpoint;
6c0d3f6a 372 tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint;
c906108c
SS
373 tp->step_range_start = step_range_start;
374 tp->step_range_end = step_range_end;
375 tp->step_frame_address = step_frame_address;
c906108c 376 tp->handling_longjmp = handling_longjmp;
c906108c
SS
377 tp->another_trap = another_trap;
378 tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
379 tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
380 tp->stepping_through_sigtramp = stepping_through_sigtramp;
6c0d3f6a
MS
381 tp->current_line = current_line;
382 tp->current_symtab = current_symtab;
383 tp->step_sp = step_sp;
c906108c
SS
384}
385
386/* Return true if TP is an active thread. */
387static int
fba45db2 388thread_alive (struct thread_info *tp)
c906108c 389{
39f77062 390 if (PIDGET (tp->ptid) == -1)
c906108c 391 return 0;
39f77062 392 if (!target_thread_alive (tp->ptid))
c906108c 393 {
39f77062 394 tp->ptid = pid_to_ptid (-1); /* Mark it as dead */
c906108c
SS
395 return 0;
396 }
397 return 1;
398}
399
400static void
fba45db2 401prune_threads (void)
c906108c 402{
d4f3574e 403 struct thread_info *tp, *next;
c906108c 404
c906108c
SS
405 for (tp = thread_list; tp; tp = next)
406 {
407 next = tp->next;
408 if (!thread_alive (tp))
39f77062 409 delete_thread (tp->ptid);
c906108c
SS
410 }
411}
412
413/* Print information about currently known threads
c5aa993b 414
c906108c
SS
415 * Note: this has the drawback that it _really_ switches
416 * threads, which frees the frame cache. A no-side
417 * effects info-threads command would be nicer.
418 */
419
420static void
fba45db2 421info_threads_command (char *arg, int from_tty)
c906108c
SS
422{
423 struct thread_info *tp;
39f77062 424 ptid_t current_ptid;
c5aa993b
JM
425 struct frame_info *cur_frame;
426 int saved_frame_level = selected_frame_level;
427 int counter;
0d06e24b 428 char *extra_info;
c906108c
SS
429
430 /* Avoid coredumps which would happen if we tried to access a NULL
431 selected_frame. */
c5aa993b
JM
432 if (!target_has_stack)
433 error ("No stack.");
c906108c
SS
434
435 prune_threads ();
b83266a0 436 target_find_new_threads ();
39f77062 437 current_ptid = inferior_ptid;
c906108c
SS
438 for (tp = thread_list; tp; tp = tp->next)
439 {
39f77062 440 if (ptid_equal (tp->ptid, current_ptid))
c906108c
SS
441 printf_filtered ("* ");
442 else
443 printf_filtered (" ");
444
445#ifdef HPUXHPPA
39f77062 446 printf_filtered ("%d %s", tp->num, target_tid_to_str (tp->ptid));
c906108c 447#else
39f77062 448 printf_filtered ("%d %s", tp->num, target_pid_to_str (tp->ptid));
c906108c 449#endif
0d06e24b
JM
450
451 extra_info = target_extra_thread_info (tp);
452 if (extra_info)
453 printf_filtered (" (%s)", extra_info);
454 puts_filtered (" ");
455
39f77062 456 switch_to_thread (tp->ptid);
c906108c
SS
457 if (selected_frame)
458 print_only_stack_frame (selected_frame, -1, 0);
459 else
460 printf_filtered ("[No stack.]\n");
461 }
462
39f77062 463 switch_to_thread (current_ptid);
c906108c
SS
464
465 /* Code below copied from "up_silently_base" in "stack.c".
466 * It restores the frame set by the user before the "info threads"
467 * command. We have finished the info-threads display by switching
468 * back to the current thread. That switch has put us at the top
469 * of the stack (leaf frame).
470 */
c5aa993b
JM
471 counter = saved_frame_level;
472 cur_frame = find_relative_frame (selected_frame, &counter);
c906108c
SS
473 if (counter != 0)
474 {
475 /* Ooops, can't restore, tell user where we are. */
476 warning ("Couldn't restore frame in current thread, at frame 0");
477 print_stack_frame (selected_frame, -1, 0);
478 }
479 else
480 {
c5aa993b 481 select_frame (cur_frame, saved_frame_level);
c906108c
SS
482 }
483
484 /* re-show current frame. */
c5aa993b 485 show_stack_frame (cur_frame);
c906108c
SS
486}
487
488/* Switch from one thread to another. */
489
490static void
39f77062 491switch_to_thread (ptid_t ptid)
c906108c 492{
39f77062 493 if (ptid_equal (ptid, inferior_ptid))
c906108c
SS
494 return;
495
39f77062 496 inferior_ptid = ptid;
c906108c
SS
497 flush_cached_frames ();
498 registers_changed ();
c5aa993b 499 stop_pc = read_pc ();
c906108c
SS
500 select_frame (get_current_frame (), 0);
501}
502
503static void
39f77062 504restore_current_thread (ptid_t ptid)
c906108c 505{
39f77062 506 if (! ptid_equal (ptid, inferior_ptid))
c906108c 507 {
39f77062 508 switch_to_thread (ptid);
c5aa993b 509 print_stack_frame (get_current_frame (), 0, -1);
c906108c
SS
510 }
511}
512
6ecce94d
AC
513struct current_thread_cleanup
514{
39f77062 515 ptid_t inferior_ptid;
6ecce94d
AC
516};
517
518static void
519do_restore_current_thread_cleanup (void *arg)
520{
521 struct current_thread_cleanup *old = arg;
39f77062 522 restore_current_thread (old->inferior_ptid);
b8c9b27d 523 xfree (old);
6ecce94d
AC
524}
525
526static struct cleanup *
39f77062 527make_cleanup_restore_current_thread (ptid_t inferior_ptid)
6ecce94d
AC
528{
529 struct current_thread_cleanup *old
530 = xmalloc (sizeof (struct current_thread_cleanup));
39f77062 531 old->inferior_ptid = inferior_ptid;
6ecce94d
AC
532 return make_cleanup (do_restore_current_thread_cleanup, old);
533}
534
c906108c
SS
535/* Apply a GDB command to a list of threads. List syntax is a whitespace
536 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
537 of two numbers seperated by a hyphen. Examples:
538
c5aa993b
JM
539 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
540 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
541 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
542 */
c906108c
SS
543
544static void
fba45db2 545thread_apply_all_command (char *cmd, int from_tty)
c906108c
SS
546{
547 struct thread_info *tp;
548 struct cleanup *old_chain;
e35ce267
CF
549 struct cleanup *saved_cmd_cleanup_chain;
550 char *saved_cmd;
c906108c
SS
551
552 if (cmd == NULL || *cmd == '\000')
553 error ("Please specify a command following the thread ID list");
554
39f77062 555 old_chain = make_cleanup_restore_current_thread (inferior_ptid);
c906108c 556
e9d196c5
MS
557 /* It is safe to update the thread list now, before
558 traversing it for "thread apply all". MVS */
559 target_find_new_threads ();
560
e35ce267
CF
561 /* Save a copy of the command in case it is clobbered by
562 execute_command */
5b616ba1 563 saved_cmd = xstrdup (cmd);
b8c9b27d 564 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
565 for (tp = thread_list; tp; tp = tp->next)
566 if (thread_alive (tp))
567 {
39f77062 568 switch_to_thread (tp->ptid);
c906108c
SS
569#ifdef HPUXHPPA
570 printf_filtered ("\nThread %d (%s):\n",
571 tp->num,
39f77062 572 target_tid_to_str (inferior_ptid));
c906108c
SS
573#else
574 printf_filtered ("\nThread %d (%s):\n", tp->num,
39f77062 575 target_pid_to_str (inferior_ptid));
c906108c
SS
576#endif
577 execute_command (cmd, from_tty);
e35ce267 578 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c 579 }
6ecce94d 580
e35ce267 581 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 582 do_cleanups (old_chain);
c906108c
SS
583}
584
585static void
fba45db2 586thread_apply_command (char *tidlist, int from_tty)
c906108c
SS
587{
588 char *cmd;
589 char *p;
590 struct cleanup *old_chain;
e35ce267
CF
591 struct cleanup *saved_cmd_cleanup_chain;
592 char *saved_cmd;
c906108c
SS
593
594 if (tidlist == NULL || *tidlist == '\000')
595 error ("Please specify a thread ID list");
596
c5aa993b 597 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
598
599 if (*cmd == '\000')
600 error ("Please specify a command following the thread ID list");
601
39f77062 602 old_chain = make_cleanup_restore_current_thread (inferior_ptid);
c906108c 603
e35ce267
CF
604 /* Save a copy of the command in case it is clobbered by
605 execute_command */
5b616ba1 606 saved_cmd = xstrdup (cmd);
b8c9b27d 607 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
608 while (tidlist < cmd)
609 {
610 struct thread_info *tp;
611 int start, end;
612
613 start = strtol (tidlist, &p, 10);
614 if (p == tidlist)
615 error ("Error parsing %s", tidlist);
616 tidlist = p;
617
618 while (*tidlist == ' ' || *tidlist == '\t')
619 tidlist++;
620
621 if (*tidlist == '-') /* Got a range of IDs? */
622 {
c5aa993b 623 tidlist++; /* Skip the - */
c906108c
SS
624 end = strtol (tidlist, &p, 10);
625 if (p == tidlist)
626 error ("Error parsing %s", tidlist);
627 tidlist = p;
628
629 while (*tidlist == ' ' || *tidlist == '\t')
630 tidlist++;
631 }
632 else
633 end = start;
634
635 for (; start <= end; start++)
636 {
637 tp = find_thread_id (start);
638
639 if (!tp)
640 warning ("Unknown thread %d.", start);
641 else if (!thread_alive (tp))
642 warning ("Thread %d has terminated.", start);
643 else
644 {
39f77062 645 switch_to_thread (tp->ptid);
c906108c
SS
646#ifdef HPUXHPPA
647 printf_filtered ("\nThread %d (%s):\n", tp->num,
39f77062 648 target_tid_to_str (inferior_ptid));
c906108c
SS
649#else
650 printf_filtered ("\nThread %d (%s):\n", tp->num,
39f77062 651 target_pid_to_str (inferior_ptid));
c906108c
SS
652#endif
653 execute_command (cmd, from_tty);
e35ce267 654 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c
SS
655 }
656 }
657 }
6ecce94d 658
e35ce267 659 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 660 do_cleanups (old_chain);
c906108c
SS
661}
662
663/* Switch to the specified thread. Will dispatch off to thread_apply_command
664 if prefix of arg is `apply'. */
665
666static void
fba45db2 667thread_command (char *tidstr, int from_tty)
c906108c 668{
c906108c
SS
669 if (!tidstr)
670 {
671 /* Don't generate an error, just say which thread is current. */
672 if (target_has_stack)
673 printf_filtered ("[Current thread is %d (%s)]\n",
39f77062 674 pid_to_thread_id (inferior_ptid),
c906108c 675#if defined(HPUXHPPA)
39f77062 676 target_tid_to_str (inferior_ptid)
c906108c 677#else
39f77062 678 target_pid_to_str (inferior_ptid)
c906108c 679#endif
c5aa993b 680 );
c906108c
SS
681 else
682 error ("No stack.");
683 return;
684 }
c5394b80
JM
685
686 gdb_thread_select (tidstr);
687}
688
689static int
690do_captured_thread_select (void *tidstr)
691{
692 int num;
693 struct thread_info *tp;
694
81490ea1 695 num = value_as_long (parse_and_eval (tidstr));
c906108c
SS
696
697 tp = find_thread_id (num);
698
8b93c638
JM
699#ifdef UI_OUT
700 if (!tp)
701 error ("Thread ID %d not known.", num);
702#else
c906108c
SS
703 if (!tp)
704 error ("Thread ID %d not known. Use the \"info threads\" command to\n\
705see the IDs of currently known threads.", num);
8b93c638 706#endif
c906108c
SS
707
708 if (!thread_alive (tp))
709 error ("Thread ID %d has terminated.\n", num);
710
39f77062 711 switch_to_thread (tp->ptid);
c906108c 712
8b93c638
JM
713#ifdef UI_OUT
714 ui_out_text (uiout, "[Switching to thread ");
39f77062 715 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
8b93c638
JM
716 ui_out_text (uiout, " (");
717#if defined(HPUXHPPA)
39f77062 718 ui_out_text (uiout, target_tid_to_str (inferior_ptid));
8b93c638 719#else
39f77062 720 ui_out_text (uiout, target_pid_to_str (inferior_ptid));
8b93c638
JM
721#endif
722 ui_out_text (uiout, ")]");
723#else /* UI_OUT */
c906108c 724 printf_filtered ("[Switching to thread %d (%s)]\n",
39f77062 725 pid_to_thread_id (inferior_ptid),
c906108c 726#if defined(HPUXHPPA)
39f77062 727 target_tid_to_str (inferior_ptid)
c906108c 728#else
39f77062 729 target_pid_to_str (inferior_ptid)
c906108c 730#endif
c5aa993b 731 );
8b93c638 732#endif /* UI_OUT */
c5394b80 733
c906108c 734 print_stack_frame (selected_frame, selected_frame_level, 1);
c5394b80
JM
735 return GDB_RC_OK;
736}
737
738enum gdb_rc
739gdb_thread_select (char *tidstr)
740{
741 return catch_errors (do_captured_thread_select, tidstr,
742 NULL, RETURN_MASK_ALL);
c906108c
SS
743}
744
745/* Commands with a prefix of `thread'. */
746struct cmd_list_element *thread_cmd_list = NULL;
747
748void
fba45db2 749_initialize_thread (void)
c906108c
SS
750{
751 static struct cmd_list_element *thread_apply_list = NULL;
c906108c
SS
752
753 add_info ("threads", info_threads_command,
754 "IDs of currently known threads.");
755
756 add_prefix_cmd ("thread", class_run, thread_command,
757 "Use this command to switch between threads.\n\
758The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1,
759 &cmdlist);
760
761 add_prefix_cmd ("apply", class_run, thread_apply_command,
762 "Apply a command to a list of threads.",
763 &thread_apply_list, "apply ", 1, &thread_cmd_list);
764
765 add_cmd ("all", class_run, thread_apply_all_command,
766 "Apply a command to all threads.",
767 &thread_apply_list);
768
769 if (!xdb_commands)
770 add_com_alias ("t", "thread", class_run, 1);
771}
This page took 0.173482 seconds and 4 git commands to generate.