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