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 /* Prototypes for exported functions. */
78 void _initialize_thread
PARAMS ((void));
80 /* Prototypes for local functions. */
82 static struct thread_info
*thread_list
= NULL
;
83 static int highest_thread_num
;
85 static struct thread_info
* find_thread_id
PARAMS ((int num
));
87 static void thread_command
PARAMS ((char * tidstr
, int from_tty
));
88 static void thread_apply_all_command
PARAMS ((char *, int));
89 static int thread_alive
PARAMS ((struct thread_info
*));
90 static void info_threads_command
PARAMS ((char *, int));
91 static void thread_apply_command
PARAMS ((char *, int));
92 static void restore_current_thread
PARAMS ((int));
93 static void switch_to_thread
PARAMS ((int pid
));
94 static void prune_threads
PARAMS ((void));
99 struct thread_info
*tp
, *tpnext
;
104 for (tp
= thread_list
; tp
; tp
= tpnext
)
111 highest_thread_num
= 0;
118 struct thread_info
*tp
;
120 tp
= (struct thread_info
*) xmalloc (sizeof (struct thread_info
));
123 tp
->num
= ++highest_thread_num
;
125 tp
->prev_func_start
= 0;
126 tp
->prev_func_name
= NULL
;
127 tp
->step_range_start
= 0;
128 tp
->step_range_end
= 0;
129 tp
->step_frame_address
=0;
130 tp
->step_resume_breakpoint
= 0;
131 tp
->through_sigtramp_breakpoint
= 0;
132 tp
->handling_longjmp
= 0;
133 tp
->trap_expected
= 0;
134 tp
->another_trap
= 0;
135 tp
->stepping_through_solib_after_catch
= 0;
136 tp
->stepping_through_solib_catchpoints
= NULL
;
137 tp
->stepping_through_sigtramp
= 0;
138 tp
->next
= thread_list
;
146 struct thread_info
*tp
, *tpprev
;
150 for (tp
= thread_list
; tp
; tpprev
= tp
, tp
= tp
->next
)
158 tpprev
->next
= tp
->next
;
160 thread_list
= tp
->next
;
167 static struct thread_info
*
171 struct thread_info
*tp
;
173 for (tp
= thread_list
; tp
; tp
= tp
->next
)
181 valid_thread_id (num
)
184 struct thread_info
*tp
;
186 for (tp
= thread_list
; tp
; tp
= tp
->next
)
194 pid_to_thread_id (pid
)
197 struct thread_info
*tp
;
199 for (tp
= thread_list
; tp
; tp
= tp
->next
)
207 thread_id_to_pid (num
)
210 struct thread_info
*thread
= find_thread_id (num
);
221 struct thread_info
*tp
;
223 for (tp
= thread_list
; tp
; tp
= tp
->next
)
227 return 0; /* Never heard of 'im */
230 /* Load infrun state for the thread PID. */
232 void load_infrun_state (pid
, prev_pc
, prev_func_start
, prev_func_name
,
233 trap_expected
, step_resume_breakpoint
,
234 through_sigtramp_breakpoint
, step_range_start
,
235 step_range_end
, step_frame_address
,
236 handling_longjmp
, another_trap
,
237 stepping_through_solib_after_catch
,
238 stepping_through_solib_catchpoints
,
239 stepping_through_sigtramp
)
242 CORE_ADDR
*prev_func_start
;
243 char **prev_func_name
;
245 struct breakpoint
**step_resume_breakpoint
;
246 struct breakpoint
**through_sigtramp_breakpoint
;
247 CORE_ADDR
*step_range_start
;
248 CORE_ADDR
*step_range_end
;
249 CORE_ADDR
*step_frame_address
;
250 int *handling_longjmp
;
252 int * stepping_through_solib_after_catch
;
253 bpstat
* stepping_through_solib_catchpoints
;
254 int * stepping_through_sigtramp
;
256 struct thread_info
*tp
;
258 /* If we can't find the thread, then we're debugging a single threaded
259 process. No need to do anything in that case. */
260 tp
= find_thread_id (pid_to_thread_id (pid
));
264 *prev_pc
= tp
->prev_pc
;
265 *prev_func_start
= tp
->prev_func_start
;
266 *prev_func_name
= tp
->prev_func_name
;
267 *step_resume_breakpoint
= tp
->step_resume_breakpoint
;
268 *step_range_start
= tp
->step_range_start
;
269 *step_range_end
= tp
->step_range_end
;
270 *step_frame_address
= tp
->step_frame_address
;
271 *through_sigtramp_breakpoint
= tp
->through_sigtramp_breakpoint
;
272 *handling_longjmp
= tp
->handling_longjmp
;
273 *trap_expected
= tp
->trap_expected
;
274 *another_trap
= tp
->another_trap
;
275 *stepping_through_solib_after_catch
= tp
->stepping_through_solib_after_catch
;
276 *stepping_through_solib_catchpoints
= tp
->stepping_through_solib_catchpoints
;
277 *stepping_through_sigtramp
= tp
->stepping_through_sigtramp
;
280 /* Save infrun state for the thread PID. */
282 void save_infrun_state (pid
, prev_pc
, prev_func_start
, prev_func_name
,
283 trap_expected
, step_resume_breakpoint
,
284 through_sigtramp_breakpoint
, step_range_start
,
285 step_range_end
, step_frame_address
,
286 handling_longjmp
, another_trap
,
287 stepping_through_solib_after_catch
,
288 stepping_through_solib_catchpoints
,
289 stepping_through_sigtramp
)
292 CORE_ADDR prev_func_start
;
293 char *prev_func_name
;
295 struct breakpoint
*step_resume_breakpoint
;
296 struct breakpoint
*through_sigtramp_breakpoint
;
297 CORE_ADDR step_range_start
;
298 CORE_ADDR step_range_end
;
299 CORE_ADDR step_frame_address
;
300 int handling_longjmp
;
302 int stepping_through_solib_after_catch
;
303 bpstat stepping_through_solib_catchpoints
;
304 int stepping_through_sigtramp
;
306 struct thread_info
*tp
;
308 /* If we can't find the thread, then we're debugging a single-threaded
309 process. Nothing to do in that case. */
310 tp
= find_thread_id (pid_to_thread_id (pid
));
314 tp
->prev_pc
= prev_pc
;
315 tp
->prev_func_start
= prev_func_start
;
316 tp
->prev_func_name
= prev_func_name
;
317 tp
->step_resume_breakpoint
= step_resume_breakpoint
;
318 tp
->step_range_start
= step_range_start
;
319 tp
->step_range_end
= step_range_end
;
320 tp
->step_frame_address
= step_frame_address
;
321 tp
->through_sigtramp_breakpoint
= through_sigtramp_breakpoint
;
322 tp
->handling_longjmp
= handling_longjmp
;
323 tp
->trap_expected
= trap_expected
;
324 tp
->another_trap
= another_trap
;
325 tp
->stepping_through_solib_after_catch
= stepping_through_solib_after_catch
;
326 tp
->stepping_through_solib_catchpoints
= stepping_through_solib_catchpoints
;
327 tp
->stepping_through_sigtramp
= stepping_through_sigtramp
;
330 /* Return true if TP is an active thread. */
333 struct thread_info
*tp
;
337 if (! target_thread_alive (tp
->pid
))
339 tp
->pid
= -1; /* Mark it as dead */
348 struct thread_info
*tp
, *tpprev
, *next
;
351 for (tp
= thread_list
; tp
; tp
= next
)
354 if (!thread_alive (tp
))
367 /* Print information about currently known threads
369 * Note: this has the drawback that it _really_ switches
370 * threads, which frees the frame cache. A no-side
371 * effects info-threads command would be nicer.
375 info_threads_command (arg
, from_tty
)
379 struct thread_info
*tp
;
381 struct frame_info
*cur_frame
;
382 int saved_frame_level
= selected_frame_level
;
385 /* Avoid coredumps which would happen if we tried to access a NULL
387 if (!target_has_stack
) error ("No 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 ();
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);