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