att ChangeLog.
[deliverable/binutils-gdb.git] / gdb / thread.c
CommitLineData
da0baf42 1/* Multi-process/thread control for GDB, the GNU debugger.
87feff9d 2 Copyright 1986, 1987, 1988, 1993, 1998
da0baf42
SG
3
4 Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
5 Free Software Foundation, Inc.
6
7This file is part of GDB.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
6c9638b4 21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25286543
SG
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"
fdfa3315 30#include "gdbthread.h"
46c28185 31#include "command.h"
89ce0c8f 32#include "gdbcmd.h"
25286543 33
89ce0c8f 34#include <ctype.h>
25286543
SG
35#include <sys/types.h>
36#include <signal.h>
37
38/*#include "lynxos-core.h"*/
39
40struct thread_info
41{
42 struct thread_info *next;
43 int pid; /* Actual process id */
44 int num; /* Convenient handle */
88a294b1
JL
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;
25286543 56
65b07ddc
DT
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;
25286543 69
65b07ddc
DT
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};
9ee59844
JM
75
76static struct target_thread_vector *target_thread_functions;
77
78int
79target_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
89int
90target_get_thread_info PARAMS ((
91 gdb_threadref * ref,
92 int selection, /* FIXME: Selection */
93 struct gdb_ext_thread_info * info));
94
95int
96target_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
117void
118bind_target_thread_vector (vec)
119 struct target_thread_vector *vec;
120{
121 target_thread_functions = vec;
122}
65b07ddc 123
879c0417 124/* Prototypes for exported functions. */
25286543 125
9ee59844
JM
126struct target_thread_vector *
127unbind_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
879c0417 135void _initialize_thread PARAMS ((void));
25286543 136
9ee59844 137
879c0417 138/* Prototypes for local functions. */
9ee59844
JM
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
148static struct thread_info *thread_list = NULL;
149static int highest_thread_num;
150
151static void
152thread_command PARAMS ((char * tidstr, int from_tty));
153static void
154prune_threads PARAMS ((void));
155
156static void
157switch_to_thread PARAMS ((int pid));
158
159static struct thread_info *
160find_thread_id PARAMS ((int num));
25286543 161
9ee59844
JM
162static void
163info_threads_command PARAMS ((char *, int));
b607efe7 164
9ee59844
JM
165static void
166restore_current_thread PARAMS ((int));
b607efe7 167
9ee59844
JM
168static void
169thread_apply_all_command PARAMS ((char *, int));
b607efe7 170
9ee59844
JM
171static void
172thread_apply_command PARAMS ((char *, int));
b607efe7 173
879c0417 174static void info_threads_command PARAMS ((char *, int));
de43d7d0 175
879c0417
JM
176static void restore_current_thread PARAMS ((int));
177
178static void thread_apply_all_command PARAMS ((char *, int));
179
180static void thread_apply_command PARAMS ((char *, int));
181
182static int thread_alive PARAMS ((struct thread_info *));
87feff9d 183
25286543
SG
184void
185init_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
202void
203add_thread (pid)
204 int pid;
205{
206 struct thread_info *tp;
207
3082244d 208 tp = (struct thread_info *) xmalloc (sizeof (struct thread_info));
25286543
SG
209
210 tp->pid = pid;
211 tp->num = ++highest_thread_num;
88a294b1
JL
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;
65b07ddc
DT
223 tp->stepping_through_solib_after_catch = 0;
224 tp->stepping_through_solib_catchpoints = NULL;
225 tp->stepping_through_sigtramp = 0;
25286543
SG
226 tp->next = thread_list;
227 thread_list = tp;
228}
229
3780c337
MS
230void
231delete_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
25286543
SG
255static struct thread_info *
256find_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
de43d7d0
SG
268int
269valid_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
281int
282pid_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
c889a1eb
MS
294int
295thread_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
25286543
SG
305int
306in_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
88a294b1
JL
318/* Load infrun state for the thread PID. */
319
320void 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,
65b07ddc 324 handling_longjmp, another_trap,
9bff382d
MS
325 stepping_through_solib_after_catch,
326 stepping_through_solib_catchpoints,
327 stepping_through_sigtramp)
88a294b1
JL
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;
65b07ddc
DT
340 int * stepping_through_solib_after_catch;
341 bpstat * stepping_through_solib_catchpoints;
342 int * stepping_through_sigtramp;
88a294b1
JL
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;
65b07ddc
DT
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;
88a294b1
JL
366}
367
368/* Save infrun state for the thread PID. */
369
370void 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,
65b07ddc 374 handling_longjmp, another_trap,
9bff382d
MS
375 stepping_through_solib_after_catch,
376 stepping_through_solib_catchpoints,
377 stepping_through_sigtramp)
88a294b1
JL
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;
65b07ddc
DT
390 int stepping_through_solib_after_catch;
391 bpstat stepping_through_solib_catchpoints;
392 int stepping_through_sigtramp;
88a294b1
JL
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;
65b07ddc
DT
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;
88a294b1
JL
416}
417
2847920a
MS
418/* Return true if TP is an active thread. */
419static int
420thread_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
25286543
SG
433static void
434prune_threads ()
435{
2847920a 436 struct thread_info *tp, *tpprev, *next;
25286543
SG
437
438 tpprev = 0;
2847920a
MS
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 }
25286543
SG
453}
454
65b07ddc
DT
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 */
25286543
SG
461
462static void
463info_threads_command (arg, from_tty)
464 char *arg;
465 int from_tty;
466{
467 struct thread_info *tp;
b53a1514 468 int current_pid;
9bff382d 469 struct frame_info *cur_frame;
65b07ddc
DT
470 int saved_frame_level = selected_frame_level;
471 int counter;
25286543 472
4cc1b3f7
JK
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
2847920a 477 prune_threads ();
02227894
DT
478#if defined(FIND_NEW_THREADS)
479 FIND_NEW_THREADS ();
480#endif
b53a1514 481 current_pid = inferior_pid;
25286543
SG
482 for (tp = thread_list; tp; tp = tp->next)
483 {
25286543
SG
484 if (tp->pid == current_pid)
485 printf_filtered ("* ");
486 else
487 printf_filtered (" ");
488
65b07ddc
DT
489#ifdef HPUXHPPA
490 printf_filtered ("%d %s ", tp->num, target_tid_to_str (tp->pid));
491#else
25286543 492 printf_filtered ("%d %s ", tp->num, target_pid_to_str (tp->pid));
65b07ddc 493#endif
c889a1eb 494 switch_to_thread (tp->pid);
3780c337 495 if (selected_frame)
65b07ddc 496 print_only_stack_frame (selected_frame, -1, 0);
3780c337
MS
497 else
498 printf_filtered ("[No stack.]\n");
25286543
SG
499 }
500
c889a1eb 501 switch_to_thread (current_pid);
65b07ddc
DT
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);
9bff382d
MS
511 if (counter != 0)
512 {
65b07ddc
DT
513 /* Ooops, can't restore, tell user where we are. */
514 warning ("Couldn't restore frame in current thread, at frame 0");
515 print_stack_frame (selected_frame, -1, 0);
9bff382d
MS
516 }
517 else
518 {
65b07ddc 519 select_frame(cur_frame, saved_frame_level);
9bff382d 520 }
65b07ddc
DT
521
522 /* re-show current frame. */
523 show_stack_frame(cur_frame);
25286543
SG
524}
525
526/* Switch from one thread to another. */
527
3082244d 528static void
c889a1eb 529switch_to_thread (pid)
25286543
SG
530 int pid;
531{
532 if (pid == inferior_pid)
533 return;
534
535 inferior_pid = pid;
25286543
SG
536 flush_cached_frames ();
537 registers_changed ();
538 stop_pc = read_pc();
25286543
SG
539 select_frame (get_current_frame (), 0);
540}
541
5090e82c
SG
542static void
543restore_current_thread (pid)
544 int pid;
545{
9bff382d
MS
546 if (pid != inferior_pid)
547 {
548 switch_to_thread (pid);
549 print_stack_frame( get_current_frame(), 0, -1);
550 }
5090e82c
SG
551}
552
553/* Apply a GDB command to a list of threads. List syntax is a whitespace
554 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
555 of two numbers seperated by a hyphen. Examples:
556
557 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
558 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
559 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
560*/
561
562static void
563thread_apply_all_command (cmd, from_tty)
564 char *cmd;
565 int from_tty;
566{
567 struct thread_info *tp;
568 struct cleanup *old_chain;
569
570 if (cmd == NULL || *cmd == '\000')
571 error ("Please specify a command following the thread ID list");
572
ad3b8c4a 573 old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
9bff382d 574 (void *) inferior_pid);
5090e82c
SG
575
576 for (tp = thread_list; tp; tp = tp->next)
2847920a
MS
577 if (thread_alive (tp))
578 {
579 switch_to_thread (tp->pid);
65b07ddc 580#ifdef HPUXHPPA
9bff382d
MS
581 printf_filtered ("\nThread %d (%s):\n",
582 tp->num,
583 target_tid_to_str (inferior_pid));
65b07ddc 584#else
2847920a
MS
585 printf_filtered ("\nThread %d (%s):\n", tp->num,
586 target_pid_to_str (inferior_pid));
65b07ddc 587#endif
2847920a
MS
588 execute_command (cmd, from_tty);
589 }
5090e82c
SG
590}
591
592static void
593thread_apply_command (tidlist, from_tty)
594 char *tidlist;
595 int from_tty;
596{
597 char *cmd;
598 char *p;
599 struct cleanup *old_chain;
600
601 if (tidlist == NULL || *tidlist == '\000')
602 error ("Please specify a thread ID list");
603
604 for (cmd = tidlist; *cmd != '\000' && !isalpha(*cmd); cmd++);
605
606 if (*cmd == '\000')
607 error ("Please specify a command following the thread ID list");
608
ad3b8c4a 609 old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
9bff382d 610 (void *) inferior_pid);
5090e82c
SG
611
612 while (tidlist < cmd)
613 {
614 struct thread_info *tp;
615 int start, end;
616
617 start = strtol (tidlist, &p, 10);
618 if (p == tidlist)
619 error ("Error parsing %s", tidlist);
620 tidlist = p;
621
622 while (*tidlist == ' ' || *tidlist == '\t')
623 tidlist++;
624
625 if (*tidlist == '-') /* Got a range of IDs? */
626 {
627 tidlist++; /* Skip the - */
628 end = strtol (tidlist, &p, 10);
629 if (p == tidlist)
630 error ("Error parsing %s", tidlist);
631 tidlist = p;
632
633 while (*tidlist == ' ' || *tidlist == '\t')
634 tidlist++;
635 }
636 else
637 end = start;
638
639 for (; start <= end; start++)
640 {
641 tp = find_thread_id (start);
642
643 if (!tp)
2847920a
MS
644 warning ("Unknown thread %d.", start);
645 else if (!thread_alive (tp))
646 warning ("Thread %d has terminated.", start);
647 else
5090e82c 648 {
2847920a 649 switch_to_thread (tp->pid);
65b07ddc 650#ifdef HPUXHPPA
9bff382d
MS
651 printf_filtered ("\nThread %d (%s):\n", tp->num,
652 target_tid_to_str (inferior_pid));
65b07ddc 653#else
2847920a
MS
654 printf_filtered ("\nThread %d (%s):\n", tp->num,
655 target_pid_to_str (inferior_pid));
65b07ddc 656#endif
2847920a 657 execute_command (cmd, from_tty);
5090e82c 658 }
5090e82c
SG
659 }
660 }
661}
662
663/* Switch to the specified thread. Will dispatch off to thread_apply_command
664 if prefix of arg is `apply'. */
665
25286543
SG
666static void
667thread_command (tidstr, from_tty)
668 char *tidstr;
669 int from_tty;
670{
671 int num;
672 struct thread_info *tp;
673
674 if (!tidstr)
65b07ddc
DT
675 {
676 /* Don't generate an error, just say which thread is current. */
677 if (target_has_stack)
678 printf_filtered ("[Current thread is %d (%s)]\n",
679 pid_to_thread_id(inferior_pid),
680#if defined(HPUXHPPA)
681 target_tid_to_str(inferior_pid)
682#else
683 target_pid_to_str(inferior_pid)
684#endif
685 );
686 else
687 error ("No stack.");
688 return;
689 }
25286543
SG
690 num = atoi (tidstr);
691
692 tp = find_thread_id (num);
693
694 if (!tp)
695 error ("Thread ID %d not known. Use the \"info threads\" command to\n\
696see the IDs of currently known threads.", num);
2847920a
MS
697
698 if (!thread_alive (tp))
699 error ("Thread ID %d has terminated.\n", num);
25286543 700
c889a1eb 701 switch_to_thread (tp->pid);
65b07ddc 702
4ff5d55a
MH
703 if (context_hook)
704 context_hook (num);
65b07ddc
DT
705
706 printf_filtered ("[Switching to thread %d (%s)]\n",
707 pid_to_thread_id (inferior_pid),
708#if defined(HPUXHPPA)
709 target_tid_to_str (inferior_pid)
710#else
711 target_pid_to_str (inferior_pid)
712#endif
713 );
25286543
SG
714 print_stack_frame (selected_frame, selected_frame_level, 1);
715}
716
c889a1eb
MS
717/* Commands with a prefix of `thread'. */
718struct cmd_list_element *thread_cmd_list = NULL;
719
25286543
SG
720void
721_initialize_thread ()
722{
5090e82c
SG
723 static struct cmd_list_element *thread_apply_list = NULL;
724 extern struct cmd_list_element *cmdlist;
725
25286543
SG
726 add_info ("threads", info_threads_command,
727 "IDs of currently known threads.");
5090e82c
SG
728
729 add_prefix_cmd ("thread", class_run, thread_command,
730 "Use this command to switch between threads.\n\
731The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1,
732 &cmdlist);
733
734 add_prefix_cmd ("apply", class_run, thread_apply_command,
735 "Apply a command to a list of threads.",
736 &thread_apply_list, "apply ", 1, &thread_cmd_list);
737
738 add_cmd ("all", class_run, thread_apply_all_command,
739 "Apply a command to all threads.",
740 &thread_apply_list);
741
65b07ddc
DT
742 if (!xdb_commands)
743 add_com_alias ("t", "thread", class_run, 1);
25286543 744}
This page took 0.346592 seconds and 4 git commands to generate.