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,
22 Boston, MA 02111-1307, USA. */
31 #include "gdbthread.h"
36 #include <sys/types.h>
39 /*#include "lynxos-core.h" */
43 struct thread_info *next;
44 int pid; /* Actual process id */
45 int num; /* Convenient handle */
46 CORE_ADDR prev_pc; /* State from wait_for_inferior */
47 CORE_ADDR prev_func_start;
49 struct breakpoint *step_resume_breakpoint;
50 struct breakpoint *through_sigtramp_breakpoint;
51 CORE_ADDR step_range_start;
52 CORE_ADDR step_range_end;
53 CORE_ADDR step_frame_address;
58 /* This is set TRUE when a catchpoint of a shared library event
59 triggers. Since we don't wish to leave the inferior in the
60 solib hook when we report the event, we step the inferior
61 back to user code before stopping and reporting the event.
63 int stepping_through_solib_after_catch;
65 /* When stepping_through_solib_after_catch is TRUE, this is a
66 list of the catchpoints that should be reported as triggering
67 when we finally do stop stepping.
69 bpstat stepping_through_solib_catchpoints;
71 /* This is set to TRUE when this thread is in a signal handler
72 trampoline and we're single-stepping through it */
73 int stepping_through_sigtramp;
77 /* Prototypes for exported functions. */
79 void _initialize_thread PARAMS ((void));
81 /* Prototypes for local functions. */
83 static struct thread_info *thread_list = NULL;
84 static int highest_thread_num;
86 static struct thread_info *find_thread_id PARAMS ((int num));
88 static void thread_command PARAMS ((char *tidstr, int from_tty));
89 static void thread_apply_all_command PARAMS ((char *, int));
90 static int thread_alive PARAMS ((struct thread_info *));
91 static void info_threads_command PARAMS ((char *, int));
92 static void thread_apply_command PARAMS ((char *, int));
93 static void restore_current_thread PARAMS ((int));
94 static void switch_to_thread PARAMS ((int pid));
95 static void prune_threads PARAMS ((void));
100 struct thread_info *tp, *tpnext;
105 for (tp = thread_list; tp; tp = tpnext)
112 highest_thread_num = 0;
119 struct thread_info *tp;
121 tp = (struct thread_info *) xmalloc (sizeof (struct thread_info));
124 tp->num = ++highest_thread_num;
126 tp->prev_func_start = 0;
127 tp->prev_func_name = NULL;
128 tp->step_range_start = 0;
129 tp->step_range_end = 0;
130 tp->step_frame_address = 0;
131 tp->step_resume_breakpoint = 0;
132 tp->through_sigtramp_breakpoint = 0;
133 tp->handling_longjmp = 0;
134 tp->trap_expected = 0;
135 tp->another_trap = 0;
136 tp->stepping_through_solib_after_catch = 0;
137 tp->stepping_through_solib_catchpoints = NULL;
138 tp->stepping_through_sigtramp = 0;
139 tp->next = thread_list;
147 struct thread_info *tp, *tpprev;
151 for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
159 tpprev->next = tp->next;
161 thread_list = tp->next;
168 static struct thread_info *
172 struct thread_info *tp;
174 for (tp = thread_list; tp; tp = tp->next)
182 valid_thread_id (num)
185 struct thread_info *tp;
187 for (tp = thread_list; tp; tp = tp->next)
195 pid_to_thread_id (pid)
198 struct thread_info *tp;
200 for (tp = thread_list; tp; tp = tp->next)
208 thread_id_to_pid (num)
211 struct thread_info *thread = find_thread_id (num);
222 struct thread_info *tp;
224 for (tp = thread_list; tp; tp = tp->next)
228 return 0; /* Never heard of 'im */
231 /* Load infrun state for the thread PID. */
234 load_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
235 trap_expected, step_resume_breakpoint,
236 through_sigtramp_breakpoint, step_range_start,
237 step_range_end, step_frame_address,
238 handling_longjmp, another_trap,
239 stepping_through_solib_after_catch,
240 stepping_through_solib_catchpoints,
241 stepping_through_sigtramp)
244 CORE_ADDR *prev_func_start;
245 char **prev_func_name;
247 struct breakpoint **step_resume_breakpoint;
248 struct breakpoint **through_sigtramp_breakpoint;
249 CORE_ADDR *step_range_start;
250 CORE_ADDR *step_range_end;
251 CORE_ADDR *step_frame_address;
252 int *handling_longjmp;
254 int *stepping_through_solib_after_catch;
255 bpstat *stepping_through_solib_catchpoints;
256 int *stepping_through_sigtramp;
258 struct thread_info *tp;
260 /* If we can't find the thread, then we're debugging a single threaded
261 process. No need to do anything in that case. */
262 tp = find_thread_id (pid_to_thread_id (pid));
266 *prev_pc = tp->prev_pc;
267 *prev_func_start = tp->prev_func_start;
268 *prev_func_name = tp->prev_func_name;
269 *step_resume_breakpoint = tp->step_resume_breakpoint;
270 *step_range_start = tp->step_range_start;
271 *step_range_end = tp->step_range_end;
272 *step_frame_address = tp->step_frame_address;
273 *through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint;
274 *handling_longjmp = tp->handling_longjmp;
275 *trap_expected = tp->trap_expected;
276 *another_trap = tp->another_trap;
277 *stepping_through_solib_after_catch = tp->stepping_through_solib_after_catch;
278 *stepping_through_solib_catchpoints = tp->stepping_through_solib_catchpoints;
279 *stepping_through_sigtramp = tp->stepping_through_sigtramp;
282 /* Save infrun state for the thread PID. */
285 save_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
286 trap_expected, step_resume_breakpoint,
287 through_sigtramp_breakpoint, step_range_start,
288 step_range_end, step_frame_address,
289 handling_longjmp, another_trap,
290 stepping_through_solib_after_catch,
291 stepping_through_solib_catchpoints,
292 stepping_through_sigtramp)
295 CORE_ADDR prev_func_start;
296 char *prev_func_name;
298 struct breakpoint *step_resume_breakpoint;
299 struct breakpoint *through_sigtramp_breakpoint;
300 CORE_ADDR step_range_start;
301 CORE_ADDR step_range_end;
302 CORE_ADDR step_frame_address;
303 int handling_longjmp;
305 int stepping_through_solib_after_catch;
306 bpstat stepping_through_solib_catchpoints;
307 int stepping_through_sigtramp;
309 struct thread_info *tp;
311 /* If we can't find the thread, then we're debugging a single-threaded
312 process. Nothing to do in that case. */
313 tp = find_thread_id (pid_to_thread_id (pid));
317 tp->prev_pc = prev_pc;
318 tp->prev_func_start = prev_func_start;
319 tp->prev_func_name = prev_func_name;
320 tp->step_resume_breakpoint = step_resume_breakpoint;
321 tp->step_range_start = step_range_start;
322 tp->step_range_end = step_range_end;
323 tp->step_frame_address = step_frame_address;
324 tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint;
325 tp->handling_longjmp = handling_longjmp;
326 tp->trap_expected = trap_expected;
327 tp->another_trap = another_trap;
328 tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
329 tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
330 tp->stepping_through_sigtramp = stepping_through_sigtramp;
333 /* Return true if TP is an active thread. */
336 struct thread_info *tp;
340 if (!target_thread_alive (tp->pid))
342 tp->pid = -1; /* Mark it as dead */
351 struct thread_info *tp, *tpprev, *next;
354 for (tp = thread_list; tp; tp = next)
357 if (!thread_alive (tp))
370 /* Print information about currently known threads
372 * Note: this has the drawback that it _really_ switches
373 * threads, which frees the frame cache. A no-side
374 * effects info-threads command would be nicer.
378 info_threads_command (arg, from_tty)
382 struct thread_info *tp;
384 struct frame_info *cur_frame;
385 int saved_frame_level = selected_frame_level;
388 /* Avoid coredumps which would happen if we tried to access a NULL
390 if (!target_has_stack)
394 target_find_new_threads ();
395 current_pid = inferior_pid;
396 for (tp = thread_list; tp; tp = tp->next)
398 if (tp->pid == current_pid)
399 printf_filtered ("* ");
401 printf_filtered (" ");
404 printf_filtered ("%d %s ", tp->num, target_tid_to_str (tp->pid));
406 printf_filtered ("%d %s ", tp->num, target_pid_to_str (tp->pid));
408 switch_to_thread (tp->pid);
410 print_only_stack_frame (selected_frame, -1, 0);
412 printf_filtered ("[No stack.]\n");
415 switch_to_thread (current_pid);
417 /* Code below copied from "up_silently_base" in "stack.c".
418 * It restores the frame set by the user before the "info threads"
419 * command. We have finished the info-threads display by switching
420 * back to the current thread. That switch has put us at the top
421 * of the stack (leaf frame).
423 counter = saved_frame_level;
424 cur_frame = find_relative_frame (selected_frame, &counter);
427 /* Ooops, can't restore, tell user where we are. */
428 warning ("Couldn't restore frame in current thread, at frame 0");
429 print_stack_frame (selected_frame, -1, 0);
433 select_frame (cur_frame, saved_frame_level);
436 /* re-show current frame. */
437 show_stack_frame (cur_frame);
440 /* Switch from one thread to another. */
443 switch_to_thread (pid)
446 if (pid == inferior_pid)
450 flush_cached_frames ();
451 registers_changed ();
452 stop_pc = read_pc ();
453 select_frame (get_current_frame (), 0);
457 restore_current_thread (pid)
460 if (pid != inferior_pid)
462 switch_to_thread (pid);
463 print_stack_frame (get_current_frame (), 0, -1);
467 /* Apply a GDB command to a list of threads. List syntax is a whitespace
468 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
469 of two numbers seperated by a hyphen. Examples:
471 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
472 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
473 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
477 thread_apply_all_command (cmd, from_tty)
481 struct thread_info *tp;
482 struct cleanup *old_chain;
484 if (cmd == NULL || *cmd == '\000')
485 error ("Please specify a command following the thread ID list");
487 old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
488 (void *) inferior_pid);
490 for (tp = thread_list; tp; tp = tp->next)
491 if (thread_alive (tp))
493 switch_to_thread (tp->pid);
495 printf_filtered ("\nThread %d (%s):\n",
497 target_tid_to_str (inferior_pid));
499 printf_filtered ("\nThread %d (%s):\n", tp->num,
500 target_pid_to_str (inferior_pid));
502 execute_command (cmd, from_tty);
507 thread_apply_command (tidlist, from_tty)
513 struct cleanup *old_chain;
515 if (tidlist == NULL || *tidlist == '\000')
516 error ("Please specify a thread ID list");
518 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
521 error ("Please specify a command following the thread ID list");
523 old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
524 (void *) inferior_pid);
526 while (tidlist < cmd)
528 struct thread_info *tp;
531 start = strtol (tidlist, &p, 10);
533 error ("Error parsing %s", tidlist);
536 while (*tidlist == ' ' || *tidlist == '\t')
539 if (*tidlist == '-') /* Got a range of IDs? */
541 tidlist++; /* Skip the - */
542 end = strtol (tidlist, &p, 10);
544 error ("Error parsing %s", tidlist);
547 while (*tidlist == ' ' || *tidlist == '\t')
553 for (; start <= end; start++)
555 tp = find_thread_id (start);
558 warning ("Unknown thread %d.", start);
559 else if (!thread_alive (tp))
560 warning ("Thread %d has terminated.", start);
563 switch_to_thread (tp->pid);
565 printf_filtered ("\nThread %d (%s):\n", tp->num,
566 target_tid_to_str (inferior_pid));
568 printf_filtered ("\nThread %d (%s):\n", tp->num,
569 target_pid_to_str (inferior_pid));
571 execute_command (cmd, from_tty);
577 /* Switch to the specified thread. Will dispatch off to thread_apply_command
578 if prefix of arg is `apply'. */
581 thread_command (tidstr, from_tty)
586 struct thread_info *tp;
590 /* Don't generate an error, just say which thread is current. */
591 if (target_has_stack)
592 printf_filtered ("[Current thread is %d (%s)]\n",
593 pid_to_thread_id (inferior_pid),
594 #if defined(HPUXHPPA)
595 target_tid_to_str (inferior_pid)
597 target_pid_to_str (inferior_pid)
606 tp = find_thread_id (num);
609 error ("Thread ID %d not known. Use the \"info threads\" command to\n\
610 see the IDs of currently known threads.", num);
612 if (!thread_alive (tp))
613 error ("Thread ID %d has terminated.\n", num);
615 switch_to_thread (tp->pid);
620 printf_filtered ("[Switching to thread %d (%s)]\n",
621 pid_to_thread_id (inferior_pid),
622 #if defined(HPUXHPPA)
623 target_tid_to_str (inferior_pid)
625 target_pid_to_str (inferior_pid)
628 print_stack_frame (selected_frame, selected_frame_level, 1);
631 /* Commands with a prefix of `thread'. */
632 struct cmd_list_element *thread_cmd_list = NULL;
635 _initialize_thread ()
637 static struct cmd_list_element *thread_apply_list = NULL;
639 add_info ("threads", info_threads_command,
640 "IDs of currently known threads.");
642 add_prefix_cmd ("thread", class_run, thread_command,
643 "Use this command to switch between threads.\n\
644 The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1,
647 add_prefix_cmd ("apply", class_run, thread_apply_command,
648 "Apply a command to a list of threads.",
649 &thread_apply_list, "apply ", 1, &thread_cmd_list);
651 add_cmd ("all", class_run, thread_apply_all_command,
652 "Apply a command to all threads.",
656 add_com_alias ("t", "thread", class_run, 1);