* hppa-dis.c: (print_insn_hppa): Do output a space before a 'v'
[deliverable/binutils-gdb.git] / gdb / thread.c
1 /* Multi-process/thread control for GDB, the GNU debugger.
2 Copyright 1986, 1987, 1988, 1993, 1998
3
4 Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
5 Free Software Foundation, Inc.
6
7 This file is part of GDB.
8
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.
13
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.
18
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. */
23
24 #include "defs.h"
25 #include "symtab.h"
26 #include "frame.h"
27 #include "inferior.h"
28 #include "environ.h"
29 #include "value.h"
30 #include "target.h"
31 #include "gdbthread.h"
32 #include "command.h"
33 #include "gdbcmd.h"
34
35 #include <ctype.h>
36 #include <sys/types.h>
37 #include <signal.h>
38
39 /*#include "lynxos-core.h" */
40
41 struct thread_info
42 {
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;
48 char *prev_func_name;
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;
54 int trap_expected;
55 int handling_longjmp;
56 int another_trap;
57
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.
62 */
63 int stepping_through_solib_after_catch;
64
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.
68 */
69 bpstat stepping_through_solib_catchpoints;
70
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;
74
75 };
76
77 /* Prototypes for exported functions. */
78
79 void _initialize_thread PARAMS ((void));
80
81 /* Prototypes for local functions. */
82
83 static struct thread_info *thread_list = NULL;
84 static int highest_thread_num;
85
86 static struct thread_info *find_thread_id PARAMS ((int num));
87
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));
96
97 void
98 init_thread_list ()
99 {
100 struct thread_info *tp, *tpnext;
101
102 if (!thread_list)
103 return;
104
105 for (tp = thread_list; tp; tp = tpnext)
106 {
107 tpnext = tp->next;
108 free (tp);
109 }
110
111 thread_list = NULL;
112 highest_thread_num = 0;
113 }
114
115 void
116 add_thread (pid)
117 int pid;
118 {
119 struct thread_info *tp;
120
121 tp = (struct thread_info *) xmalloc (sizeof (struct thread_info));
122
123 tp->pid = pid;
124 tp->num = ++highest_thread_num;
125 tp->prev_pc = 0;
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;
140 thread_list = tp;
141 }
142
143 void
144 delete_thread (pid)
145 int pid;
146 {
147 struct thread_info *tp, *tpprev;
148
149 tpprev = NULL;
150
151 for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
152 if (tp->pid == pid)
153 break;
154
155 if (!tp)
156 return;
157
158 if (tpprev)
159 tpprev->next = tp->next;
160 else
161 thread_list = tp->next;
162
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);
167
168 free (tp);
169
170 return;
171 }
172
173 static struct thread_info *
174 find_thread_id (num)
175 int num;
176 {
177 struct thread_info *tp;
178
179 for (tp = thread_list; tp; tp = tp->next)
180 if (tp->num == num)
181 return tp;
182
183 return NULL;
184 }
185
186 int
187 valid_thread_id (num)
188 int num;
189 {
190 struct thread_info *tp;
191
192 for (tp = thread_list; tp; tp = tp->next)
193 if (tp->num == num)
194 return 1;
195
196 return 0;
197 }
198
199 int
200 pid_to_thread_id (pid)
201 int pid;
202 {
203 struct thread_info *tp;
204
205 for (tp = thread_list; tp; tp = tp->next)
206 if (tp->pid == pid)
207 return tp->num;
208
209 return 0;
210 }
211
212 int
213 thread_id_to_pid (num)
214 int num;
215 {
216 struct thread_info *thread = find_thread_id (num);
217 if (thread)
218 return thread->pid;
219 else
220 return -1;
221 }
222
223 int
224 in_thread_list (pid)
225 int pid;
226 {
227 struct thread_info *tp;
228
229 for (tp = thread_list; tp; tp = tp->next)
230 if (tp->pid == pid)
231 return 1;
232
233 return 0; /* Never heard of 'im */
234 }
235
236 /* Load infrun state for the thread PID. */
237
238 void
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)
247 int pid;
248 CORE_ADDR *prev_pc;
249 CORE_ADDR *prev_func_start;
250 char **prev_func_name;
251 int *trap_expected;
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;
258 int *another_trap;
259 int *stepping_through_solib_after_catch;
260 bpstat *stepping_through_solib_catchpoints;
261 int *stepping_through_sigtramp;
262 {
263 struct thread_info *tp;
264
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));
268 if (tp == NULL)
269 return;
270
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;
285 }
286
287 /* Save infrun state for the thread PID. */
288
289 void
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)
298 int pid;
299 CORE_ADDR prev_pc;
300 CORE_ADDR prev_func_start;
301 char *prev_func_name;
302 int trap_expected;
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;
309 int another_trap;
310 int stepping_through_solib_after_catch;
311 bpstat stepping_through_solib_catchpoints;
312 int stepping_through_sigtramp;
313 {
314 struct thread_info *tp;
315
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));
319 if (tp == NULL)
320 return;
321
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;
336 }
337
338 /* Return true if TP is an active thread. */
339 static int
340 thread_alive (tp)
341 struct thread_info *tp;
342 {
343 if (tp->pid == -1)
344 return 0;
345 if (!target_thread_alive (tp->pid))
346 {
347 tp->pid = -1; /* Mark it as dead */
348 return 0;
349 }
350 return 1;
351 }
352
353 static void
354 prune_threads ()
355 {
356 struct thread_info *tp, *next;
357
358 for (tp = thread_list; tp; tp = next)
359 {
360 next = tp->next;
361 if (!thread_alive (tp))
362 delete_thread (tp->pid);
363 }
364 }
365
366 /* Print information about currently known threads
367
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.
371 */
372
373 static void
374 info_threads_command (arg, from_tty)
375 char *arg;
376 int from_tty;
377 {
378 struct thread_info *tp;
379 int current_pid;
380 struct frame_info *cur_frame;
381 int saved_frame_level = selected_frame_level;
382 int counter;
383
384 /* Avoid coredumps which would happen if we tried to access a NULL
385 selected_frame. */
386 if (!target_has_stack)
387 error ("No stack.");
388
389 prune_threads ();
390 target_find_new_threads ();
391 current_pid = inferior_pid;
392 for (tp = thread_list; tp; tp = tp->next)
393 {
394 if (tp->pid == current_pid)
395 printf_filtered ("* ");
396 else
397 printf_filtered (" ");
398
399 #ifdef HPUXHPPA
400 printf_filtered ("%d %s ", tp->num, target_tid_to_str (tp->pid));
401 #else
402 printf_filtered ("%d %s ", tp->num, target_pid_to_str (tp->pid));
403 #endif
404 switch_to_thread (tp->pid);
405 if (selected_frame)
406 print_only_stack_frame (selected_frame, -1, 0);
407 else
408 printf_filtered ("[No stack.]\n");
409 }
410
411 switch_to_thread (current_pid);
412
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).
418 */
419 counter = saved_frame_level;
420 cur_frame = find_relative_frame (selected_frame, &counter);
421 if (counter != 0)
422 {
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);
426 }
427 else
428 {
429 select_frame (cur_frame, saved_frame_level);
430 }
431
432 /* re-show current frame. */
433 show_stack_frame (cur_frame);
434 }
435
436 /* Switch from one thread to another. */
437
438 static void
439 switch_to_thread (pid)
440 int pid;
441 {
442 if (pid == inferior_pid)
443 return;
444
445 inferior_pid = pid;
446 flush_cached_frames ();
447 registers_changed ();
448 stop_pc = read_pc ();
449 select_frame (get_current_frame (), 0);
450 }
451
452 static void
453 restore_current_thread (pid)
454 int pid;
455 {
456 if (pid != inferior_pid)
457 {
458 switch_to_thread (pid);
459 print_stack_frame (get_current_frame (), 0, -1);
460 }
461 }
462
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:
466
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
470 */
471
472 static void
473 thread_apply_all_command (cmd, from_tty)
474 char *cmd;
475 int from_tty;
476 {
477 struct thread_info *tp;
478 struct cleanup *old_chain;
479
480 if (cmd == NULL || *cmd == '\000')
481 error ("Please specify a command following the thread ID list");
482
483 old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
484 (void *) inferior_pid);
485
486 for (tp = thread_list; tp; tp = tp->next)
487 if (thread_alive (tp))
488 {
489 switch_to_thread (tp->pid);
490 #ifdef HPUXHPPA
491 printf_filtered ("\nThread %d (%s):\n",
492 tp->num,
493 target_tid_to_str (inferior_pid));
494 #else
495 printf_filtered ("\nThread %d (%s):\n", tp->num,
496 target_pid_to_str (inferior_pid));
497 #endif
498 execute_command (cmd, from_tty);
499 }
500 }
501
502 static void
503 thread_apply_command (tidlist, from_tty)
504 char *tidlist;
505 int from_tty;
506 {
507 char *cmd;
508 char *p;
509 struct cleanup *old_chain;
510
511 if (tidlist == NULL || *tidlist == '\000')
512 error ("Please specify a thread ID list");
513
514 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
515
516 if (*cmd == '\000')
517 error ("Please specify a command following the thread ID list");
518
519 old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
520 (void *) inferior_pid);
521
522 while (tidlist < cmd)
523 {
524 struct thread_info *tp;
525 int start, end;
526
527 start = strtol (tidlist, &p, 10);
528 if (p == tidlist)
529 error ("Error parsing %s", tidlist);
530 tidlist = p;
531
532 while (*tidlist == ' ' || *tidlist == '\t')
533 tidlist++;
534
535 if (*tidlist == '-') /* Got a range of IDs? */
536 {
537 tidlist++; /* Skip the - */
538 end = strtol (tidlist, &p, 10);
539 if (p == tidlist)
540 error ("Error parsing %s", tidlist);
541 tidlist = p;
542
543 while (*tidlist == ' ' || *tidlist == '\t')
544 tidlist++;
545 }
546 else
547 end = start;
548
549 for (; start <= end; start++)
550 {
551 tp = find_thread_id (start);
552
553 if (!tp)
554 warning ("Unknown thread %d.", start);
555 else if (!thread_alive (tp))
556 warning ("Thread %d has terminated.", start);
557 else
558 {
559 switch_to_thread (tp->pid);
560 #ifdef HPUXHPPA
561 printf_filtered ("\nThread %d (%s):\n", tp->num,
562 target_tid_to_str (inferior_pid));
563 #else
564 printf_filtered ("\nThread %d (%s):\n", tp->num,
565 target_pid_to_str (inferior_pid));
566 #endif
567 execute_command (cmd, from_tty);
568 }
569 }
570 }
571 }
572
573 /* Switch to the specified thread. Will dispatch off to thread_apply_command
574 if prefix of arg is `apply'. */
575
576 static void
577 thread_command (tidstr, from_tty)
578 char *tidstr;
579 int from_tty;
580 {
581 int num;
582 struct thread_info *tp;
583
584 if (!tidstr)
585 {
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)
592 #else
593 target_pid_to_str (inferior_pid)
594 #endif
595 );
596 else
597 error ("No stack.");
598 return;
599 }
600 num = atoi (tidstr);
601
602 tp = find_thread_id (num);
603
604 if (!tp)
605 error ("Thread ID %d not known. Use the \"info threads\" command to\n\
606 see the IDs of currently known threads.", num);
607
608 if (!thread_alive (tp))
609 error ("Thread ID %d has terminated.\n", num);
610
611 switch_to_thread (tp->pid);
612
613 if (context_hook)
614 context_hook (num);
615
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)
620 #else
621 target_pid_to_str (inferior_pid)
622 #endif
623 );
624 print_stack_frame (selected_frame, selected_frame_level, 1);
625 }
626
627 /* Commands with a prefix of `thread'. */
628 struct cmd_list_element *thread_cmd_list = NULL;
629
630 void
631 _initialize_thread ()
632 {
633 static struct cmd_list_element *thread_apply_list = NULL;
634
635 add_info ("threads", info_threads_command,
636 "IDs of currently known threads.");
637
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,
641 &cmdlist);
642
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);
646
647 add_cmd ("all", class_run, thread_apply_all_command,
648 "Apply a command to all threads.",
649 &thread_apply_list);
650
651 if (!xdb_commands)
652 add_com_alias ("t", "thread", class_run, 1);
653 }
This page took 0.139288 seconds and 4 git commands to generate.