all remaining *.c *.h files from hp merge.
[deliverable/binutils-gdb.git] / gdb / thread.c
1 /* Multi-process/thread control for GDB, the GNU debugger.
2 Copyright 1986, 1987, 1988, 1993, 1998
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, Boston, MA 02111-1307, USA. */
22
23 #include "defs.h"
24 #include "symtab.h"
25 #include "frame.h"
26 #include "inferior.h"
27 #include "environ.h"
28 #include "value.h"
29 #include "target.h"
30 #include "gdbthread.h"
31 #include "command.h"
32 #include "gdbcmd.h"
33
34 #include <ctype.h>
35 #include <sys/types.h>
36 #include <signal.h>
37
38 /*#include "lynxos-core.h"*/
39
40 struct thread_info
41 {
42 struct thread_info *next;
43 int pid; /* Actual process id */
44 int num; /* Convenient handle */
45 CORE_ADDR prev_pc; /* State from wait_for_inferior */
46 CORE_ADDR prev_func_start;
47 char *prev_func_name;
48 struct breakpoint *step_resume_breakpoint;
49 struct breakpoint *through_sigtramp_breakpoint;
50 CORE_ADDR step_range_start;
51 CORE_ADDR step_range_end;
52 CORE_ADDR step_frame_address;
53 int trap_expected;
54 int handling_longjmp;
55 int another_trap;
56
57 /* This is set TRUE when a catchpoint of a shared library event
58 triggers. Since we don't wish to leave the inferior in the
59 solib hook when we report the event, we step the inferior
60 back to user code before stopping and reporting the event.
61 */
62 int stepping_through_solib_after_catch;
63
64 /* When stepping_through_solib_after_catch is TRUE, this is a
65 list of the catchpoints that should be reported as triggering
66 when we finally do stop stepping.
67 */
68 bpstat stepping_through_solib_catchpoints;
69
70 /* This is set to TRUE when this thread is in a signal handler
71 trampoline and we're single-stepping through it */
72 int stepping_through_sigtramp;
73
74 };
75
76 static struct target_thread_vector *target_thread_functions;
77
78 int
79 target_find_new_threads ()
80 {
81 int retval = 0;
82 if (target_thread_functions &&
83 target_thread_functions->find_new_threads)
84 retval = (*(target_thread_functions->find_new_threads)) ();
85 return retval; /* no support */
86 }
87
88
89 int
90 target_get_thread_info PARAMS ((
91 gdb_threadref * ref,
92 int selection, /* FIXME: Selection */
93 struct gdb_ext_thread_info * info));
94
95 int
96 target_get_thread_info (ref, selection, info)
97
98 gdb_threadref *ref;
99 int selection;
100 /* FIXME: Selection */
101 struct gdb_ext_thread_info *info;
102
103 {
104 int retval = 0;
105 if (target_thread_functions
106 && target_thread_functions->get_thread_info)
107 retval = (*(target_thread_functions->get_thread_info)) (ref, selection, info);
108 return retval;
109 }
110
111
112 /* It is possible that these bind and unbinf functions implement a
113 stack the interface allows it, but its not implemented that way
114 */
115
116
117 void
118 bind_target_thread_vector (vec)
119 struct target_thread_vector *vec;
120 {
121 target_thread_functions = vec;
122 }
123
124 /* Prototypes for exported functions. */
125
126 struct target_thread_vector *
127 unbind_target_thread_vector ()
128 {
129 struct target_thread_vector *retval;
130 retval = target_thread_functions;
131 target_thread_functions = 0;
132 return retval;
133 } /* unbind_target_thread-vector */
134
135 void _initialize_thread PARAMS ((void));
136
137
138 /* Prototypes for local functions. */
139 /* If the host has threads, the host machine definition may
140 set this macro. But, for remote thread debugging, it gets more
141 complex and setting macros does not bind to the various target
142 dependent methods well. So, we use the vector target_thread_functions
143 */
144 #if !defined(FIND_NEW_THREADS)
145 #define FIND_NEW_THREADS target_find_new_threads
146 #endif
147
148 static struct thread_info *thread_list = NULL;
149 static int highest_thread_num;
150
151 static void
152 thread_command PARAMS ((char * tidstr, int from_tty));
153 static void
154 prune_threads PARAMS ((void));
155
156 static void
157 switch_to_thread PARAMS ((int pid));
158
159 static struct thread_info *
160 find_thread_id PARAMS ((int num));
161
162 static void
163 info_threads_command PARAMS ((char *, int));
164
165 static void
166 restore_current_thread PARAMS ((int));
167
168 static void
169 thread_apply_all_command PARAMS ((char *, int));
170
171 static void
172 thread_apply_command PARAMS ((char *, int));
173
174 static void info_threads_command PARAMS ((char *, int));
175
176 static void restore_current_thread PARAMS ((int));
177
178 static void thread_apply_all_command PARAMS ((char *, int));
179
180 static void thread_apply_command PARAMS ((char *, int));
181
182 static int thread_alive PARAMS ((struct thread_info *));
183
184 void
185 init_thread_list ()
186 {
187 struct thread_info *tp, *tpnext;
188
189 if (!thread_list)
190 return;
191
192 for (tp = thread_list; tp; tp = tpnext)
193 {
194 tpnext = tp->next;
195 free (tp);
196 }
197
198 thread_list = NULL;
199 highest_thread_num = 0;
200 }
201
202 void
203 add_thread (pid)
204 int pid;
205 {
206 struct thread_info *tp;
207
208 tp = (struct thread_info *) xmalloc (sizeof (struct thread_info));
209
210 tp->pid = pid;
211 tp->num = ++highest_thread_num;
212 tp->prev_pc = 0;
213 tp->prev_func_start = 0;
214 tp->prev_func_name = NULL;
215 tp->step_range_start = 0;
216 tp->step_range_end = 0;
217 tp->step_frame_address =0;
218 tp->step_resume_breakpoint = 0;
219 tp->through_sigtramp_breakpoint = 0;
220 tp->handling_longjmp = 0;
221 tp->trap_expected = 0;
222 tp->another_trap = 0;
223 tp->stepping_through_solib_after_catch = 0;
224 tp->stepping_through_solib_catchpoints = NULL;
225 tp->stepping_through_sigtramp = 0;
226 tp->next = thread_list;
227 thread_list = tp;
228 }
229
230 void
231 delete_thread (pid)
232 int pid;
233 {
234 struct thread_info *tp, *tpprev;
235
236 tpprev = NULL;
237
238 for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
239 if (tp->pid == pid)
240 break;
241
242 if (!tp)
243 return;
244
245 if (tpprev)
246 tpprev->next = tp->next;
247 else
248 thread_list = tp->next;
249
250 free (tp);
251
252 return;
253 }
254
255 static struct thread_info *
256 find_thread_id (num)
257 int num;
258 {
259 struct thread_info *tp;
260
261 for (tp = thread_list; tp; tp = tp->next)
262 if (tp->num == num)
263 return tp;
264
265 return NULL;
266 }
267
268 int
269 valid_thread_id (num)
270 int num;
271 {
272 struct thread_info *tp;
273
274 for (tp = thread_list; tp; tp = tp->next)
275 if (tp->num == num)
276 return 1;
277
278 return 0;
279 }
280
281 int
282 pid_to_thread_id (pid)
283 int pid;
284 {
285 struct thread_info *tp;
286
287 for (tp = thread_list; tp; tp = tp->next)
288 if (tp->pid == pid)
289 return tp->num;
290
291 return 0;
292 }
293
294 int
295 thread_id_to_pid (num)
296 int num;
297 {
298 struct thread_info *thread = find_thread_id (num);
299 if (thread)
300 return thread->pid;
301 else
302 return -1;
303 }
304
305 int
306 in_thread_list (pid)
307 int pid;
308 {
309 struct thread_info *tp;
310
311 for (tp = thread_list; tp; tp = tp->next)
312 if (tp->pid == pid)
313 return 1;
314
315 return 0; /* Never heard of 'im */
316 }
317
318 /* Load infrun state for the thread PID. */
319
320 void load_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
321 trap_expected, step_resume_breakpoint,
322 through_sigtramp_breakpoint, step_range_start,
323 step_range_end, step_frame_address,
324 handling_longjmp, another_trap,
325 stepping_through_solib_after_catch,
326 stepping_through_solib_catchpoints,
327 stepping_through_sigtramp)
328 int pid;
329 CORE_ADDR *prev_pc;
330 CORE_ADDR *prev_func_start;
331 char **prev_func_name;
332 int *trap_expected;
333 struct breakpoint **step_resume_breakpoint;
334 struct breakpoint **through_sigtramp_breakpoint;
335 CORE_ADDR *step_range_start;
336 CORE_ADDR *step_range_end;
337 CORE_ADDR *step_frame_address;
338 int *handling_longjmp;
339 int *another_trap;
340 int * stepping_through_solib_after_catch;
341 bpstat * stepping_through_solib_catchpoints;
342 int * stepping_through_sigtramp;
343 {
344 struct thread_info *tp;
345
346 /* If we can't find the thread, then we're debugging a single threaded
347 process. No need to do anything in that case. */
348 tp = find_thread_id (pid_to_thread_id (pid));
349 if (tp == NULL)
350 return;
351
352 *prev_pc = tp->prev_pc;
353 *prev_func_start = tp->prev_func_start;
354 *prev_func_name = tp->prev_func_name;
355 *step_resume_breakpoint = tp->step_resume_breakpoint;
356 *step_range_start = tp->step_range_start;
357 *step_range_end = tp->step_range_end;
358 *step_frame_address = tp->step_frame_address;
359 *through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint;
360 *handling_longjmp = tp->handling_longjmp;
361 *trap_expected = tp->trap_expected;
362 *another_trap = tp->another_trap;
363 *stepping_through_solib_after_catch = tp->stepping_through_solib_after_catch;
364 *stepping_through_solib_catchpoints = tp->stepping_through_solib_catchpoints;
365 *stepping_through_sigtramp = tp->stepping_through_sigtramp;
366 }
367
368 /* Save infrun state for the thread PID. */
369
370 void save_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
371 trap_expected, step_resume_breakpoint,
372 through_sigtramp_breakpoint, step_range_start,
373 step_range_end, step_frame_address,
374 handling_longjmp, another_trap,
375 stepping_through_solib_after_catch,
376 stepping_through_solib_catchpoints,
377 stepping_through_sigtramp)
378 int pid;
379 CORE_ADDR prev_pc;
380 CORE_ADDR prev_func_start;
381 char *prev_func_name;
382 int trap_expected;
383 struct breakpoint *step_resume_breakpoint;
384 struct breakpoint *through_sigtramp_breakpoint;
385 CORE_ADDR step_range_start;
386 CORE_ADDR step_range_end;
387 CORE_ADDR step_frame_address;
388 int handling_longjmp;
389 int another_trap;
390 int stepping_through_solib_after_catch;
391 bpstat stepping_through_solib_catchpoints;
392 int stepping_through_sigtramp;
393 {
394 struct thread_info *tp;
395
396 /* If we can't find the thread, then we're debugging a single-threaded
397 process. Nothing to do in that case. */
398 tp = find_thread_id (pid_to_thread_id (pid));
399 if (tp == NULL)
400 return;
401
402 tp->prev_pc = prev_pc;
403 tp->prev_func_start = prev_func_start;
404 tp->prev_func_name = prev_func_name;
405 tp->step_resume_breakpoint = step_resume_breakpoint;
406 tp->step_range_start = step_range_start;
407 tp->step_range_end = step_range_end;
408 tp->step_frame_address = step_frame_address;
409 tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint;
410 tp->handling_longjmp = handling_longjmp;
411 tp->trap_expected = trap_expected;
412 tp->another_trap = another_trap;
413 tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
414 tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
415 tp->stepping_through_sigtramp = stepping_through_sigtramp;
416 }
417
418 /* Return true if TP is an active thread. */
419 static int
420 thread_alive (tp)
421 struct thread_info *tp;
422 {
423 if (tp->pid == -1)
424 return 0;
425 if (! target_thread_alive (tp->pid))
426 {
427 tp->pid = -1; /* Mark it as dead */
428 return 0;
429 }
430 return 1;
431 }
432
433 static void
434 prune_threads ()
435 {
436 struct thread_info *tp, *tpprev, *next;
437
438 tpprev = 0;
439 for (tp = thread_list; tp; tp = next)
440 {
441 next = tp->next;
442 if (!thread_alive (tp))
443 {
444 if (tpprev)
445 tpprev->next = next;
446 else
447 thread_list = next;
448 free (tp);
449 }
450 else
451 tpprev = tp;
452 }
453 }
454
455 /* Print information about currently known threads
456 *
457 * Note: this has the drawback that it _really_ switches
458 * threads, which frees the frame cache. A no-side
459 * effects info-threads command would be nicer.
460 */
461
462 static void
463 info_threads_command (arg, from_tty)
464 char *arg;
465 int from_tty;
466 {
467 struct thread_info *tp;
468 int current_pid = inferior_pid;
469 struct frame_info *cur_frame;
470 int saved_frame_level = selected_frame_level;
471 int counter;
472
473 /* Avoid coredumps which would happen if we tried to access a NULL
474 selected_frame. */
475 if (!target_has_stack) error ("No stack.");
476
477 prune_threads ();
478 #if defined(FIND_NEW_THREADS)
479 FIND_NEW_THREADS ();
480 #endif
481
482 for (tp = thread_list; tp; tp = tp->next)
483 {
484 if (tp->pid == current_pid)
485 printf_filtered ("* ");
486 else
487 printf_filtered (" ");
488
489 #ifdef HPUXHPPA
490 printf_filtered ("%d %s ", tp->num, target_tid_to_str (tp->pid));
491 #else
492 printf_filtered ("%d %s ", tp->num, target_pid_to_str (tp->pid));
493 #endif
494 switch_to_thread (tp->pid);
495 if (selected_frame)
496 print_only_stack_frame (selected_frame, -1, 0);
497 else
498 printf_filtered ("[No stack.]\n");
499 }
500
501 switch_to_thread (current_pid);
502
503 /* Code below copied from "up_silently_base" in "stack.c".
504 * It restores the frame set by the user before the "info threads"
505 * command. We have finished the info-threads display by switching
506 * back to the current thread. That switch has put us at the top
507 * of the stack (leaf frame).
508 */
509 counter = saved_frame_level;
510 cur_frame = find_relative_frame(selected_frame, &counter);
511 if (counter != 0) {
512 /* Ooops, can't restore, tell user where we are. */
513 warning ("Couldn't restore frame in current thread, at frame 0");
514 print_stack_frame (selected_frame, -1, 0);
515 }
516 else {
517 select_frame(cur_frame, saved_frame_level);
518 }
519
520 /* re-show current frame. */
521 show_stack_frame(cur_frame);
522 }
523
524 /* Switch from one thread to another. */
525
526 static void
527 switch_to_thread (pid)
528 int pid;
529 {
530 if (pid == inferior_pid)
531 return;
532
533 inferior_pid = pid;
534 flush_cached_frames ();
535 registers_changed ();
536 stop_pc = read_pc();
537 select_frame (get_current_frame (), 0);
538 }
539
540 static void
541 restore_current_thread (pid)
542 int pid;
543 {
544 if (pid != inferior_pid) {
545 switch_to_thread (pid);
546 print_stack_frame( get_current_frame(), 0, -1);
547 }
548 }
549
550 /* Apply a GDB command to a list of threads. List syntax is a whitespace
551 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
552 of two numbers seperated by a hyphen. Examples:
553
554 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
555 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
556 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
557 */
558
559 static void
560 thread_apply_all_command (cmd, from_tty)
561 char *cmd;
562 int from_tty;
563 {
564 struct thread_info *tp;
565 struct cleanup *old_chain;
566
567 if (cmd == NULL || *cmd == '\000')
568 error ("Please specify a command following the thread ID list");
569
570 old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
571 (void *) inferior_pid);
572
573 for (tp = thread_list; tp; tp = tp->next)
574 if (thread_alive (tp))
575 {
576 switch_to_thread (tp->pid);
577 #ifdef HPUXHPPA
578 printf_filtered ("\nThread %d (%s):\n",
579 tp->num,
580 target_tid_to_str (inferior_pid));
581 #else
582 printf_filtered ("\nThread %d (%s):\n", tp->num,
583 target_pid_to_str (inferior_pid));
584 #endif
585 execute_command (cmd, from_tty);
586 }
587 }
588
589 static void
590 thread_apply_command (tidlist, from_tty)
591 char *tidlist;
592 int from_tty;
593 {
594 char *cmd;
595 char *p;
596 struct cleanup *old_chain;
597
598 if (tidlist == NULL || *tidlist == '\000')
599 error ("Please specify a thread ID list");
600
601 for (cmd = tidlist; *cmd != '\000' && !isalpha(*cmd); cmd++);
602
603 if (*cmd == '\000')
604 error ("Please specify a command following the thread ID list");
605
606 old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
607 (void *) inferior_pid);
608
609 while (tidlist < cmd)
610 {
611 struct thread_info *tp;
612 int start, end;
613
614 start = strtol (tidlist, &p, 10);
615 if (p == tidlist)
616 error ("Error parsing %s", tidlist);
617 tidlist = p;
618
619 while (*tidlist == ' ' || *tidlist == '\t')
620 tidlist++;
621
622 if (*tidlist == '-') /* Got a range of IDs? */
623 {
624 tidlist++; /* Skip the - */
625 end = strtol (tidlist, &p, 10);
626 if (p == tidlist)
627 error ("Error parsing %s", tidlist);
628 tidlist = p;
629
630 while (*tidlist == ' ' || *tidlist == '\t')
631 tidlist++;
632 }
633 else
634 end = start;
635
636 for (; start <= end; start++)
637 {
638 tp = find_thread_id (start);
639
640 if (!tp)
641 warning ("Unknown thread %d.", start);
642 else if (!thread_alive (tp))
643 warning ("Thread %d has terminated.", start);
644 else
645 {
646 switch_to_thread (tp->pid);
647 #ifdef HPUXHPPA
648 printf_filtered ("\nThread %d (%s):\n", tp->num,
649 target_tid_to_str (inferior_pid));
650 #else
651 printf_filtered ("\nThread %d (%s):\n", tp->num,
652 target_pid_to_str (inferior_pid));
653 #endif
654 execute_command (cmd, from_tty);
655 }
656 }
657 }
658 }
659
660 /* Switch to the specified thread. Will dispatch off to thread_apply_command
661 if prefix of arg is `apply'. */
662
663 static void
664 thread_command (tidstr, from_tty)
665 char *tidstr;
666 int from_tty;
667 {
668 int num;
669 struct thread_info *tp;
670
671 if (!tidstr)
672 {
673 /* Don't generate an error, just say which thread is current. */
674 if (target_has_stack)
675 printf_filtered ("[Current thread is %d (%s)]\n",
676 pid_to_thread_id(inferior_pid),
677 #if defined(HPUXHPPA)
678 target_tid_to_str(inferior_pid)
679 #else
680 target_pid_to_str(inferior_pid)
681 #endif
682 );
683 else
684 error ("No stack.");
685 return;
686 }
687 num = atoi (tidstr);
688
689 tp = find_thread_id (num);
690
691 if (!tp)
692 error ("Thread ID %d not known. Use the \"info threads\" command to\n\
693 see the IDs of currently known threads.", num);
694
695 if (!thread_alive (tp))
696 error ("Thread ID %d has terminated.\n", num);
697
698 switch_to_thread (tp->pid);
699
700 if (context_hook)
701 context_hook (num);
702
703 printf_filtered ("[Switching to thread %d (%s)]\n",
704 pid_to_thread_id (inferior_pid),
705 #if defined(HPUXHPPA)
706 target_tid_to_str (inferior_pid)
707 #else
708 target_pid_to_str (inferior_pid)
709 #endif
710 );
711 print_stack_frame (selected_frame, selected_frame_level, 1);
712 }
713
714 /* Commands with a prefix of `thread'. */
715 struct cmd_list_element *thread_cmd_list = NULL;
716
717 void
718 _initialize_thread ()
719 {
720 static struct cmd_list_element *thread_apply_list = NULL;
721 extern struct cmd_list_element *cmdlist;
722
723 add_info ("threads", info_threads_command,
724 "IDs of currently known threads.");
725
726 add_prefix_cmd ("thread", class_run, thread_command,
727 "Use this command to switch between threads.\n\
728 The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1,
729 &cmdlist);
730
731 add_prefix_cmd ("apply", class_run, thread_apply_command,
732 "Apply a command to a list of threads.",
733 &thread_apply_list, "apply ", 1, &thread_cmd_list);
734
735 add_cmd ("all", class_run, thread_apply_all_command,
736 "Apply a command to all threads.",
737 &thread_apply_list);
738
739 if (!xdb_commands)
740 add_com_alias ("t", "thread", class_run, 1);
741 }
This page took 0.067437 seconds and 5 git commands to generate.