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
;
163 /* NOTE: this will take care of any left-over step_resume breakpoints,
164 but not any user-specified thread-specific breakpoints. */
165 if (tp
->step_resume_breakpoint
)
166 delete_breakpoint (tp
->step_resume_breakpoint
);
173 static struct thread_info
*
177 struct thread_info
*tp
;
179 for (tp
= thread_list
; tp
; tp
= tp
->next
)
187 valid_thread_id (num
)
190 struct thread_info
*tp
;
192 for (tp
= thread_list
; tp
; tp
= tp
->next
)
200 pid_to_thread_id (pid
)
203 struct thread_info
*tp
;
205 for (tp
= thread_list
; tp
; tp
= tp
->next
)
213 thread_id_to_pid (num
)
216 struct thread_info
*thread
= find_thread_id (num
);
227 struct thread_info
*tp
;
229 for (tp
= thread_list
; tp
; tp
= tp
->next
)
233 return 0; /* Never heard of 'im */
236 /* Load infrun state for the thread PID. */
239 load_infrun_state (pid
, prev_pc
, prev_func_start
, prev_func_name
,
240 trap_expected
, step_resume_breakpoint
,
241 through_sigtramp_breakpoint
, step_range_start
,
242 step_range_end
, step_frame_address
,
243 handling_longjmp
, another_trap
,
244 stepping_through_solib_after_catch
,
245 stepping_through_solib_catchpoints
,
246 stepping_through_sigtramp
)
249 CORE_ADDR
*prev_func_start
;
250 char **prev_func_name
;
252 struct breakpoint
**step_resume_breakpoint
;
253 struct breakpoint
**through_sigtramp_breakpoint
;
254 CORE_ADDR
*step_range_start
;
255 CORE_ADDR
*step_range_end
;
256 CORE_ADDR
*step_frame_address
;
257 int *handling_longjmp
;
259 int *stepping_through_solib_after_catch
;
260 bpstat
*stepping_through_solib_catchpoints
;
261 int *stepping_through_sigtramp
;
263 struct thread_info
*tp
;
265 /* If we can't find the thread, then we're debugging a single threaded
266 process. No need to do anything in that case. */
267 tp
= find_thread_id (pid_to_thread_id (pid
));
271 *prev_pc
= tp
->prev_pc
;
272 *prev_func_start
= tp
->prev_func_start
;
273 *prev_func_name
= tp
->prev_func_name
;
274 *step_resume_breakpoint
= tp
->step_resume_breakpoint
;
275 *step_range_start
= tp
->step_range_start
;
276 *step_range_end
= tp
->step_range_end
;
277 *step_frame_address
= tp
->step_frame_address
;
278 *through_sigtramp_breakpoint
= tp
->through_sigtramp_breakpoint
;
279 *handling_longjmp
= tp
->handling_longjmp
;
280 *trap_expected
= tp
->trap_expected
;
281 *another_trap
= tp
->another_trap
;
282 *stepping_through_solib_after_catch
= tp
->stepping_through_solib_after_catch
;
283 *stepping_through_solib_catchpoints
= tp
->stepping_through_solib_catchpoints
;
284 *stepping_through_sigtramp
= tp
->stepping_through_sigtramp
;
287 /* Save infrun state for the thread PID. */
290 save_infrun_state (pid
, prev_pc
, prev_func_start
, prev_func_name
,
291 trap_expected
, step_resume_breakpoint
,
292 through_sigtramp_breakpoint
, step_range_start
,
293 step_range_end
, step_frame_address
,
294 handling_longjmp
, another_trap
,
295 stepping_through_solib_after_catch
,
296 stepping_through_solib_catchpoints
,
297 stepping_through_sigtramp
)
300 CORE_ADDR prev_func_start
;
301 char *prev_func_name
;
303 struct breakpoint
*step_resume_breakpoint
;
304 struct breakpoint
*through_sigtramp_breakpoint
;
305 CORE_ADDR step_range_start
;
306 CORE_ADDR step_range_end
;
307 CORE_ADDR step_frame_address
;
308 int handling_longjmp
;
310 int stepping_through_solib_after_catch
;
311 bpstat stepping_through_solib_catchpoints
;
312 int stepping_through_sigtramp
;
314 struct thread_info
*tp
;
316 /* If we can't find the thread, then we're debugging a single-threaded
317 process. Nothing to do in that case. */
318 tp
= find_thread_id (pid_to_thread_id (pid
));
322 tp
->prev_pc
= prev_pc
;
323 tp
->prev_func_start
= prev_func_start
;
324 tp
->prev_func_name
= prev_func_name
;
325 tp
->step_resume_breakpoint
= step_resume_breakpoint
;
326 tp
->step_range_start
= step_range_start
;
327 tp
->step_range_end
= step_range_end
;
328 tp
->step_frame_address
= step_frame_address
;
329 tp
->through_sigtramp_breakpoint
= through_sigtramp_breakpoint
;
330 tp
->handling_longjmp
= handling_longjmp
;
331 tp
->trap_expected
= trap_expected
;
332 tp
->another_trap
= another_trap
;
333 tp
->stepping_through_solib_after_catch
= stepping_through_solib_after_catch
;
334 tp
->stepping_through_solib_catchpoints
= stepping_through_solib_catchpoints
;
335 tp
->stepping_through_sigtramp
= stepping_through_sigtramp
;
338 /* Return true if TP is an active thread. */
341 struct thread_info
*tp
;
345 if (!target_thread_alive (tp
->pid
))
347 tp
->pid
= -1; /* Mark it as dead */
356 struct thread_info
*tp
, *next
;
358 for (tp
= thread_list
; tp
; tp
= next
)
361 if (!thread_alive (tp
))
362 delete_thread (tp
->pid
);
366 /* Print information about currently known threads
368 * Note: this has the drawback that it _really_ switches
369 * threads, which frees the frame cache. A no-side
370 * effects info-threads command would be nicer.
374 info_threads_command (arg
, from_tty
)
378 struct thread_info
*tp
;
380 struct frame_info
*cur_frame
;
381 int saved_frame_level
= selected_frame_level
;
384 /* Avoid coredumps which would happen if we tried to access a NULL
386 if (!target_has_stack
)
390 target_find_new_threads ();
391 current_pid
= inferior_pid
;
392 for (tp
= thread_list
; tp
; tp
= tp
->next
)
394 if (tp
->pid
== current_pid
)
395 printf_filtered ("* ");
397 printf_filtered (" ");
400 printf_filtered ("%d %s ", tp
->num
, target_tid_to_str (tp
->pid
));
402 printf_filtered ("%d %s ", tp
->num
, target_pid_to_str (tp
->pid
));
404 switch_to_thread (tp
->pid
);
406 print_only_stack_frame (selected_frame
, -1, 0);
408 printf_filtered ("[No stack.]\n");
411 switch_to_thread (current_pid
);
413 /* Code below copied from "up_silently_base" in "stack.c".
414 * It restores the frame set by the user before the "info threads"
415 * command. We have finished the info-threads display by switching
416 * back to the current thread. That switch has put us at the top
417 * of the stack (leaf frame).
419 counter
= saved_frame_level
;
420 cur_frame
= find_relative_frame (selected_frame
, &counter
);
423 /* Ooops, can't restore, tell user where we are. */
424 warning ("Couldn't restore frame in current thread, at frame 0");
425 print_stack_frame (selected_frame
, -1, 0);
429 select_frame (cur_frame
, saved_frame_level
);
432 /* re-show current frame. */
433 show_stack_frame (cur_frame
);
436 /* Switch from one thread to another. */
439 switch_to_thread (pid
)
442 if (pid
== inferior_pid
)
446 flush_cached_frames ();
447 registers_changed ();
448 stop_pc
= read_pc ();
449 select_frame (get_current_frame (), 0);
453 restore_current_thread (pid
)
456 if (pid
!= inferior_pid
)
458 switch_to_thread (pid
);
459 print_stack_frame (get_current_frame (), 0, -1);
463 /* Apply a GDB command to a list of threads. List syntax is a whitespace
464 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist
465 of two numbers seperated by a hyphen. Examples:
467 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
468 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
469 thread apply all p x/i $pc Apply x/i $pc cmd to all threads
473 thread_apply_all_command (cmd
, from_tty
)
477 struct thread_info
*tp
;
478 struct cleanup
*old_chain
;
480 if (cmd
== NULL
|| *cmd
== '\000')
481 error ("Please specify a command following the thread ID list");
483 old_chain
= make_cleanup ((make_cleanup_func
) restore_current_thread
,
484 (void *) inferior_pid
);
486 for (tp
= thread_list
; tp
; tp
= tp
->next
)
487 if (thread_alive (tp
))
489 switch_to_thread (tp
->pid
);
491 printf_filtered ("\nThread %d (%s):\n",
493 target_tid_to_str (inferior_pid
));
495 printf_filtered ("\nThread %d (%s):\n", tp
->num
,
496 target_pid_to_str (inferior_pid
));
498 execute_command (cmd
, from_tty
);
503 thread_apply_command (tidlist
, from_tty
)
509 struct cleanup
*old_chain
;
511 if (tidlist
== NULL
|| *tidlist
== '\000')
512 error ("Please specify a thread ID list");
514 for (cmd
= tidlist
; *cmd
!= '\000' && !isalpha (*cmd
); cmd
++);
517 error ("Please specify a command following the thread ID list");
519 old_chain
= make_cleanup ((make_cleanup_func
) restore_current_thread
,
520 (void *) inferior_pid
);
522 while (tidlist
< cmd
)
524 struct thread_info
*tp
;
527 start
= strtol (tidlist
, &p
, 10);
529 error ("Error parsing %s", tidlist
);
532 while (*tidlist
== ' ' || *tidlist
== '\t')
535 if (*tidlist
== '-') /* Got a range of IDs? */
537 tidlist
++; /* Skip the - */
538 end
= strtol (tidlist
, &p
, 10);
540 error ("Error parsing %s", tidlist
);
543 while (*tidlist
== ' ' || *tidlist
== '\t')
549 for (; start
<= end
; start
++)
551 tp
= find_thread_id (start
);
554 warning ("Unknown thread %d.", start
);
555 else if (!thread_alive (tp
))
556 warning ("Thread %d has terminated.", start
);
559 switch_to_thread (tp
->pid
);
561 printf_filtered ("\nThread %d (%s):\n", tp
->num
,
562 target_tid_to_str (inferior_pid
));
564 printf_filtered ("\nThread %d (%s):\n", tp
->num
,
565 target_pid_to_str (inferior_pid
));
567 execute_command (cmd
, from_tty
);
573 /* Switch to the specified thread. Will dispatch off to thread_apply_command
574 if prefix of arg is `apply'. */
577 thread_command (tidstr
, from_tty
)
582 struct thread_info
*tp
;
586 /* Don't generate an error, just say which thread is current. */
587 if (target_has_stack
)
588 printf_filtered ("[Current thread is %d (%s)]\n",
589 pid_to_thread_id (inferior_pid
),
590 #if defined(HPUXHPPA)
591 target_tid_to_str (inferior_pid
)
593 target_pid_to_str (inferior_pid
)
602 tp
= find_thread_id (num
);
605 error ("Thread ID %d not known. Use the \"info threads\" command to\n\
606 see the IDs of currently known threads.", num
);
608 if (!thread_alive (tp
))
609 error ("Thread ID %d has terminated.\n", num
);
611 switch_to_thread (tp
->pid
);
616 printf_filtered ("[Switching to thread %d (%s)]\n",
617 pid_to_thread_id (inferior_pid
),
618 #if defined(HPUXHPPA)
619 target_tid_to_str (inferior_pid
)
621 target_pid_to_str (inferior_pid
)
624 print_stack_frame (selected_frame
, selected_frame_level
, 1);
627 /* Commands with a prefix of `thread'. */
628 struct cmd_list_element
*thread_cmd_list
= NULL
;
631 _initialize_thread ()
633 static struct cmd_list_element
*thread_apply_list
= NULL
;
635 add_info ("threads", info_threads_command
,
636 "IDs of currently known threads.");
638 add_prefix_cmd ("thread", class_run
, thread_command
,
639 "Use this command to switch between threads.\n\
640 The new thread ID must be currently known.", &thread_cmd_list
, "thread ", 1,
643 add_prefix_cmd ("apply", class_run
, thread_apply_command
,
644 "Apply a command to a list of threads.",
645 &thread_apply_list
, "apply ", 1, &thread_cmd_list
);
647 add_cmd ("all", class_run
, thread_apply_all_command
,
648 "Apply a command to all threads.",
652 add_com_alias ("t", "thread", class_run
, 1);