]> Git Repo - binutils.git/blob - gdb/thread.c
Purge last remaining make_cleanup_func.
[binutils.git] / gdb / thread.c
1 /* Multi-process/thread control for GDB, the GNU debugger.
2    Copyright 1986, 1987, 1988, 1993, 1998, 1999, 2000
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 #ifdef UI_OUT
39 #include "ui-out.h"
40 #endif
41
42 /*#include "lynxos-core.h" */
43
44 /* Definition of struct thread_info exported to gdbthread.h */
45
46 /* Prototypes for exported functions. */
47
48 void _initialize_thread (void);
49
50 /* Prototypes for local functions. */
51
52 static struct thread_info *thread_list = NULL;
53 static int highest_thread_num;
54
55 static struct thread_info *find_thread_id (int num);
56
57 static void thread_command (char *tidstr, int from_tty);
58 static void thread_apply_all_command (char *, int);
59 static int thread_alive (struct thread_info *);
60 static void info_threads_command (char *, int);
61 static void thread_apply_command (char *, int);
62 static void restore_current_thread (int);
63 static void switch_to_thread (int pid);
64 static void prune_threads (void);
65
66 void
67 init_thread_list ()
68 {
69   struct thread_info *tp, *tpnext;
70
71   if (!thread_list)
72     return;
73
74   for (tp = thread_list; tp; tp = tpnext)
75     {
76       tpnext = tp->next;
77       free (tp);
78     }
79
80   thread_list = NULL;
81   highest_thread_num = 0;
82 }
83
84 /* add_thread now returns a pointer to the new thread_info, 
85    so that back_ends can initialize their private data.  */
86
87 struct thread_info *
88 add_thread (pid)
89      int pid;
90 {
91   struct thread_info *tp;
92
93   tp = (struct thread_info *) xmalloc (sizeof (struct thread_info));
94
95   tp->pid = pid;
96   tp->num = ++highest_thread_num;
97   tp->prev_pc = 0;
98   tp->prev_func_start = 0;
99   tp->prev_func_name = NULL;
100   tp->step_range_start = 0;
101   tp->step_range_end = 0;
102   tp->step_frame_address = 0;
103   tp->step_resume_breakpoint = 0;
104   tp->through_sigtramp_breakpoint = 0;
105   tp->handling_longjmp = 0;
106   tp->trap_expected = 0;
107   tp->another_trap = 0;
108   tp->stepping_through_solib_after_catch = 0;
109   tp->stepping_through_solib_catchpoints = NULL;
110   tp->stepping_through_sigtramp = 0;
111   tp->next = thread_list;
112   tp->private = NULL;
113   thread_list = tp;
114   return tp;
115 }
116
117 void
118 delete_thread (pid)
119      int pid;
120 {
121   struct thread_info *tp, *tpprev;
122
123   tpprev = NULL;
124
125   for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
126     if (tp->pid == pid)
127       break;
128
129   if (!tp)
130     return;
131
132   if (tpprev)
133     tpprev->next = tp->next;
134   else
135     thread_list = tp->next;
136
137   /* NOTE: this will take care of any left-over step_resume breakpoints,
138      but not any user-specified thread-specific breakpoints. */
139   if (tp->step_resume_breakpoint)
140     delete_breakpoint (tp->step_resume_breakpoint);
141
142   /* FIXME: do I ever need to call the back-end to give it a
143      chance at this private data before deleting the thread?  */
144   if (tp->private)
145     free (tp->private);
146
147   free (tp);
148
149   return;
150 }
151
152 static struct thread_info *
153 find_thread_id (num)
154      int num;
155 {
156   struct thread_info *tp;
157
158   for (tp = thread_list; tp; tp = tp->next)
159     if (tp->num == num)
160       return tp;
161
162   return NULL;
163 }
164
165 /* Find a thread_info by matching 'pid'.  */
166 struct thread_info *
167 find_thread_pid (pid)
168      int pid;
169 {
170   struct thread_info *tp;
171
172   for (tp = thread_list; tp; tp = tp->next)
173     if (tp->pid == pid)
174       return tp;
175
176   return NULL;
177 }
178
179 /*
180  * Thread iterator function.
181  *
182  * Calls a callback function once for each thread, so long as
183  * the callback function returns false.  If the callback function
184  * returns true, the iteration will end and the current thread
185  * will be returned.  This can be useful for implementing a 
186  * search for a thread with arbitrary attributes, or for applying
187  * some operation to every thread.
188  *
189  * FIXME: some of the existing functionality, such as 
190  * "Thread apply all", might be rewritten using this functionality.
191  */
192
193 struct thread_info *
194 iterate_over_threads (callback, data)
195      int (*callback) ();
196      void *data;
197 {
198   struct thread_info *tp;
199
200   for (tp = thread_list; tp; tp = tp->next)
201     if ((*callback) (tp, data))
202       return tp;
203
204   return NULL;
205 }
206
207 int
208 valid_thread_id (num)
209      int num;
210 {
211   struct thread_info *tp;
212
213   for (tp = thread_list; tp; tp = tp->next)
214     if (tp->num == num)
215       return 1;
216
217   return 0;
218 }
219
220 int
221 pid_to_thread_id (pid)
222      int pid;
223 {
224   struct thread_info *tp;
225
226   for (tp = thread_list; tp; tp = tp->next)
227     if (tp->pid == pid)
228       return tp->num;
229
230   return 0;
231 }
232
233 int
234 thread_id_to_pid (num)
235      int num;
236 {
237   struct thread_info *thread = find_thread_id (num);
238   if (thread)
239     return thread->pid;
240   else
241     return -1;
242 }
243
244 int
245 in_thread_list (pid)
246      int pid;
247 {
248   struct thread_info *tp;
249
250   for (tp = thread_list; tp; tp = tp->next)
251     if (tp->pid == pid)
252       return 1;
253
254   return 0;                     /* Never heard of 'im */
255 }
256 #ifdef UI_OUT
257 /* Print a list of thread ids currently known, and the total number of
258    threads. To be used from within catch_errors. */
259 static int 
260 do_captured_list_thread_ids (void *arg)
261 {
262   struct thread_info *tp;
263   int num = 0;
264
265   ui_out_list_begin (uiout, "thread-ids");
266
267   for (tp = thread_list; tp; tp = tp->next)
268     {
269       num++;
270       ui_out_field_int (uiout, "thread-id", tp->num);
271     }
272
273   ui_out_list_end (uiout);
274   ui_out_field_int (uiout, "number-of-threads", num);
275   return GDB_RC_OK;
276 }
277
278 /* Official gdblib interface function to get a list of thread ids and
279    the total number. */
280 enum gdb_rc
281 gdb_list_thread_ids (/* output object */)
282 {
283   return catch_errors (do_captured_list_thread_ids, NULL,
284                        NULL, RETURN_MASK_ALL);
285 }
286 #endif
287
288 /* Load infrun state for the thread PID.  */
289
290 void
291 load_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
292                    trap_expected, step_resume_breakpoint,
293                    through_sigtramp_breakpoint, step_range_start,
294                    step_range_end, step_frame_address,
295                    handling_longjmp, another_trap,
296                    stepping_through_solib_after_catch,
297                    stepping_through_solib_catchpoints,
298                    stepping_through_sigtramp)
299      int pid;
300      CORE_ADDR *prev_pc;
301      CORE_ADDR *prev_func_start;
302      char **prev_func_name;
303      int *trap_expected;
304      struct breakpoint **step_resume_breakpoint;
305      struct breakpoint **through_sigtramp_breakpoint;
306      CORE_ADDR *step_range_start;
307      CORE_ADDR *step_range_end;
308      CORE_ADDR *step_frame_address;
309      int *handling_longjmp;
310      int *another_trap;
311      int *stepping_through_solib_after_catch;
312      bpstat *stepping_through_solib_catchpoints;
313      int *stepping_through_sigtramp;
314 {
315   struct thread_info *tp;
316
317   /* If we can't find the thread, then we're debugging a single threaded
318      process.  No need to do anything in that case.  */
319   tp = find_thread_id (pid_to_thread_id (pid));
320   if (tp == NULL)
321     return;
322
323   *prev_pc = tp->prev_pc;
324   *prev_func_start = tp->prev_func_start;
325   *prev_func_name = tp->prev_func_name;
326   *step_resume_breakpoint = tp->step_resume_breakpoint;
327   *step_range_start = tp->step_range_start;
328   *step_range_end = tp->step_range_end;
329   *step_frame_address = tp->step_frame_address;
330   *through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint;
331   *handling_longjmp = tp->handling_longjmp;
332   *trap_expected = tp->trap_expected;
333   *another_trap = tp->another_trap;
334   *stepping_through_solib_after_catch = tp->stepping_through_solib_after_catch;
335   *stepping_through_solib_catchpoints = tp->stepping_through_solib_catchpoints;
336   *stepping_through_sigtramp = tp->stepping_through_sigtramp;
337 }
338
339 /* Save infrun state for the thread PID.  */
340
341 void
342 save_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
343                    trap_expected, step_resume_breakpoint,
344                    through_sigtramp_breakpoint, step_range_start,
345                    step_range_end, step_frame_address,
346                    handling_longjmp, another_trap,
347                    stepping_through_solib_after_catch,
348                    stepping_through_solib_catchpoints,
349                    stepping_through_sigtramp)
350      int pid;
351      CORE_ADDR prev_pc;
352      CORE_ADDR prev_func_start;
353      char *prev_func_name;
354      int trap_expected;
355      struct breakpoint *step_resume_breakpoint;
356      struct breakpoint *through_sigtramp_breakpoint;
357      CORE_ADDR step_range_start;
358      CORE_ADDR step_range_end;
359      CORE_ADDR step_frame_address;
360      int handling_longjmp;
361      int another_trap;
362      int stepping_through_solib_after_catch;
363      bpstat stepping_through_solib_catchpoints;
364      int stepping_through_sigtramp;
365 {
366   struct thread_info *tp;
367
368   /* If we can't find the thread, then we're debugging a single-threaded
369      process.  Nothing to do in that case.  */
370   tp = find_thread_id (pid_to_thread_id (pid));
371   if (tp == NULL)
372     return;
373
374   tp->prev_pc = prev_pc;
375   tp->prev_func_start = prev_func_start;
376   tp->prev_func_name = prev_func_name;
377   tp->step_resume_breakpoint = step_resume_breakpoint;
378   tp->step_range_start = step_range_start;
379   tp->step_range_end = step_range_end;
380   tp->step_frame_address = step_frame_address;
381   tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint;
382   tp->handling_longjmp = handling_longjmp;
383   tp->trap_expected = trap_expected;
384   tp->another_trap = another_trap;
385   tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
386   tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
387   tp->stepping_through_sigtramp = stepping_through_sigtramp;
388 }
389
390 /* Return true if TP is an active thread. */
391 static int
392 thread_alive (tp)
393      struct thread_info *tp;
394 {
395   if (tp->pid == -1)
396     return 0;
397   if (!target_thread_alive (tp->pid))
398     {
399       tp->pid = -1;             /* Mark it as dead */
400       return 0;
401     }
402   return 1;
403 }
404
405 static void
406 prune_threads ()
407 {
408   struct thread_info *tp, *next;
409
410   for (tp = thread_list; tp; tp = next)
411     {
412       next = tp->next;
413       if (!thread_alive (tp))
414         delete_thread (tp->pid);
415     }
416 }
417
418 /* Print information about currently known threads 
419
420  * Note: this has the drawback that it _really_ switches
421  *       threads, which frees the frame cache.  A no-side
422  *       effects info-threads command would be nicer.
423  */
424
425 static void
426 info_threads_command (arg, from_tty)
427      char *arg;
428      int from_tty;
429 {
430   struct thread_info *tp;
431   int current_pid;
432   struct frame_info *cur_frame;
433   int saved_frame_level = selected_frame_level;
434   int counter;
435   char *extra_info;
436
437   /* Avoid coredumps which would happen if we tried to access a NULL
438      selected_frame.  */
439   if (!target_has_stack)
440     error ("No stack.");
441
442   prune_threads ();
443   target_find_new_threads ();
444   current_pid = inferior_pid;
445   for (tp = thread_list; tp; tp = tp->next)
446     {
447       if (tp->pid == current_pid)
448         printf_filtered ("* ");
449       else
450         printf_filtered ("  ");
451
452 #ifdef HPUXHPPA
453       printf_filtered ("%d %s", tp->num, target_tid_to_str (tp->pid));
454 #else
455       printf_filtered ("%d %s", tp->num, target_pid_to_str (tp->pid));
456 #endif
457
458       extra_info = target_extra_thread_info (tp);
459       if (extra_info)
460         printf_filtered (" (%s)", extra_info);
461       puts_filtered ("  ");
462
463       switch_to_thread (tp->pid);
464       if (selected_frame)
465         print_only_stack_frame (selected_frame, -1, 0);
466       else
467         printf_filtered ("[No stack.]\n");
468     }
469
470   switch_to_thread (current_pid);
471
472   /* Code below copied from "up_silently_base" in "stack.c".
473    * It restores the frame set by the user before the "info threads"
474    * command.  We have finished the info-threads display by switching
475    * back to the current thread.  That switch has put us at the top
476    * of the stack (leaf frame).
477    */
478   counter = saved_frame_level;
479   cur_frame = find_relative_frame (selected_frame, &counter);
480   if (counter != 0)
481     {
482       /* Ooops, can't restore, tell user where we are. */
483       warning ("Couldn't restore frame in current thread, at frame 0");
484       print_stack_frame (selected_frame, -1, 0);
485     }
486   else
487     {
488       select_frame (cur_frame, saved_frame_level);
489     }
490
491   /* re-show current frame. */
492   show_stack_frame (cur_frame);
493 }
494
495 /* Switch from one thread to another. */
496
497 static void
498 switch_to_thread (pid)
499      int pid;
500 {
501   if (pid == inferior_pid)
502     return;
503
504   inferior_pid = pid;
505   flush_cached_frames ();
506   registers_changed ();
507   stop_pc = read_pc ();
508   select_frame (get_current_frame (), 0);
509 }
510
511 static void
512 restore_current_thread (pid)
513      int pid;
514 {
515   if (pid != inferior_pid)
516     {
517       switch_to_thread (pid);
518       print_stack_frame (get_current_frame (), 0, -1);
519     }
520 }
521
522 struct current_thread_cleanup
523 {
524   int inferior_pid;
525 };
526
527 static void
528 do_restore_current_thread_cleanup (void *arg)
529 {
530   struct current_thread_cleanup *old = arg;
531   restore_current_thread (old->inferior_pid);
532   free (old);
533 }
534
535 static struct cleanup *
536 make_cleanup_restore_current_thread (int inferior_pid)
537 {
538   struct current_thread_cleanup *old
539     = xmalloc (sizeof (struct current_thread_cleanup));
540   old->inferior_pid = inferior_pid;
541   return make_cleanup (do_restore_current_thread_cleanup, old);
542 }
543
544 /* Apply a GDB command to a list of threads.  List syntax is a whitespace
545    seperated list of numbers, or ranges, or the keyword `all'.  Ranges consist
546    of two numbers seperated by a hyphen.  Examples:
547
548    thread apply 1 2 7 4 backtrace       Apply backtrace cmd to threads 1,2,7,4
549    thread apply 2-7 9 p foo(1)  Apply p foo(1) cmd to threads 2->7 & 9
550    thread apply all p x/i $pc   Apply x/i $pc cmd to all threads
551  */
552
553 static void
554 thread_apply_all_command (cmd, from_tty)
555      char *cmd;
556      int from_tty;
557 {
558   struct thread_info *tp;
559   struct cleanup *old_chain;
560
561   if (cmd == NULL || *cmd == '\000')
562     error ("Please specify a command following the thread ID list");
563
564   old_chain = make_cleanup_restore_current_thread (inferior_pid);
565
566   for (tp = thread_list; tp; tp = tp->next)
567     if (thread_alive (tp))
568       {
569         switch_to_thread (tp->pid);
570 #ifdef HPUXHPPA
571         printf_filtered ("\nThread %d (%s):\n",
572                          tp->num,
573                          target_tid_to_str (inferior_pid));
574 #else
575         printf_filtered ("\nThread %d (%s):\n", tp->num,
576                          target_pid_to_str (inferior_pid));
577 #endif
578         execute_command (cmd, from_tty);
579       }
580
581   do_cleanups (old_chain);
582 }
583
584 static void
585 thread_apply_command (tidlist, from_tty)
586      char *tidlist;
587      int from_tty;
588 {
589   char *cmd;
590   char *p;
591   struct cleanup *old_chain;
592
593   if (tidlist == NULL || *tidlist == '\000')
594     error ("Please specify a thread ID list");
595
596   for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
597
598   if (*cmd == '\000')
599     error ("Please specify a command following the thread ID list");
600
601   old_chain = make_cleanup_restore_current_thread (inferior_pid);
602
603   while (tidlist < cmd)
604     {
605       struct thread_info *tp;
606       int start, end;
607
608       start = strtol (tidlist, &p, 10);
609       if (p == tidlist)
610         error ("Error parsing %s", tidlist);
611       tidlist = p;
612
613       while (*tidlist == ' ' || *tidlist == '\t')
614         tidlist++;
615
616       if (*tidlist == '-')      /* Got a range of IDs? */
617         {
618           tidlist++;            /* Skip the - */
619           end = strtol (tidlist, &p, 10);
620           if (p == tidlist)
621             error ("Error parsing %s", tidlist);
622           tidlist = p;
623
624           while (*tidlist == ' ' || *tidlist == '\t')
625             tidlist++;
626         }
627       else
628         end = start;
629
630       for (; start <= end; start++)
631         {
632           tp = find_thread_id (start);
633
634           if (!tp)
635             warning ("Unknown thread %d.", start);
636           else if (!thread_alive (tp))
637             warning ("Thread %d has terminated.", start);
638           else
639             {
640               switch_to_thread (tp->pid);
641 #ifdef HPUXHPPA
642               printf_filtered ("\nThread %d (%s):\n", tp->num,
643                                target_tid_to_str (inferior_pid));
644 #else
645               printf_filtered ("\nThread %d (%s):\n", tp->num,
646                                target_pid_to_str (inferior_pid));
647 #endif
648               execute_command (cmd, from_tty);
649             }
650         }
651     }
652
653   do_cleanups (old_chain);
654 }
655
656 /* Switch to the specified thread.  Will dispatch off to thread_apply_command
657    if prefix of arg is `apply'.  */
658
659 static void
660 thread_command (tidstr, from_tty)
661      char *tidstr;
662      int from_tty;
663 {
664   if (!tidstr)
665     {
666       /* Don't generate an error, just say which thread is current. */
667       if (target_has_stack)
668         printf_filtered ("[Current thread is %d (%s)]\n",
669                          pid_to_thread_id (inferior_pid),
670 #if defined(HPUXHPPA)
671                          target_tid_to_str (inferior_pid)
672 #else
673                          target_pid_to_str (inferior_pid)
674 #endif
675           );
676       else
677         error ("No stack.");
678       return;
679     }
680
681   gdb_thread_select (tidstr);
682 }
683
684 static int
685 do_captured_thread_select (void *tidstr)
686 {
687   int num;
688   struct thread_info *tp;
689
690   num = atoi ((char *)tidstr);
691
692   tp = find_thread_id (num);
693
694 #ifdef UI_OUT
695   if (!tp)
696     error ("Thread ID %d not known.", num);
697 #else
698   if (!tp)
699     error ("Thread ID %d not known.  Use the \"info threads\" command to\n\
700 see the IDs of currently known threads.", num);
701 #endif
702
703   if (!thread_alive (tp))
704     error ("Thread ID %d has terminated.\n", num);
705
706   switch_to_thread (tp->pid);
707
708 #ifdef UI_OUT
709   ui_out_text (uiout, "[Switching to thread ");
710   ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_pid));
711   ui_out_text (uiout, " (");
712 #if defined(HPUXHPPA)
713   ui_out_text (uiout, target_tid_to_str (inferior_pid));
714 #else
715   ui_out_text (uiout, target_pid_to_str (inferior_pid));
716 #endif
717   ui_out_text (uiout, ")]");
718 #else /* UI_OUT */
719   printf_filtered ("[Switching to thread %d (%s)]\n",
720                    pid_to_thread_id (inferior_pid),
721 #if defined(HPUXHPPA)
722                    target_tid_to_str (inferior_pid)
723 #else
724                    target_pid_to_str (inferior_pid)
725 #endif
726     );
727 #endif /* UI_OUT */
728
729   print_stack_frame (selected_frame, selected_frame_level, 1);
730   return GDB_RC_OK;
731 }
732
733 enum gdb_rc
734 gdb_thread_select (char *tidstr)
735 {
736   return catch_errors (do_captured_thread_select, tidstr,
737                        NULL, RETURN_MASK_ALL);
738 }
739
740 /* Commands with a prefix of `thread'.  */
741 struct cmd_list_element *thread_cmd_list = NULL;
742
743 void
744 _initialize_thread ()
745 {
746   static struct cmd_list_element *thread_apply_list = NULL;
747
748   add_info ("threads", info_threads_command,
749             "IDs of currently known threads.");
750
751   add_prefix_cmd ("thread", class_run, thread_command,
752                   "Use this command to switch between threads.\n\
753 The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1,
754                   &cmdlist);
755
756   add_prefix_cmd ("apply", class_run, thread_apply_command,
757                   "Apply a command to a list of threads.",
758                   &thread_apply_list, "apply ", 1, &thread_cmd_list);
759
760   add_cmd ("all", class_run, thread_apply_all_command,
761            "Apply a command to all threads.",
762            &thread_apply_list);
763
764   if (!xdb_commands)
765     add_com_alias ("t", "thread", class_run, 1);
766 }
This page took 0.065595 seconds and 4 git commands to generate.