1 /* Multi-process/thread control for GDB, the GNU debugger.
2 Copyright 1986, 1987, 1988, 1993, 1998
4 Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
5 Free Software Foundation, Inc.
7 This file is part of GDB.
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.
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.
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. */
30 #include "gdbthread.h"
35 #include <sys/types.h>
38 /*#include "lynxos-core.h"*/
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
;
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
;
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.
62 int stepping_through_solib_after_catch
;
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.
68 bpstat stepping_through_solib_catchpoints
;
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
;
76 static struct target_thread_vector
*target_thread_functions
;
79 target_find_new_threads ()
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 */
90 target_get_thread_info
PARAMS ((
92 int selection
, /* FIXME: Selection */
93 struct gdb_ext_thread_info
* info
));
96 target_get_thread_info (ref
, selection
, info
)
100 /* FIXME: Selection */
101 struct gdb_ext_thread_info
*info
;
105 if (target_thread_functions
106 && target_thread_functions
->get_thread_info
)
107 retval
= (*(target_thread_functions
->get_thread_info
)) (ref
, selection
, info
);
112 /* It is possible that these bind and unbinf functions implement a
113 stack the interface allows it, but its not implemented that way
118 bind_target_thread_vector (vec
)
119 struct target_thread_vector
*vec
;
121 target_thread_functions
= vec
;
124 /* Prototypes for exported functions. */
126 struct target_thread_vector
*
127 unbind_target_thread_vector ()
129 struct target_thread_vector
*retval
;
130 retval
= target_thread_functions
;
131 target_thread_functions
= 0;
133 } /* unbind_target_thread-vector */
135 void _initialize_thread
PARAMS ((void));
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
144 #if !defined(FIND_NEW_THREADS)
145 #define FIND_NEW_THREADS target_find_new_threads
148 static struct thread_info
*thread_list
= NULL
;
149 static int highest_thread_num
;
152 thread_command
PARAMS ((char * tidstr
, int from_tty
));
154 prune_threads
PARAMS ((void));
157 switch_to_thread
PARAMS ((int pid
));
159 static struct thread_info
*
160 find_thread_id
PARAMS ((int num
));
163 info_threads_command
PARAMS ((char *, int));
166 restore_current_thread
PARAMS ((int));
169 thread_apply_all_command
PARAMS ((char *, int));
172 thread_apply_command
PARAMS ((char *, int));
174 static void info_threads_command
PARAMS ((char *, int));
176 static void restore_current_thread
PARAMS ((int));
178 static void thread_apply_all_command
PARAMS ((char *, int));
180 static void thread_apply_command
PARAMS ((char *, int));
182 static int thread_alive
PARAMS ((struct thread_info
*));
187 struct thread_info
*tp
, *tpnext
;
192 for (tp
= thread_list
; tp
; tp
= tpnext
)
199 highest_thread_num
= 0;
206 struct thread_info
*tp
;
208 tp
= (struct thread_info
*) xmalloc (sizeof (struct thread_info
));
211 tp
->num
= ++highest_thread_num
;
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
;
234 struct thread_info
*tp
, *tpprev
;
238 for (tp
= thread_list
; tp
; tpprev
= tp
, tp
= tp
->next
)
246 tpprev
->next
= tp
->next
;
248 thread_list
= tp
->next
;
255 static struct thread_info
*
259 struct thread_info
*tp
;
261 for (tp
= thread_list
; tp
; tp
= tp
->next
)
269 valid_thread_id (num
)
272 struct thread_info
*tp
;
274 for (tp
= thread_list
; tp
; tp
= tp
->next
)
282 pid_to_thread_id (pid
)
285 struct thread_info
*tp
;
287 for (tp
= thread_list
; tp
; tp
= tp
->next
)
295 thread_id_to_pid (num
)
298 struct thread_info
*thread
= find_thread_id (num
);
309 struct thread_info
*tp
;
311 for (tp
= thread_list
; tp
; tp
= tp
->next
)
315 return 0; /* Never heard of 'im */
318 /* Load infrun state for the thread PID. */
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
)
330 CORE_ADDR
*prev_func_start
;
331 char **prev_func_name
;
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
;
340 int * stepping_through_solib_after_catch
;
341 bpstat
* stepping_through_solib_catchpoints
;
342 int * stepping_through_sigtramp
;
344 struct thread_info
*tp
;
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
));
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
;
368 /* Save infrun state for the thread PID. */
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
)
380 CORE_ADDR prev_func_start
;
381 char *prev_func_name
;
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
;
390 int stepping_through_solib_after_catch
;
391 bpstat stepping_through_solib_catchpoints
;
392 int stepping_through_sigtramp
;
394 struct thread_info
*tp
;
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
));
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
;
418 /* Return true if TP is an active thread. */
421 struct thread_info
*tp
;
425 if (! target_thread_alive (tp
->pid
))
427 tp
->pid
= -1; /* Mark it as dead */
436 struct thread_info
*tp
, *tpprev
, *next
;
439 for (tp
= thread_list
; tp
; tp
= next
)
442 if (!thread_alive (tp
))
455 /* Print information about currently known threads
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.
463 info_threads_command (arg
, from_tty
)
467 struct thread_info
*tp
;
469 struct frame_info
*cur_frame
;
470 int saved_frame_level
= selected_frame_level
;
473 /* Avoid coredumps which would happen if we tried to access a NULL
475 if (!target_has_stack
) error ("No stack.");
478 #if defined(FIND_NEW_THREADS)
481 current_pid
= inferior_pid
;
482 for (tp
= thread_list
; tp
; tp
= tp
->next
)
484 if (tp
->pid
== current_pid
)
485 printf_filtered ("* ");
487 printf_filtered (" ");
490 printf_filtered ("%d %s ", tp
->num
, target_tid_to_str (tp
->pid
));
492 printf_filtered ("%d %s ", tp
->num
, target_pid_to_str (tp
->pid
));
494 switch_to_thread (tp
->pid
);
496 print_only_stack_frame (selected_frame
, -1, 0);
498 printf_filtered ("[No stack.]\n");
501 switch_to_thread (current_pid
);
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).
509 counter
= saved_frame_level
;
510 cur_frame
= find_relative_frame(selected_frame
, &counter
);
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);
519 select_frame(cur_frame
, saved_frame_level
);
522 /* re-show current frame. */
523 show_stack_frame(cur_frame
);
526 /* Switch from one thread to another. */
529 switch_to_thread (pid
)
532 if (pid
== inferior_pid
)
536 flush_cached_frames ();
537 registers_changed ();
539 select_frame (get_current_frame (), 0);
543 restore_current_thread (pid
)
546 if (pid
!= inferior_pid
)
548 switch_to_thread (pid
);
549 print_stack_frame( get_current_frame(), 0, -1);
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:
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
563 thread_apply_all_command (cmd
, from_tty
)
567 struct thread_info
*tp
;
568 struct cleanup
*old_chain
;
570 if (cmd
== NULL
|| *cmd
== '\000')
571 error ("Please specify a command following the thread ID list");
573 old_chain
= make_cleanup ((make_cleanup_func
) restore_current_thread
,
574 (void *) inferior_pid
);
576 for (tp
= thread_list
; tp
; tp
= tp
->next
)
577 if (thread_alive (tp
))
579 switch_to_thread (tp
->pid
);
581 printf_filtered ("\nThread %d (%s):\n",
583 target_tid_to_str (inferior_pid
));
585 printf_filtered ("\nThread %d (%s):\n", tp
->num
,
586 target_pid_to_str (inferior_pid
));
588 execute_command (cmd
, from_tty
);
593 thread_apply_command (tidlist
, from_tty
)
599 struct cleanup
*old_chain
;
601 if (tidlist
== NULL
|| *tidlist
== '\000')
602 error ("Please specify a thread ID list");
604 for (cmd
= tidlist
; *cmd
!= '\000' && !isalpha(*cmd
); cmd
++);
607 error ("Please specify a command following the thread ID list");
609 old_chain
= make_cleanup ((make_cleanup_func
) restore_current_thread
,
610 (void *) inferior_pid
);
612 while (tidlist
< cmd
)
614 struct thread_info
*tp
;
617 start
= strtol (tidlist
, &p
, 10);
619 error ("Error parsing %s", tidlist
);
622 while (*tidlist
== ' ' || *tidlist
== '\t')
625 if (*tidlist
== '-') /* Got a range of IDs? */
627 tidlist
++; /* Skip the - */
628 end
= strtol (tidlist
, &p
, 10);
630 error ("Error parsing %s", tidlist
);
633 while (*tidlist
== ' ' || *tidlist
== '\t')
639 for (; start
<= end
; start
++)
641 tp
= find_thread_id (start
);
644 warning ("Unknown thread %d.", start
);
645 else if (!thread_alive (tp
))
646 warning ("Thread %d has terminated.", start
);
649 switch_to_thread (tp
->pid
);
651 printf_filtered ("\nThread %d (%s):\n", tp
->num
,
652 target_tid_to_str (inferior_pid
));
654 printf_filtered ("\nThread %d (%s):\n", tp
->num
,
655 target_pid_to_str (inferior_pid
));
657 execute_command (cmd
, from_tty
);
663 /* Switch to the specified thread. Will dispatch off to thread_apply_command
664 if prefix of arg is `apply'. */
667 thread_command (tidstr
, from_tty
)
672 struct thread_info
*tp
;
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
)
683 target_pid_to_str(inferior_pid
)
692 tp
= find_thread_id (num
);
695 error ("Thread ID %d not known. Use the \"info threads\" command to\n\
696 see the IDs of currently known threads.", num
);
698 if (!thread_alive (tp
))
699 error ("Thread ID %d has terminated.\n", num
);
701 switch_to_thread (tp
->pid
);
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
)
711 target_pid_to_str (inferior_pid
)
714 print_stack_frame (selected_frame
, selected_frame_level
, 1);
717 /* Commands with a prefix of `thread'. */
718 struct cmd_list_element
*thread_cmd_list
= NULL
;
721 _initialize_thread ()
723 static struct cmd_list_element
*thread_apply_list
= NULL
;
724 extern struct cmd_list_element
*cmdlist
;
726 add_info ("threads", info_threads_command
,
727 "IDs of currently known threads.");
729 add_prefix_cmd ("thread", class_run
, thread_command
,
730 "Use this command to switch between threads.\n\
731 The new thread ID must be currently known.", &thread_cmd_list
, "thread ", 1,
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
);
738 add_cmd ("all", class_run
, thread_apply_all_command
,
739 "Apply a command to all threads.",
743 add_com_alias ("t", "thread", class_run
, 1);