* config/pa/tm-hppa.h (SOFT_FLOAT): Delete this macro.
[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,
7789c6f5 4 1999, 2000, 2001, 2002, 2003 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
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"
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"
c906108c 43
c5aa993b 44/*#include "lynxos-core.h" */
c906108c 45
0d06e24b 46/* Definition of struct thread_info exported to gdbthread.h */
c906108c
SS
47
48/* Prototypes for exported functions. */
49
a14ed312 50void _initialize_thread (void);
c906108c
SS
51
52/* Prototypes for local functions. */
53
c906108c
SS
54static struct thread_info *thread_list = NULL;
55static int highest_thread_num;
56
a14ed312 57static struct thread_info *find_thread_id (int num);
c906108c 58
a14ed312
KB
59static void thread_command (char *tidstr, int from_tty);
60static void thread_apply_all_command (char *, int);
61static int thread_alive (struct thread_info *);
62static void info_threads_command (char *, int);
63static void thread_apply_command (char *, int);
39f77062
KB
64static void restore_current_thread (ptid_t);
65static void switch_to_thread (ptid_t ptid);
a14ed312 66static void prune_threads (void);
c906108c 67
8601f500
MS
68void
69delete_step_resume_breakpoint (void *arg)
70{
71 struct breakpoint **breakpointp = (struct breakpoint **) arg;
72 struct thread_info *tp;
73
74 if (*breakpointp != NULL)
75 {
76 delete_breakpoint (*breakpointp);
77 for (tp = thread_list; tp; tp = tp->next)
78 if (tp->step_resume_breakpoint == *breakpointp)
79 tp->step_resume_breakpoint = NULL;
80
81 *breakpointp = NULL;
82 }
83}
84
7c952b6d
ND
85static void
86free_thread (struct thread_info *tp)
87{
88 /* NOTE: this will take care of any left-over step_resume breakpoints,
89 but not any user-specified thread-specific breakpoints. */
90 if (tp->step_resume_breakpoint)
91 delete_breakpoint (tp->step_resume_breakpoint);
92
93 /* FIXME: do I ever need to call the back-end to give it a
94 chance at this private data before deleting the thread? */
95 if (tp->private)
b8c9b27d 96 xfree (tp->private);
7c952b6d 97
b8c9b27d 98 xfree (tp);
7c952b6d
ND
99}
100
c906108c 101void
fba45db2 102init_thread_list (void)
c906108c
SS
103{
104 struct thread_info *tp, *tpnext;
105
7c952b6d 106 highest_thread_num = 0;
c906108c
SS
107 if (!thread_list)
108 return;
109
110 for (tp = thread_list; tp; tp = tpnext)
111 {
112 tpnext = tp->next;
7c952b6d 113 free_thread (tp);
c906108c
SS
114 }
115
116 thread_list = NULL;
c906108c
SS
117}
118
0d06e24b
JM
119/* add_thread now returns a pointer to the new thread_info,
120 so that back_ends can initialize their private data. */
121
122struct thread_info *
39f77062 123add_thread (ptid_t ptid)
c906108c
SS
124{
125 struct thread_info *tp;
126
6c0d3f6a
MS
127 tp = (struct thread_info *) xmalloc (sizeof (*tp));
128 memset (tp, 0, sizeof (*tp));
39f77062 129 tp->ptid = ptid;
c906108c 130 tp->num = ++highest_thread_num;
c906108c
SS
131 tp->next = thread_list;
132 thread_list = tp;
0d06e24b 133 return tp;
c906108c
SS
134}
135
136void
39f77062 137delete_thread (ptid_t ptid)
c906108c
SS
138{
139 struct thread_info *tp, *tpprev;
140
141 tpprev = NULL;
142
143 for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
39f77062 144 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
145 break;
146
147 if (!tp)
148 return;
149
150 if (tpprev)
151 tpprev->next = tp->next;
152 else
153 thread_list = tp->next;
154
7c952b6d 155 free_thread (tp);
c906108c
SS
156}
157
158static struct thread_info *
fba45db2 159find_thread_id (int num)
c906108c
SS
160{
161 struct thread_info *tp;
162
163 for (tp = thread_list; tp; tp = tp->next)
164 if (tp->num == num)
165 return tp;
166
167 return NULL;
168}
169
39f77062 170/* Find a thread_info by matching PTID. */
0d06e24b 171struct thread_info *
39f77062 172find_thread_pid (ptid_t ptid)
0d06e24b
JM
173{
174 struct thread_info *tp;
175
176 for (tp = thread_list; tp; tp = tp->next)
39f77062 177 if (ptid_equal (tp->ptid, ptid))
0d06e24b
JM
178 return tp;
179
180 return NULL;
181}
182
183/*
184 * Thread iterator function.
185 *
186 * Calls a callback function once for each thread, so long as
187 * the callback function returns false. If the callback function
188 * returns true, the iteration will end and the current thread
189 * will be returned. This can be useful for implementing a
190 * search for a thread with arbitrary attributes, or for applying
191 * some operation to every thread.
192 *
193 * FIXME: some of the existing functionality, such as
194 * "Thread apply all", might be rewritten using this functionality.
195 */
196
197struct thread_info *
fd118b61
KB
198iterate_over_threads (int (*callback) (struct thread_info *, void *),
199 void *data)
0d06e24b
JM
200{
201 struct thread_info *tp;
202
203 for (tp = thread_list; tp; tp = tp->next)
204 if ((*callback) (tp, data))
205 return tp;
206
207 return NULL;
208}
209
c906108c 210int
fba45db2 211valid_thread_id (int num)
c906108c
SS
212{
213 struct thread_info *tp;
214
215 for (tp = thread_list; tp; tp = tp->next)
216 if (tp->num == num)
217 return 1;
218
219 return 0;
220}
221
222int
39f77062 223pid_to_thread_id (ptid_t ptid)
c906108c
SS
224{
225 struct thread_info *tp;
226
227 for (tp = thread_list; tp; tp = tp->next)
39f77062 228 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
229 return tp->num;
230
231 return 0;
232}
233
39f77062 234ptid_t
fba45db2 235thread_id_to_pid (int num)
c906108c
SS
236{
237 struct thread_info *thread = find_thread_id (num);
238 if (thread)
39f77062 239 return thread->ptid;
c906108c 240 else
39f77062 241 return pid_to_ptid (-1);
c906108c
SS
242}
243
244int
39f77062 245in_thread_list (ptid_t ptid)
c906108c
SS
246{
247 struct thread_info *tp;
248
249 for (tp = thread_list; tp; tp = tp->next)
39f77062 250 if (ptid_equal (tp->ptid, ptid))
c906108c
SS
251 return 1;
252
253 return 0; /* Never heard of 'im */
254}
8926118c 255
8b93c638
JM
256/* Print a list of thread ids currently known, and the total number of
257 threads. To be used from within catch_errors. */
6949171e
JJ
258static int
259do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
8b93c638
JM
260{
261 struct thread_info *tp;
262 int num = 0;
3b31d625 263 struct cleanup *cleanup_chain;
8b93c638 264
7990a578
EZ
265 prune_threads ();
266 target_find_new_threads ();
267
3b31d625 268 cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids");
8b93c638
JM
269
270 for (tp = thread_list; tp; tp = tp->next)
271 {
272 num++;
273 ui_out_field_int (uiout, "thread-id", tp->num);
274 }
275
3b31d625 276 do_cleanups (cleanup_chain);
8b93c638
JM
277 ui_out_field_int (uiout, "number-of-threads", num);
278 return GDB_RC_OK;
279}
280
281/* Official gdblib interface function to get a list of thread ids and
282 the total number. */
283enum gdb_rc
2b65245e 284gdb_list_thread_ids (struct ui_out *uiout)
8b93c638 285{
2b65245e
AC
286 return catch_exceptions (uiout, do_captured_list_thread_ids, NULL,
287 NULL, RETURN_MASK_ALL);
8b93c638 288}
c906108c
SS
289
290/* Load infrun state for the thread PID. */
291
c5aa993b 292void
6949171e
JJ
293load_infrun_state (ptid_t ptid,
294 CORE_ADDR *prev_pc,
6949171e 295 char **prev_func_name,
6c0d3f6a 296 int *trap_expected,
fba45db2
KB
297 struct breakpoint **step_resume_breakpoint,
298 struct breakpoint **through_sigtramp_breakpoint,
6949171e 299 CORE_ADDR *step_range_start,
6c0d3f6a 300 CORE_ADDR *step_range_end,
6949171e 301 struct frame_id *step_frame_id,
6c0d3f6a 302 int *handling_longjmp,
6949171e 303 int *another_trap,
6c0d3f6a 304 int *stepping_through_solib_after_catch,
fba45db2 305 bpstat *stepping_through_solib_catchpoints,
6c0d3f6a 306 int *stepping_through_sigtramp,
6949171e
JJ
307 int *current_line,
308 struct symtab **current_symtab, 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;
c906108c 319 *prev_func_name = tp->prev_func_name;
6c0d3f6a 320 *trap_expected = tp->trap_expected;
c906108c 321 *step_resume_breakpoint = tp->step_resume_breakpoint;
6c0d3f6a 322 *through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint;
c906108c
SS
323 *step_range_start = tp->step_range_start;
324 *step_range_end = tp->step_range_end;
aa0cd9c1 325 *step_frame_id = tp->step_frame_id;
c906108c 326 *handling_longjmp = tp->handling_longjmp;
c906108c 327 *another_trap = tp->another_trap;
6949171e
JJ
328 *stepping_through_solib_after_catch =
329 tp->stepping_through_solib_after_catch;
330 *stepping_through_solib_catchpoints =
331 tp->stepping_through_solib_catchpoints;
c906108c 332 *stepping_through_sigtramp = tp->stepping_through_sigtramp;
6c0d3f6a
MS
333 *current_line = tp->current_line;
334 *current_symtab = tp->current_symtab;
335 *step_sp = tp->step_sp;
c906108c
SS
336}
337
338/* Save infrun state for the thread PID. */
339
c5aa993b 340void
6949171e
JJ
341save_infrun_state (ptid_t ptid,
342 CORE_ADDR prev_pc,
6949171e 343 char *prev_func_name,
6c0d3f6a 344 int trap_expected,
fba45db2
KB
345 struct breakpoint *step_resume_breakpoint,
346 struct breakpoint *through_sigtramp_breakpoint,
6949171e 347 CORE_ADDR step_range_start,
6c0d3f6a 348 CORE_ADDR step_range_end,
6949171e 349 const struct frame_id *step_frame_id,
6c0d3f6a 350 int handling_longjmp,
6949171e 351 int another_trap,
6c0d3f6a 352 int stepping_through_solib_after_catch,
fba45db2 353 bpstat stepping_through_solib_catchpoints,
6949171e 354 int stepping_through_sigtramp,
6c0d3f6a 355 int current_line,
6949171e 356 struct symtab *current_symtab, CORE_ADDR step_sp)
c906108c
SS
357{
358 struct thread_info *tp;
359
360 /* If we can't find the thread, then we're debugging a single-threaded
361 process. Nothing to do in that case. */
39f77062 362 tp = find_thread_id (pid_to_thread_id (ptid));
c906108c
SS
363 if (tp == NULL)
364 return;
365
366 tp->prev_pc = prev_pc;
c906108c 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;
aa0cd9c1 373 tp->step_frame_id = (*step_frame_id);
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 423 struct frame_info *cur_frame;
6e7f8b9c 424 int saved_frame_level = frame_relative_level (deprecated_selected_frame);
c5aa993b 425 int counter;
0d06e24b 426 char *extra_info;
c906108c
SS
427
428 /* Avoid coredumps which would happen if we tried to access a NULL
6e7f8b9c 429 deprecated_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);
6e7f8b9c 455 if (deprecated_selected_frame)
7789c6f5 456 print_stack_frame (deprecated_selected_frame, -1, 0);
c906108c
SS
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 469 counter = saved_frame_level;
6e7f8b9c 470 cur_frame = find_relative_frame (deprecated_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");
6e7f8b9c 475 print_stack_frame (deprecated_selected_frame, -1, 0);
c906108c
SS
476 }
477 else
478 {
0f7d239c 479 select_frame (cur_frame);
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 ();
0f7d239c 498 select_frame (get_current_frame ());
c906108c
SS
499}
500
501static void
39f77062 502restore_current_thread (ptid_t ptid)
c906108c 503{
6949171e 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",
6949171e 569 tp->num, target_tid_to_str (inferior_ptid));
c906108c
SS
570#else
571 printf_filtered ("\nThread %d (%s):\n", tp->num,
39f77062 572 target_pid_to_str (inferior_ptid));
c906108c
SS
573#endif
574 execute_command (cmd, from_tty);
6949171e 575 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c 576 }
6ecce94d 577
e35ce267 578 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 579 do_cleanups (old_chain);
c906108c
SS
580}
581
582static void
fba45db2 583thread_apply_command (char *tidlist, int from_tty)
c906108c
SS
584{
585 char *cmd;
586 char *p;
587 struct cleanup *old_chain;
e35ce267
CF
588 struct cleanup *saved_cmd_cleanup_chain;
589 char *saved_cmd;
c906108c
SS
590
591 if (tidlist == NULL || *tidlist == '\000')
592 error ("Please specify a thread ID list");
593
c5aa993b 594 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
595
596 if (*cmd == '\000')
597 error ("Please specify a command following the thread ID list");
598
39f77062 599 old_chain = make_cleanup_restore_current_thread (inferior_ptid);
c906108c 600
e35ce267
CF
601 /* Save a copy of the command in case it is clobbered by
602 execute_command */
5b616ba1 603 saved_cmd = xstrdup (cmd);
b8c9b27d 604 saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
c906108c
SS
605 while (tidlist < cmd)
606 {
607 struct thread_info *tp;
608 int start, end;
609
610 start = strtol (tidlist, &p, 10);
611 if (p == tidlist)
612 error ("Error parsing %s", tidlist);
613 tidlist = p;
614
615 while (*tidlist == ' ' || *tidlist == '\t')
616 tidlist++;
617
618 if (*tidlist == '-') /* Got a range of IDs? */
619 {
c5aa993b 620 tidlist++; /* Skip the - */
c906108c
SS
621 end = strtol (tidlist, &p, 10);
622 if (p == tidlist)
623 error ("Error parsing %s", tidlist);
624 tidlist = p;
625
626 while (*tidlist == ' ' || *tidlist == '\t')
627 tidlist++;
628 }
629 else
630 end = start;
631
632 for (; start <= end; start++)
633 {
634 tp = find_thread_id (start);
635
636 if (!tp)
637 warning ("Unknown thread %d.", start);
638 else if (!thread_alive (tp))
639 warning ("Thread %d has terminated.", start);
640 else
641 {
39f77062 642 switch_to_thread (tp->ptid);
c906108c
SS
643#ifdef HPUXHPPA
644 printf_filtered ("\nThread %d (%s):\n", tp->num,
39f77062 645 target_tid_to_str (inferior_ptid));
c906108c
SS
646#else
647 printf_filtered ("\nThread %d (%s):\n", tp->num,
39f77062 648 target_pid_to_str (inferior_ptid));
c906108c
SS
649#endif
650 execute_command (cmd, from_tty);
e35ce267 651 strcpy (cmd, saved_cmd); /* Restore exact command used previously */
c906108c
SS
652 }
653 }
654 }
6ecce94d 655
e35ce267 656 do_cleanups (saved_cmd_cleanup_chain);
6ecce94d 657 do_cleanups (old_chain);
c906108c
SS
658}
659
660/* Switch to the specified thread. Will dispatch off to thread_apply_command
661 if prefix of arg is `apply'. */
662
663static void
fba45db2 664thread_command (char *tidstr, int from_tty)
c906108c 665{
c906108c
SS
666 if (!tidstr)
667 {
668 /* Don't generate an error, just say which thread is current. */
669 if (target_has_stack)
670 printf_filtered ("[Current thread is %d (%s)]\n",
39f77062 671 pid_to_thread_id (inferior_ptid),
c906108c 672#if defined(HPUXHPPA)
39f77062 673 target_tid_to_str (inferior_ptid)
c906108c 674#else
39f77062 675 target_pid_to_str (inferior_ptid)
c906108c 676#endif
c5aa993b 677 );
c906108c
SS
678 else
679 error ("No stack.");
680 return;
681 }
c5394b80 682
2b65245e 683 gdb_thread_select (uiout, tidstr);
c5394b80
JM
684}
685
686static int
6949171e 687do_captured_thread_select (struct ui_out *uiout, void *tidstr)
c5394b80
JM
688{
689 int num;
690 struct thread_info *tp;
691
81490ea1 692 num = value_as_long (parse_and_eval (tidstr));
c906108c
SS
693
694 tp = find_thread_id (num);
695
8b93c638
JM
696 if (!tp)
697 error ("Thread ID %d not known.", num);
c906108c
SS
698
699 if (!thread_alive (tp))
700 error ("Thread ID %d has terminated.\n", num);
701
39f77062 702 switch_to_thread (tp->ptid);
c906108c 703
8b93c638 704 ui_out_text (uiout, "[Switching to thread ");
39f77062 705 ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
8b93c638
JM
706 ui_out_text (uiout, " (");
707#if defined(HPUXHPPA)
39f77062 708 ui_out_text (uiout, target_tid_to_str (inferior_ptid));
8b93c638 709#else
39f77062 710 ui_out_text (uiout, target_pid_to_str (inferior_ptid));
8b93c638
JM
711#endif
712 ui_out_text (uiout, ")]");
c5394b80 713
6e7f8b9c
AC
714 print_stack_frame (deprecated_selected_frame,
715 frame_relative_level (deprecated_selected_frame), 1);
c5394b80
JM
716 return GDB_RC_OK;
717}
718
719enum gdb_rc
6949171e 720gdb_thread_select (struct ui_out *uiout, char *tidstr)
c5394b80 721{
2b65245e
AC
722 return catch_exceptions (uiout, do_captured_thread_select, tidstr,
723 NULL, RETURN_MASK_ALL);
c906108c
SS
724}
725
726/* Commands with a prefix of `thread'. */
727struct cmd_list_element *thread_cmd_list = NULL;
728
729void
fba45db2 730_initialize_thread (void)
c906108c
SS
731{
732 static struct cmd_list_element *thread_apply_list = NULL;
c906108c
SS
733
734 add_info ("threads", info_threads_command,
735 "IDs of currently known threads.");
736
737 add_prefix_cmd ("thread", class_run, thread_command,
738 "Use this command to switch between threads.\n\
6949171e 739The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1, &cmdlist);
c906108c
SS
740
741 add_prefix_cmd ("apply", class_run, thread_apply_command,
742 "Apply a command to a list of threads.",
743 &thread_apply_list, "apply ", 1, &thread_cmd_list);
744
745 add_cmd ("all", class_run, thread_apply_all_command,
6949171e 746 "Apply a command to all threads.", &thread_apply_list);
c906108c
SS
747
748 if (!xdb_commands)
749 add_com_alias ("t", "thread", class_run, 1);
750}
This page took 0.368238 seconds and 4 git commands to generate.