]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/thread.c
Only support interworking and pic for ELF or COFF targets
[thirdparty/binutils-gdb.git] / gdb / thread.c
CommitLineData
c906108c
SS
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
c5aa993b 7 This file is part of GDB.
c906108c 8
c5aa993b
JM
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.
c906108c 13
c5aa993b
JM
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.
c906108c 18
c5aa993b
JM
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. */
c906108c
SS
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
c5aa993b 39/*#include "lynxos-core.h" */
c906108c
SS
40
41struct thread_info
c5aa993b
JM
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.
c906108c 62 */
c5aa993b 63 int stepping_through_solib_after_catch;
c906108c 64
c5aa993b
JM
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.
c906108c 68 */
c5aa993b 69 bpstat stepping_through_solib_catchpoints;
c906108c 70
c5aa993b
JM
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;
c906108c 74
c5aa993b 75 };
c906108c
SS
76
77/* Prototypes for exported functions. */
78
79void _initialize_thread PARAMS ((void));
80
81/* Prototypes for local functions. */
82
c906108c
SS
83static struct thread_info *thread_list = NULL;
84static int highest_thread_num;
85
c5aa993b 86static struct thread_info *find_thread_id PARAMS ((int num));
c906108c 87
c5aa993b 88static void thread_command PARAMS ((char *tidstr, int from_tty));
c906108c 89static void thread_apply_all_command PARAMS ((char *, int));
c5aa993b 90static int thread_alive PARAMS ((struct thread_info *));
c906108c
SS
91static void info_threads_command PARAMS ((char *, int));
92static void thread_apply_command PARAMS ((char *, int));
93static void restore_current_thread PARAMS ((int));
94static void switch_to_thread PARAMS ((int pid));
95static void prune_threads PARAMS ((void));
c906108c
SS
96
97void
98init_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
115void
116add_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;
c5aa993b 130 tp->step_frame_address = 0;
c906108c
SS
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
143void
144delete_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
53a5351d
JM
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
c906108c
SS
168 free (tp);
169
170 return;
171}
172
173static struct thread_info *
174find_thread_id (num)
c5aa993b 175 int num;
c906108c
SS
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
186int
187valid_thread_id (num)
c5aa993b 188 int num;
c906108c
SS
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
199int
200pid_to_thread_id (pid)
c5aa993b 201 int pid;
c906108c
SS
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
212int
213thread_id_to_pid (num)
c5aa993b 214 int num;
c906108c
SS
215{
216 struct thread_info *thread = find_thread_id (num);
217 if (thread)
218 return thread->pid;
219 else
220 return -1;
221}
222
223int
224in_thread_list (pid)
c5aa993b 225 int pid;
c906108c
SS
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
c5aa993b
JM
238void
239load_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)
c906108c
SS
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;
c5aa993b
JM
259 int *stepping_through_solib_after_catch;
260 bpstat *stepping_through_solib_catchpoints;
261 int *stepping_through_sigtramp;
c906108c
SS
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
c5aa993b
JM
289void
290save_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)
c906108c
SS
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;
c5aa993b
JM
310 int stepping_through_solib_after_catch;
311 bpstat stepping_through_solib_catchpoints;
312 int stepping_through_sigtramp;
c906108c
SS
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. */
339static int
340thread_alive (tp)
341 struct thread_info *tp;
342{
343 if (tp->pid == -1)
344 return 0;
c5aa993b 345 if (!target_thread_alive (tp->pid))
c906108c 346 {
c5aa993b 347 tp->pid = -1; /* Mark it as dead */
c906108c
SS
348 return 0;
349 }
350 return 1;
351}
352
353static void
354prune_threads ()
355{
356 struct thread_info *tp, *tpprev, *next;
357
c906108c
SS
358 for (tp = thread_list; tp; tp = next)
359 {
360 next = tp->next;
361 if (!thread_alive (tp))
53a5351d 362 delete_thread (tp->pid);
c906108c
SS
363 }
364}
365
366/* Print information about currently known threads
c5aa993b 367
c906108c
SS
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
373static void
374info_threads_command (arg, from_tty)
375 char *arg;
376 int from_tty;
377{
378 struct thread_info *tp;
c5aa993b
JM
379 int current_pid;
380 struct frame_info *cur_frame;
381 int saved_frame_level = selected_frame_level;
382 int counter;
c906108c
SS
383
384 /* Avoid coredumps which would happen if we tried to access a NULL
385 selected_frame. */
c5aa993b
JM
386 if (!target_has_stack)
387 error ("No stack.");
c906108c
SS
388
389 prune_threads ();
b83266a0 390 target_find_new_threads ();
c906108c
SS
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 */
c5aa993b
JM
419 counter = saved_frame_level;
420 cur_frame = find_relative_frame (selected_frame, &counter);
c906108c
SS
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 {
c5aa993b 429 select_frame (cur_frame, saved_frame_level);
c906108c
SS
430 }
431
432 /* re-show current frame. */
c5aa993b 433 show_stack_frame (cur_frame);
c906108c
SS
434}
435
436/* Switch from one thread to another. */
437
438static void
439switch_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 ();
c5aa993b 448 stop_pc = read_pc ();
c906108c
SS
449 select_frame (get_current_frame (), 0);
450}
451
452static void
453restore_current_thread (pid)
454 int pid;
455{
c5aa993b 456 if (pid != inferior_pid)
c906108c
SS
457 {
458 switch_to_thread (pid);
c5aa993b 459 print_stack_frame (get_current_frame (), 0, -1);
c906108c
SS
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
c5aa993b
JM
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 */
c906108c
SS
471
472static void
473thread_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
c5aa993b 483 old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
c906108c
SS
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
502static void
503thread_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
c5aa993b 514 for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
c906108c
SS
515
516 if (*cmd == '\000')
517 error ("Please specify a command following the thread ID list");
518
c5aa993b 519 old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
c906108c
SS
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 {
c5aa993b 537 tidlist++; /* Skip the - */
c906108c
SS
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
576static void
577thread_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",
c5aa993b 589 pid_to_thread_id (inferior_pid),
c906108c 590#if defined(HPUXHPPA)
c5aa993b 591 target_tid_to_str (inferior_pid)
c906108c 592#else
c5aa993b 593 target_pid_to_str (inferior_pid)
c906108c 594#endif
c5aa993b 595 );
c906108c
SS
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\
606see 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
c5aa993b 623 );
c906108c
SS
624 print_stack_frame (selected_frame, selected_frame_level, 1);
625}
626
627/* Commands with a prefix of `thread'. */
628struct cmd_list_element *thread_cmd_list = NULL;
629
630void
631_initialize_thread ()
632{
633 static struct cmd_list_element *thread_apply_list = NULL;
c906108c
SS
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\
640The 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}