]> Git Repo - binutils.git/blob - gdb/dec-thread.c
Push pruning old threads down to the target
[binutils.git] / gdb / dec-thread.c
1 /* Copyright (C) 2008-2014 Free Software Foundation, Inc.
2
3    This file is part of GDB.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 #include "defs.h"
19 #include "command.h"
20 #include "gdbcmd.h"
21 #include "target.h"
22 #include "observer.h"
23 #include <sys/procfs.h>
24 #include "gregset.h"
25 #include "regcache.h"
26 #include "inferior.h"
27 #include "gdbthread.h"
28
29 #include <pthread_debug.h>
30
31 /* Print debugging traces if set to non-zero.  */
32 static int debug_dec_thread = 0;
33
34 /* Non-zero if the dec-thread layer is active.  */
35 static int dec_thread_active = 0;
36
37 /* The pthread_debug context.  */
38 pthreadDebugContext_t debug_context;
39
40 /* The dec-thread target_ops structure.  */
41 static struct target_ops dec_thread_ops;
42
43 /* Print a debug trace if DEBUG_DEC_THREAD is set (its value is adjusted
44    by the user using "set debug dec-thread ...").  */
45
46 static void
47 debug (char *format, ...)
48 {
49   if (debug_dec_thread)
50     {
51       va_list args;
52
53       va_start (args, format);
54       printf_unfiltered ("DEC Threads: ");
55       vprintf_unfiltered (format, args);
56       printf_unfiltered ("\n");
57       va_end (args);
58     }
59 }
60
61 /* pthread debug callbacks.  */
62
63 static int
64 suspend_clbk (void *caller_context)
65 {
66   return ESUCCESS;
67 }
68
69 static int
70 resume_clbk (void *caller_context)
71 {
72   return ESUCCESS;
73
74
75 static int
76 hold_clbk (void *caller_context, pthreadDebugKId_t kernel_tid)
77
78   return ESUCCESS;
79 }
80
81 static int
82 unhold_clbk (void *caller_context, pthreadDebugKId_t kernel_tid)
83 {
84   return ESUCCESS;
85 }
86
87 static int
88 read_clbk (void *caller_context, void *address, void *buffer,
89            unsigned long size)
90 {
91   int status = target_read_memory ((CORE_ADDR) address, buffer, size);
92
93   if (status != 0)
94     return EINVAL;
95
96   return ESUCCESS;
97 }
98
99 static int
100 write_clbk (void *caller_context, void *address, void *buffer,
101             unsigned long size)
102 {
103   int status = target_write_memory ((CORE_ADDR) address, buffer, size);
104   
105   if (status != 0)
106     return EINVAL;
107
108   return ESUCCESS;
109 }
110
111 /* Get integer regs.  */
112
113 static int
114 get_reg_clbk(void *caller_context, pthreadDebugGetRegRtn_t regs,
115              pthreadDebugKId_t kernel_tid)
116 {
117   debug ("get_reg_clbk");
118
119   /* Not sure that we actually need to do anything in this callback.  */
120   return ESUCCESS;
121 }
122
123 /* Set integer regs.  */
124
125 static int
126 set_reg_clbk(void *caller_context, const pthreadDebugRegs_t *regs,
127              pthreadDebugKId_t kernel_tid)
128 {
129   debug ("set_reg_clbk");
130
131   /* Not sure that we actually need to do anything in this callback.  */
132   return ESUCCESS;
133 }
134
135 static int
136 output_clbk (void *caller_context, char *line)
137 {
138   printf_filtered ("%s\n", line);
139   return ESUCCESS;
140 }
141
142 static int
143 error_clbk (void *caller_context, char *line)
144 {
145   fprintf_filtered (gdb_stderr, "%s\n", line);
146   return ESUCCESS;
147 }
148
149 /* Get floating-point regs.  */
150
151 static int
152 get_fpreg_clbk (void *caller_context, pthreadDebugFregs_p fregs,
153                 pthreadDebugKId_t kernel_tid)
154 {
155   debug ("get_fpreg_clbk");
156
157   /* Not sure that we actually need to do anything in this callback.  */
158   return ESUCCESS;
159 }
160
161 /* Set floating-point regs.  */
162
163 static int
164 set_fpreg_clbk (void *caller_context, const pthreadDebugFregs_t *fregs,
165                 pthreadDebugKId_t kernel_tid)
166 {
167   debug ("set_fpreg_clbk");
168
169   /* Not sure that we actually need to do anything in this callback.  */
170   return ESUCCESS;
171 }
172
173 static void *
174 malloc_clbk (void *caller_context, size_t size)
175 {
176   return xmalloc (size);
177 }
178
179 static void
180 free_clbk (void *caller_context, void *address)
181 {
182   xfree (address);
183 }
184
185 static int
186 kthdinfo_clbk (pthreadDebugClient_t caller_context,
187                pthreadDebugKId_t kernel_tid,
188                pthreadDebugKThreadInfo_p thread_info)
189 {
190   return ENOTSUP;
191 }
192
193 static int
194 speckthd_clbk (pthreadDebugClient_t caller_context,
195                pthreadDebugSpecialType_t type,
196                pthreadDebugKId_t *kernel_tid)
197 {
198   return ENOTSUP;
199 }
200
201 static pthreadDebugCallbacks_t debug_callbacks =
202 {
203   PTHREAD_DEBUG_VERSION,
204   (pthreadDebugGetMemRtn_t) read_clbk,
205   (pthreadDebugSetMemRtn_t) write_clbk,
206   suspend_clbk,
207   resume_clbk,
208   kthdinfo_clbk,
209   hold_clbk,
210   unhold_clbk,
211   (pthreadDebugGetFregRtn_t) get_fpreg_clbk,
212   (pthreadDebugSetFregRtn_t) set_fpreg_clbk,
213   (pthreadDebugGetRegRtn_t) get_reg_clbk,
214   (pthreadDebugSetRegRtn_t) set_reg_clbk,
215   (pthreadDebugOutputRtn_t) output_clbk,
216   (pthreadDebugOutputRtn_t) error_clbk,
217   malloc_clbk,
218   free_clbk,
219   speckthd_clbk
220 };
221
222 /* Activate thread support if appropriate.  Do nothing if thread
223    support is already active.  */
224
225 static void
226 enable_dec_thread (void)
227 {
228   struct bound_minimal_symbol msym;
229   void* caller_context;
230   int status;
231
232   /* If already active, nothing more to do.  */
233   if (dec_thread_active)
234     return;
235
236   msym = lookup_minimal_symbol ("__pthread_dbg_symtable", NULL, NULL);
237   if (msym.minsym == NULL)
238     {
239       debug ("enable_dec_thread: No __pthread_dbg_symtable");
240       return;
241     }
242
243   status = pthreadDebugContextInit (&caller_context, &debug_callbacks,
244                                     (void *) SYMBOL_VALUE_ADDRESS (msym.minsym),
245                                     &debug_context);
246   if (status != ESUCCESS)
247     {
248       debug ("enable_dec_thread: pthreadDebugContextInit -> %d",
249              status);
250       return;
251     }
252
253   push_target (&dec_thread_ops);
254   dec_thread_active = 1;
255
256   debug ("enable_dec_thread: Thread support enabled.");
257 }
258
259 /* Deactivate thread support.  Do nothing if thread support is
260    already inactive.  */
261
262 static void
263 disable_dec_thread (void)
264 {
265   if (!dec_thread_active)
266     return;
267
268   pthreadDebugContextDestroy (debug_context);
269   unpush_target (&dec_thread_ops);
270   dec_thread_active = 0;
271 }
272
273 /* A structure that contains a thread ID and is associated
274    pthreadDebugThreadInfo_t data.  */
275
276 struct dec_thread_info
277 {
278   pthreadDebugId_t thread;
279   pthreadDebugThreadInfo_t info;
280 };
281 typedef struct dec_thread_info dec_thread_info_s;
282
283 /* The list of user threads.  */
284
285 DEF_VEC_O (dec_thread_info_s);
286 VEC(dec_thread_info_s) *dec_thread_list;
287
288 /* Release the memory used by the given VECP thread list pointer.
289    Then set *VECP to NULL.  */
290
291 static void
292 free_dec_thread_info_vec (VEC(dec_thread_info_s) **vecp)
293 {
294   int i;
295   struct dec_thread_info *item;
296   VEC(dec_thread_info_s) *vec = *vecp;
297
298   for (i = 0; VEC_iterate (dec_thread_info_s, vec, i, item); i++)
299      xfree (item);
300   VEC_free (dec_thread_info_s, vec);
301   *vecp = NULL;
302 }
303
304 /* Return a thread's ptid given its associated INFO.  */
305
306 static ptid_t
307 ptid_build_from_info (struct dec_thread_info info)
308 {
309   int pid = ptid_get_pid (inferior_ptid);
310
311   return ptid_build (pid, 0, (long) info.thread);
312 }
313
314 /* Return non-zero if PTID is still alive.
315
316    Assumes that DEC_THREAD_LIST is up to date.  */
317 static int
318 dec_thread_ptid_is_alive (ptid_t ptid)
319 {
320   pthreadDebugId_t tid = ptid_get_tid (ptid);
321   int i;
322   struct dec_thread_info *info;
323
324   if (tid == 0)
325     /* This is the thread corresponding to the process.  This ptid
326        is always alive until the program exits.  */
327     return 1;
328
329   /* Search whether an entry with the same tid exists in the dec-thread
330      list of threads.  If it does, then the thread is still alive.
331      No match found means that the thread must be dead, now.  */
332   for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info); i++)
333     if (info->thread == tid)
334       return 1;
335   return 0;
336 }
337
338 /* Recompute the list of user threads and store the result in
339    DEC_THREAD_LIST.  */
340
341 static void
342 update_dec_thread_list (void)
343 {
344   pthreadDebugId_t thread;
345   pthreadDebugThreadInfo_t info;
346   int res;
347
348   free_dec_thread_info_vec (&dec_thread_list);
349   res = pthreadDebugThdSeqInit (debug_context, &thread);
350   while (res == ESUCCESS)
351     {
352
353       res = pthreadDebugThdGetInfo (debug_context, thread, &info);
354       if (res != ESUCCESS)
355         warning (_("unable to get thread info, ignoring thread %ld"),
356                    thread);
357       else if (info.kind == PTHREAD_DEBUG_THD_KIND_INITIAL
358                || info.kind == PTHREAD_DEBUG_THD_KIND_NORMAL)
359         {
360           struct dec_thread_info *item = 
361             xmalloc (sizeof (struct dec_thread_info));
362
363           item->thread = thread;
364           item->info = info;
365           VEC_safe_push (dec_thread_info_s, dec_thread_list, item);
366         }
367       res = pthreadDebugThdSeqNext (debug_context, &thread);
368     }
369   pthreadDebugThdSeqDestroy (debug_context);
370 }
371
372 /* A callback to count the number of threads known to GDB.  */
373
374 static int
375 dec_thread_count_gdb_threads (struct thread_info *ignored, void *context)
376 {
377   int *count = (int *) context;
378
379   *count = *count + 1;
380   return 0;
381 }
382
383 /* A callback that saves the given thread INFO at the end of an
384    array.  The end of the array is given in the CONTEXT and is
385    incremented once the info has been added.  */
386
387 static int
388 dec_thread_add_gdb_thread (struct thread_info *info, void *context)
389 {
390   struct thread_info ***listp = (struct thread_info ***) context;
391   
392   **listp = info;
393   *listp = *listp + 1;
394   return 0;
395 }
396
397 /* Find new threads.  */
398
399 static void
400 dec_thread_find_new_threads (struct target_ops *ops)
401 {
402   int i;
403   struct dec_thread_info *info;
404
405   update_dec_thread_list ();
406   for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info); i++)
407     {
408       ptid_t ptid = ptid_build_from_info (*info);
409
410       if (!in_thread_list (ptid))
411         add_thread (ptid);
412     }
413 }
414
415 /* Implement the update_thread_list target_ops method.  */
416
417 static void
418 dec_thread_update_thread_list (struct target_ops *ops)
419 {
420   int i;
421   struct dec_thread_info *info;
422
423   /* Delete dead threads.  */
424   prune_threads ();
425
426   /* Now find new threads.  */
427   dec_thread_find_new_threads (ops);
428 }
429
430 /* Resynchronize the list of threads known by GDB with the actual
431    list of threads reported by libpthread_debug.  */
432
433 static void
434 resync_thread_list (struct target_ops *ops)
435 {
436   int i;
437   int num_gdb_threads = 0;
438   struct thread_info **gdb_thread_list;
439   struct thread_info **next_thread_info;
440
441   /* Add new threads.  */
442   dec_thread_find_new_threads (ops);
443
444   /* Remove threads that no longer exist.  To help with the search,
445      we build an array of GDB threads, and then iterate over this
446      array.  */
447
448   iterate_over_threads (dec_thread_count_gdb_threads,
449                         (void *) &num_gdb_threads);
450   gdb_thread_list = alloca (num_gdb_threads * sizeof (struct thread_info *));
451   next_thread_info = gdb_thread_list;
452   iterate_over_threads (dec_thread_add_gdb_thread, (void *) &next_thread_info);
453
454   for (i = 0; i < num_gdb_threads; i++)
455     if (!dec_thread_ptid_is_alive (gdb_thread_list[i]->ptid))
456       delete_thread (gdb_thread_list[i]->ptid);
457 }
458
459 /* The "to_detach" method of the dec_thread_ops.  */
460
461 static void
462 dec_thread_detach (struct target_ops *ops, const char *args, int from_tty)
463 {   
464   struct target_ops *beneath = find_target_beneath (ops);
465
466   debug ("dec_thread_detach");
467
468   disable_dec_thread ();
469   beneath->to_detach (beneath, args, from_tty);
470 }
471
472 /* Return the ptid of the thread that is currently active.  */
473
474 static ptid_t
475 get_active_ptid (void)
476 {
477   int i;
478   struct dec_thread_info *info;
479
480   for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
481        i++)
482     if (info->info.state == PTHREAD_DEBUG_STATE_RUNNING)
483       return ptid_build_from_info (*info);
484
485   /* No active thread found.  This can happen when the program
486      has just exited.  */
487   return null_ptid;
488 }
489
490 /* The "to_wait" method of the dec_thread_ops.  */
491
492 static ptid_t
493 dec_thread_wait (struct target_ops *ops,
494                  ptid_t ptid, struct target_waitstatus *status, int options)
495 {
496   ptid_t active_ptid;
497   struct target_ops *beneath = find_target_beneath (ops);
498
499   debug ("dec_thread_wait");
500
501   ptid = beneath->to_wait (beneath, ptid, status, options);
502
503   /* The ptid returned by the target beneath us is the ptid of the process.
504      We need to find which thread is currently active and return its ptid.  */
505   resync_thread_list (ops);
506   active_ptid = get_active_ptid ();
507   if (ptid_equal (active_ptid, null_ptid))
508     return ptid;
509   return active_ptid;
510 }
511
512 /* Fetch the general purpose and floating point registers for the given
513    thread TID, and store the result in GREGSET and FPREGSET.  Return
514    zero if successful.  */
515
516 static int
517 dec_thread_get_regsets (pthreadDebugId_t tid, gdb_gregset_t *gregset,
518                         gdb_fpregset_t *fpregset)
519 {
520   int res;
521   pthreadDebugRegs_t regs;
522   pthreadDebugFregs_t fregs;
523
524   res = pthreadDebugThdGetReg (debug_context, tid, &regs);
525   if (res != ESUCCESS)
526     {
527       debug ("dec_thread_get_regsets: pthreadDebugThdGetReg -> %d", res);
528       return -1;
529     }
530   memcpy (gregset->regs, &regs, sizeof (regs));
531
532   res = pthreadDebugThdGetFreg (debug_context, tid, &fregs);
533   if (res != ESUCCESS)
534     {
535       debug ("dec_thread_get_regsets: pthreadDebugThdGetFreg -> %d", res);
536       return -1;
537     }
538   memcpy (fpregset->regs, &fregs, sizeof (fregs));
539
540   return 0;
541 }
542
543 /* The "to_fetch_registers" method of the dec_thread_ops.
544
545    Because the dec-thread debug API doesn't allow us to fetch
546    only one register, we simply ignore regno and fetch+supply all
547    registers.  */
548
549 static void
550 dec_thread_fetch_registers (struct target_ops *ops,
551                             struct regcache *regcache, int regno)
552 {
553   pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
554   gregset_t gregset;
555   fpregset_t fpregset;
556   int res;
557
558   debug ("dec_thread_fetch_registers (tid=%ld, regno=%d)", tid, regno);
559
560
561   if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
562     {
563       struct target_ops *beneath = find_target_beneath (ops);
564
565       beneath->to_fetch_registers (beneath, regcache, regno);
566       return;
567     }
568
569   res = dec_thread_get_regsets (tid, &gregset, &fpregset);
570   if (res != 0)
571     return;
572
573   supply_gregset (regcache, &gregset);
574   supply_fpregset (regcache, &fpregset);
575 }
576
577 /* Store the registers given in GREGSET and FPREGSET into the associated
578    general purpose and floating point registers of thread TID.  Return
579    zero if successful.  */
580
581 static int
582 dec_thread_set_regsets (pthreadDebugId_t tid, gdb_gregset_t gregset,
583                         gdb_fpregset_t fpregset)
584 {
585   int res;
586   pthreadDebugRegs_t regs;
587   pthreadDebugFregs_t fregs;
588
589   memcpy (&regs, gregset.regs, sizeof (regs));
590   res = pthreadDebugThdSetReg (debug_context, tid, &regs);
591   if (res != ESUCCESS)
592     {
593       debug ("dec_thread_set_regsets: pthreadDebugThdSetReg -> %d", res);
594       return -1;
595     }
596
597   memcpy (&fregs, fpregset.regs, sizeof (fregs));
598   res = pthreadDebugThdSetFreg (debug_context, tid, &fregs);
599   if (res != ESUCCESS)
600     {
601       debug ("dec_thread_set_regsets: pthreadDebugThdSetFreg -> %d", res);
602       return -1;
603     }
604
605   return 0;
606 }
607
608 /* The "to_store_registers" method of the dec_thread_ops.
609
610    Because the dec-thread debug API doesn't allow us to store
611    just one register, we store all the registers.  */
612
613 static void
614 dec_thread_store_registers (struct target_ops *ops,
615                             struct regcache *regcache, int regno)
616 {
617   pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
618   gregset_t gregset;
619   fpregset_t fpregset;
620   int res;
621
622   debug ("dec_thread_store_registers (tid=%ld, regno=%d)", tid, regno);
623
624   if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
625     {
626       struct target_ops *beneath = find_target_beneath (ops);
627
628       beneath->to_store_registers (beneath, regcache, regno);
629       return;
630     }
631
632   /* FIXME: brobecker/2008-05-28: I wonder if we could simply check
633      in which register set the register is and then only store the
634      registers for that register set, instead of storing both register
635      sets.  */
636   fill_gregset (regcache, &gregset, -1);
637   fill_fpregset (regcache, &fpregset, -1);
638   
639   res = dec_thread_set_regsets (tid, gregset, fpregset);
640   if (res != 0)
641     warning (_("failed to store registers."));
642 }
643
644 /* The "to_mourn_inferior" method of the dec_thread_ops.  */
645
646 static void
647 dec_thread_mourn_inferior (struct target_ops *ops)
648 {
649   struct target_ops *beneath = find_target_beneath (ops);
650
651   debug ("dec_thread_mourn_inferior");
652
653   disable_dec_thread ();
654   beneath->to_mourn_inferior (beneath);
655 }
656
657 /* The "to_thread_alive" method of the dec_thread_ops.  */
658 static int
659 dec_thread_thread_alive (struct target_ops *ops, ptid_t ptid)
660 {
661   debug ("dec_thread_thread_alive (tid=%ld)", ptid_get_tid (ptid));
662
663   /* The thread list maintained by GDB is up to date, since we update
664      it everytime we stop.   So check this list.  */
665   return in_thread_list (ptid);
666 }
667
668 /* The "to_pid_to_str" method of the dec_thread_ops.  */
669
670 static char *
671 dec_thread_pid_to_str (struct target_ops *ops, ptid_t ptid)
672 {
673   static char *ret = NULL;
674
675   if (ptid_get_tid (ptid) == 0)
676     {
677       struct target_ops *beneath = find_target_beneath (ops);
678
679       return beneath->to_pid_to_str (beneath, ptid);
680     }
681
682   /* Free previous return value; a new one will be allocated by
683      xstrprintf().  */
684   xfree (ret);
685
686   ret = xstrprintf (_("Thread %ld"), ptid_get_tid (ptid));
687   return ret;
688 }
689
690 /* A "new-objfile" observer.  Used to activate/deactivate dec-thread
691    support.  */
692
693 static void
694 dec_thread_new_objfile_observer (struct objfile *objfile)
695 {
696   if (objfile != NULL)
697      enable_dec_thread ();
698   else
699      disable_dec_thread ();
700 }
701
702 /* The "to_get_ada_task_ptid" method of the dec_thread_ops.  */
703
704 static ptid_t
705 dec_thread_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
706 {
707   int i;
708   struct dec_thread_info *info;
709
710   debug ("dec_thread_get_ada_task_ptid (struct target_ops *self,"
711          " lwp=0x%lx, thread=0x%lx)",
712          lwp, thread);
713
714   for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
715        i++)
716     if (info->info.teb == (pthread_t) thread)
717       return ptid_build_from_info (*info);
718
719   warning (_("Could not find thread id from THREAD = 0x%lx"), thread);
720   return inferior_ptid;
721 }
722
723 static void
724 init_dec_thread_ops (void)
725 {
726   dec_thread_ops.to_shortname          = "dec-threads";
727   dec_thread_ops.to_longname           = _("DEC threads support");
728   dec_thread_ops.to_doc                = _("DEC threads support");
729   dec_thread_ops.to_detach             = dec_thread_detach;
730   dec_thread_ops.to_wait               = dec_thread_wait;
731   dec_thread_ops.to_fetch_registers    = dec_thread_fetch_registers;
732   dec_thread_ops.to_store_registers    = dec_thread_store_registers;
733   dec_thread_ops.to_mourn_inferior     = dec_thread_mourn_inferior;
734   dec_thread_ops.to_thread_alive       = dec_thread_thread_alive;
735   dec_thread_ops.to_update_thread_list = dec_thread_update_thread_list;
736   dec_thread_ops.to_pid_to_str         = dec_thread_pid_to_str;
737   dec_thread_ops.to_stratum            = thread_stratum;
738   dec_thread_ops.to_get_ada_task_ptid  = dec_thread_get_ada_task_ptid;
739   dec_thread_ops.to_magic              = OPS_MAGIC;
740 }
741
742 void
743 _initialize_dec_thread (void)
744 {
745   init_dec_thread_ops ();
746   complete_target_initialization (&dec_thread_ops);
747
748   observer_attach_new_objfile (dec_thread_new_objfile_observer);
749
750   add_setshow_boolean_cmd ("dec-thread", class_maintenance, &debug_dec_thread,
751                             _("Set debugging of DEC threads module."),
752                             _("Show debugging of DEC threads module."),
753                             _("Enables debugging output (used to debug GDB)."),
754                             NULL, NULL,
755                             &setdebuglist, &showdebuglist);
756 }
This page took 0.065558 seconds and 4 git commands to generate.