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