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