import gdb-1999-07-07 post reformat
[external/binutils.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   free (tp);
164
165   return;
166 }
167
168 static struct thread_info *
169 find_thread_id (num)
170      int num;
171 {
172   struct thread_info *tp;
173
174   for (tp = thread_list; tp; tp = tp->next)
175     if (tp->num == num)
176       return tp;
177
178   return NULL;
179 }
180
181 int
182 valid_thread_id (num)
183      int num;
184 {
185   struct thread_info *tp;
186
187   for (tp = thread_list; tp; tp = tp->next)
188     if (tp->num == num)
189       return 1;
190
191   return 0;
192 }
193
194 int
195 pid_to_thread_id (pid)
196      int pid;
197 {
198   struct thread_info *tp;
199
200   for (tp = thread_list; tp; tp = tp->next)
201     if (tp->pid == pid)
202       return tp->num;
203
204   return 0;
205 }
206
207 int
208 thread_id_to_pid (num)
209      int num;
210 {
211   struct thread_info *thread = find_thread_id (num);
212   if (thread)
213     return thread->pid;
214   else
215     return -1;
216 }
217
218 int
219 in_thread_list (pid)
220      int pid;
221 {
222   struct thread_info *tp;
223
224   for (tp = thread_list; tp; tp = tp->next)
225     if (tp->pid == pid)
226       return 1;
227
228   return 0;                     /* Never heard of 'im */
229 }
230
231 /* Load infrun state for the thread PID.  */
232
233 void
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)
242      int pid;
243      CORE_ADDR *prev_pc;
244      CORE_ADDR *prev_func_start;
245      char **prev_func_name;
246      int *trap_expected;
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;
253      int *another_trap;
254      int *stepping_through_solib_after_catch;
255      bpstat *stepping_through_solib_catchpoints;
256      int *stepping_through_sigtramp;
257 {
258   struct thread_info *tp;
259
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));
263   if (tp == NULL)
264     return;
265
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;
280 }
281
282 /* Save infrun state for the thread PID.  */
283
284 void
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)
293      int pid;
294      CORE_ADDR prev_pc;
295      CORE_ADDR prev_func_start;
296      char *prev_func_name;
297      int trap_expected;
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;
304      int another_trap;
305      int stepping_through_solib_after_catch;
306      bpstat stepping_through_solib_catchpoints;
307      int stepping_through_sigtramp;
308 {
309   struct thread_info *tp;
310
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));
314   if (tp == NULL)
315     return;
316
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;
331 }
332
333 /* Return true if TP is an active thread. */
334 static int
335 thread_alive (tp)
336      struct thread_info *tp;
337 {
338   if (tp->pid == -1)
339     return 0;
340   if (!target_thread_alive (tp->pid))
341     {
342       tp->pid = -1;             /* Mark it as dead */
343       return 0;
344     }
345   return 1;
346 }
347
348 static void
349 prune_threads ()
350 {
351   struct thread_info *tp, *tpprev, *next;
352
353   tpprev = 0;
354   for (tp = thread_list; tp; tp = next)
355     {
356       next = tp->next;
357       if (!thread_alive (tp))
358         {
359           if (tpprev)
360             tpprev->next = next;
361           else
362             thread_list = next;
363           free (tp);
364         }
365       else
366         tpprev = tp;
367     }
368 }
369
370 /* Print information about currently known threads 
371
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.
375  */
376
377 static void
378 info_threads_command (arg, from_tty)
379      char *arg;
380      int from_tty;
381 {
382   struct thread_info *tp;
383   int current_pid;
384   struct frame_info *cur_frame;
385   int saved_frame_level = selected_frame_level;
386   int counter;
387
388   /* Avoid coredumps which would happen if we tried to access a NULL
389      selected_frame.  */
390   if (!target_has_stack)
391     error ("No stack.");
392
393   prune_threads ();
394   target_find_new_threads ();
395   current_pid = inferior_pid;
396   for (tp = thread_list; tp; tp = tp->next)
397     {
398       if (tp->pid == current_pid)
399         printf_filtered ("* ");
400       else
401         printf_filtered ("  ");
402
403 #ifdef HPUXHPPA
404       printf_filtered ("%d %s  ", tp->num, target_tid_to_str (tp->pid));
405 #else
406       printf_filtered ("%d %s  ", tp->num, target_pid_to_str (tp->pid));
407 #endif
408       switch_to_thread (tp->pid);
409       if (selected_frame)
410         print_only_stack_frame (selected_frame, -1, 0);
411       else
412         printf_filtered ("[No stack.]\n");
413     }
414
415   switch_to_thread (current_pid);
416
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).
422    */
423   counter = saved_frame_level;
424   cur_frame = find_relative_frame (selected_frame, &counter);
425   if (counter != 0)
426     {
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);
430     }
431   else
432     {
433       select_frame (cur_frame, saved_frame_level);
434     }
435
436   /* re-show current frame. */
437   show_stack_frame (cur_frame);
438 }
439
440 /* Switch from one thread to another. */
441
442 static void
443 switch_to_thread (pid)
444      int pid;
445 {
446   if (pid == inferior_pid)
447     return;
448
449   inferior_pid = pid;
450   flush_cached_frames ();
451   registers_changed ();
452   stop_pc = read_pc ();
453   select_frame (get_current_frame (), 0);
454 }
455
456 static void
457 restore_current_thread (pid)
458      int pid;
459 {
460   if (pid != inferior_pid)
461     {
462       switch_to_thread (pid);
463       print_stack_frame (get_current_frame (), 0, -1);
464     }
465 }
466
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:
470
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
474  */
475
476 static void
477 thread_apply_all_command (cmd, from_tty)
478      char *cmd;
479      int from_tty;
480 {
481   struct thread_info *tp;
482   struct cleanup *old_chain;
483
484   if (cmd == NULL || *cmd == '\000')
485     error ("Please specify a command following the thread ID list");
486
487   old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
488                             (void *) inferior_pid);
489
490   for (tp = thread_list; tp; tp = tp->next)
491     if (thread_alive (tp))
492       {
493         switch_to_thread (tp->pid);
494 #ifdef HPUXHPPA
495         printf_filtered ("\nThread %d (%s):\n",
496                          tp->num,
497                          target_tid_to_str (inferior_pid));
498 #else
499         printf_filtered ("\nThread %d (%s):\n", tp->num,
500                          target_pid_to_str (inferior_pid));
501 #endif
502         execute_command (cmd, from_tty);
503       }
504 }
505
506 static void
507 thread_apply_command (tidlist, from_tty)
508      char *tidlist;
509      int from_tty;
510 {
511   char *cmd;
512   char *p;
513   struct cleanup *old_chain;
514
515   if (tidlist == NULL || *tidlist == '\000')
516     error ("Please specify a thread ID list");
517
518   for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
519
520   if (*cmd == '\000')
521     error ("Please specify a command following the thread ID list");
522
523   old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
524                             (void *) inferior_pid);
525
526   while (tidlist < cmd)
527     {
528       struct thread_info *tp;
529       int start, end;
530
531       start = strtol (tidlist, &p, 10);
532       if (p == tidlist)
533         error ("Error parsing %s", tidlist);
534       tidlist = p;
535
536       while (*tidlist == ' ' || *tidlist == '\t')
537         tidlist++;
538
539       if (*tidlist == '-')      /* Got a range of IDs? */
540         {
541           tidlist++;            /* Skip the - */
542           end = strtol (tidlist, &p, 10);
543           if (p == tidlist)
544             error ("Error parsing %s", tidlist);
545           tidlist = p;
546
547           while (*tidlist == ' ' || *tidlist == '\t')
548             tidlist++;
549         }
550       else
551         end = start;
552
553       for (; start <= end; start++)
554         {
555           tp = find_thread_id (start);
556
557           if (!tp)
558             warning ("Unknown thread %d.", start);
559           else if (!thread_alive (tp))
560             warning ("Thread %d has terminated.", start);
561           else
562             {
563               switch_to_thread (tp->pid);
564 #ifdef HPUXHPPA
565               printf_filtered ("\nThread %d (%s):\n", tp->num,
566                                target_tid_to_str (inferior_pid));
567 #else
568               printf_filtered ("\nThread %d (%s):\n", tp->num,
569                                target_pid_to_str (inferior_pid));
570 #endif
571               execute_command (cmd, from_tty);
572             }
573         }
574     }
575 }
576
577 /* Switch to the specified thread.  Will dispatch off to thread_apply_command
578    if prefix of arg is `apply'.  */
579
580 static void
581 thread_command (tidstr, from_tty)
582      char *tidstr;
583      int from_tty;
584 {
585   int num;
586   struct thread_info *tp;
587
588   if (!tidstr)
589     {
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)
596 #else
597                          target_pid_to_str (inferior_pid)
598 #endif
599           );
600       else
601         error ("No stack.");
602       return;
603     }
604   num = atoi (tidstr);
605
606   tp = find_thread_id (num);
607
608   if (!tp)
609     error ("Thread ID %d not known.  Use the \"info threads\" command to\n\
610 see the IDs of currently known threads.", num);
611
612   if (!thread_alive (tp))
613     error ("Thread ID %d has terminated.\n", num);
614
615   switch_to_thread (tp->pid);
616
617   if (context_hook)
618     context_hook (num);
619
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)
624 #else
625                    target_pid_to_str (inferior_pid)
626 #endif
627     );
628   print_stack_frame (selected_frame, selected_frame_level, 1);
629 }
630
631 /* Commands with a prefix of `thread'.  */
632 struct cmd_list_element *thread_cmd_list = NULL;
633
634 void
635 _initialize_thread ()
636 {
637   static struct cmd_list_element *thread_apply_list = NULL;
638
639   add_info ("threads", info_threads_command,
640             "IDs of currently known threads.");
641
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,
645                   &cmdlist);
646
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);
650
651   add_cmd ("all", class_run, thread_apply_all_command,
652            "Apply a command to all threads.",
653            &thread_apply_list);
654
655   if (!xdb_commands)
656     add_com_alias ("t", "thread", class_run, 1);
657 }