1 /* Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
3 This file is part of GDB.
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.
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.
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/>. */
23 #include <sys/procfs.h>
27 #include "gdbthread.h"
29 #include <pthread_debug.h>
31 /* Print debugging traces if set to non-zero. */
32 static int debug_dec_thread
= 0;
34 /* Non-zero if the dec-thread layer is active. */
35 static int dec_thread_active
= 0;
37 /* The pthread_debug context. */
38 pthreadDebugContext_t debug_context
;
40 /* The dec-thread target_ops structure. */
41 static struct target_ops dec_thread_ops
;
43 /* Print a debug trace if DEBUG_DEC_THREAD is set (its value is adjusted
44 by the user using "set debug dec-thread ..."). */
47 debug (char *format
, ...)
53 va_start (args
, format
);
54 printf_unfiltered ("DEC Threads: ");
55 vprintf_unfiltered (format
, args
);
56 printf_unfiltered ("\n");
61 /* pthread debug callbacks. */
64 suspend_clbk (void *caller_context
)
70 resume_clbk (void *caller_context
)
76 hold_clbk (void *caller_context
, pthreadDebugKId_t kernel_tid
)
82 unhold_clbk (void *caller_context
, pthreadDebugKId_t kernel_tid
)
88 read_clbk (void *caller_context
, void *address
, void *buffer
,
91 int status
= target_read_memory ((CORE_ADDR
) address
, buffer
, size
);
100 write_clbk (void *caller_context
, void *address
, void *buffer
,
103 int status
= target_write_memory ((CORE_ADDR
) address
, buffer
, size
);
111 /* Get integer regs. */
114 get_reg_clbk(void *caller_context
, pthreadDebugGetRegRtn_t regs
,
115 pthreadDebugKId_t kernel_tid
)
117 debug ("get_reg_clbk");
119 /* Not sure that we actually need to do anything in this callback. */
123 /* Set integer regs. */
126 set_reg_clbk(void *caller_context
, const pthreadDebugRegs_t
*regs
,
127 pthreadDebugKId_t kernel_tid
)
129 debug ("set_reg_clbk");
131 /* Not sure that we actually need to do anything in this callback. */
136 output_clbk (void *caller_context
, char *line
)
138 printf_filtered ("%s\n", line
);
143 error_clbk (void *caller_context
, char *line
)
145 fprintf_filtered (gdb_stderr
, "%s\n", line
);
149 /* Get floating-point regs. */
152 get_fpreg_clbk (void *caller_context
, pthreadDebugFregs_p fregs
,
153 pthreadDebugKId_t kernel_tid
)
155 debug ("get_fpreg_clbk");
157 /* Not sure that we actually need to do anything in this callback. */
161 /* Set floating-point regs. */
164 set_fpreg_clbk (void *caller_context
, const pthreadDebugFregs_t
*fregs
,
165 pthreadDebugKId_t kernel_tid
)
167 debug ("set_fpreg_clbk");
169 /* Not sure that we actually need to do anything in this callback. */
174 malloc_clbk (void *caller_context
, size_t size
)
176 return xmalloc (size
);
180 free_clbk (void *caller_context
, void *address
)
186 kthdinfo_clbk (pthreadDebugClient_t caller_context
,
187 pthreadDebugKId_t kernel_tid
,
188 pthreadDebugKThreadInfo_p thread_info
)
194 speckthd_clbk (pthreadDebugClient_t caller_context
,
195 pthreadDebugSpecialType_t type
,
196 pthreadDebugKId_t
*kernel_tid
)
201 static pthreadDebugCallbacks_t debug_callbacks
=
203 PTHREAD_DEBUG_VERSION
,
204 (pthreadDebugGetMemRtn_t
) read_clbk
,
205 (pthreadDebugSetMemRtn_t
) write_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
,
222 /* Activate thread support if appropriate. Do nothing if thread
223 support is already active. */
226 enable_dec_thread (void)
228 struct minimal_symbol
*msym
;
229 void* caller_context
;
232 /* If already active, nothing more to do. */
233 if (dec_thread_active
)
236 msym
= lookup_minimal_symbol ("__pthread_dbg_symtable", NULL
, NULL
);
239 debug ("enable_dec_thread: No __pthread_dbg_symtable");
243 status
= pthreadDebugContextInit (&caller_context
, &debug_callbacks
,
244 (void *) SYMBOL_VALUE_ADDRESS (msym
),
246 if (status
!= ESUCCESS
)
248 debug ("enable_dec_thread: pthreadDebugContextInit -> %d",
253 push_target (&dec_thread_ops
);
254 dec_thread_active
= 1;
256 debug ("enable_dec_thread: Thread support enabled.");
259 /* Deactivate thread support. Do nothing if thread support is
263 disable_dec_thread (void)
265 if (!dec_thread_active
)
268 pthreadDebugContextDestroy (debug_context
);
269 unpush_target (&dec_thread_ops
);
270 dec_thread_active
= 0;
273 /* A structure that contains a thread ID and is associated
274 pthreadDebugThreadInfo_t data. */
276 struct dec_thread_info
278 pthreadDebugId_t thread
;
279 pthreadDebugThreadInfo_t info
;
281 typedef struct dec_thread_info dec_thread_info_s
;
283 /* The list of user threads. */
285 DEF_VEC_O (dec_thread_info_s
);
286 VEC(dec_thread_info_s
) *dec_thread_list
;
288 /* Release the memory used by the given VECP thread list pointer.
289 Then set *VECP to NULL. */
292 free_dec_thread_info_vec (VEC(dec_thread_info_s
) **vecp
)
295 struct dec_thread_info
*item
;
296 VEC(dec_thread_info_s
) *vec
= *vecp
;
298 for (i
= 0; VEC_iterate (dec_thread_info_s
, vec
, i
, item
); i
++)
300 VEC_free (dec_thread_info_s
, vec
);
304 /* Return a thread's ptid given its associated INFO. */
307 ptid_build_from_info (struct dec_thread_info info
)
309 int pid
= ptid_get_pid (inferior_ptid
);
311 return ptid_build (pid
, 0, (long) info
.thread
);
314 /* Return non-zero if PTID is still alive.
316 Assumes that DEC_THREAD_LIST is up to date. */
318 dec_thread_ptid_is_alive (ptid_t ptid
)
320 pthreadDebugId_t tid
= ptid_get_tid (ptid
);
322 struct dec_thread_info
*info
;
325 /* This is the thread corresponding to the process. This ptid
326 is always alive until the program exits. */
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
)
338 /* Recompute the list of user threads and store the result in
342 update_dec_thread_list (void)
344 pthreadDebugId_t thread
;
345 pthreadDebugThreadInfo_t info
;
348 free_dec_thread_info_vec (&dec_thread_list
);
349 res
= pthreadDebugThdSeqInit (debug_context
, &thread
);
350 while (res
== ESUCCESS
)
353 res
= pthreadDebugThdGetInfo (debug_context
, thread
, &info
);
355 warning (_("unable to get thread info, ignoring thread %ld"),
357 else if (info
.kind
== PTHREAD_DEBUG_THD_KIND_INITIAL
358 || info
.kind
== PTHREAD_DEBUG_THD_KIND_NORMAL
)
360 struct dec_thread_info
*item
=
361 xmalloc (sizeof (struct dec_thread_info
));
363 item
->thread
= thread
;
365 VEC_safe_push (dec_thread_info_s
, dec_thread_list
, item
);
367 res
= pthreadDebugThdSeqNext (debug_context
, &thread
);
369 pthreadDebugThdSeqDestroy (debug_context
);
372 /* A callback to count the number of threads known to GDB. */
375 dec_thread_count_gdb_threads (struct thread_info
*ignored
, void *context
)
377 int *count
= (int *) context
;
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. */
388 dec_thread_add_gdb_thread (struct thread_info
*info
, void *context
)
390 struct thread_info
***listp
= (struct thread_info
***) context
;
397 /* Implement the find_new_thread target_ops method. */
400 dec_thread_find_new_threads (struct target_ops
*ops
)
403 struct dec_thread_info
*info
;
405 update_dec_thread_list ();
406 for (i
= 0; VEC_iterate (dec_thread_info_s
, dec_thread_list
, i
, info
); i
++)
408 ptid_t ptid
= ptid_build_from_info (*info
);
410 if (!in_thread_list (ptid
))
415 /* Resynchronize the list of threads known by GDB with the actual
416 list of threads reported by libpthread_debug. */
419 resync_thread_list (struct target_ops
*ops
)
422 int num_gdb_threads
= 0;
423 struct thread_info
**gdb_thread_list
;
424 struct thread_info
**next_thread_info
;
426 /* Add new threads. */
427 dec_thread_find_new_threads (ops
);
429 /* Remove threads that no longer exist. To help with the search,
430 we build an array of GDB threads, and then iterate over this
433 iterate_over_threads (dec_thread_count_gdb_threads
,
434 (void *) &num_gdb_threads
);
435 gdb_thread_list
= alloca (num_gdb_threads
* sizeof (struct thread_info
*));
436 next_thread_info
= gdb_thread_list
;
437 iterate_over_threads (dec_thread_add_gdb_thread
, (void *) &next_thread_info
);
439 for (i
= 0; i
< num_gdb_threads
; i
++)
440 if (!dec_thread_ptid_is_alive (gdb_thread_list
[i
]->ptid
))
441 delete_thread (gdb_thread_list
[i
]->ptid
);
444 /* The "to_detach" method of the dec_thread_ops. */
447 dec_thread_detach (struct target_ops
*ops
, char *args
, int from_tty
)
449 struct target_ops
*beneath
= find_target_beneath (ops
);
451 debug ("dec_thread_detach");
453 disable_dec_thread ();
454 beneath
->to_detach (beneath
, args
, from_tty
);
457 /* Return the ptid of the thread that is currently active. */
460 get_active_ptid (void)
463 struct dec_thread_info
*info
;
465 for (i
= 0; VEC_iterate (dec_thread_info_s
, dec_thread_list
, i
, info
);
467 if (info
->info
.state
== PTHREAD_DEBUG_STATE_RUNNING
)
468 return ptid_build_from_info (*info
);
470 /* No active thread found. This can happen when the program
475 /* The "to_wait" method of the dec_thread_ops. */
478 dec_thread_wait (struct target_ops
*ops
,
479 ptid_t ptid
, struct target_waitstatus
*status
, int options
)
482 struct target_ops
*beneath
= find_target_beneath (ops
);
484 debug ("dec_thread_wait");
486 ptid
= beneath
->to_wait (beneath
, ptid
, status
, options
);
488 /* The ptid returned by the target beneath us is the ptid of the process.
489 We need to find which thread is currently active and return its ptid. */
490 resync_thread_list (ops
);
491 active_ptid
= get_active_ptid ();
492 if (ptid_equal (active_ptid
, null_ptid
))
497 /* Fetch the general purpose and floating point registers for the given
498 thread TID, and store the result in GREGSET and FPREGSET. Return
499 zero if successful. */
502 dec_thread_get_regsets (pthreadDebugId_t tid
, gdb_gregset_t
*gregset
,
503 gdb_fpregset_t
*fpregset
)
506 pthreadDebugRegs_t regs
;
507 pthreadDebugFregs_t fregs
;
509 res
= pthreadDebugThdGetReg (debug_context
, tid
, ®s
);
512 debug ("dec_thread_get_regsets: pthreadDebugThdGetReg -> %d", res
);
515 memcpy (gregset
->regs
, ®s
, sizeof (regs
));
517 res
= pthreadDebugThdGetFreg (debug_context
, tid
, &fregs
);
520 debug ("dec_thread_get_regsets: pthreadDebugThdGetFreg -> %d", res
);
523 memcpy (fpregset
->regs
, &fregs
, sizeof (fregs
));
528 /* The "to_fetch_registers" method of the dec_thread_ops.
530 Because the dec-thread debug API doesn't allow us to fetch
531 only one register, we simply ignore regno and fetch+supply all
535 dec_thread_fetch_registers (struct target_ops
*ops
,
536 struct regcache
*regcache
, int regno
)
538 pthreadDebugId_t tid
= ptid_get_tid (inferior_ptid
);
543 debug ("dec_thread_fetch_registers (tid=%ld, regno=%d)", tid
, regno
);
546 if (tid
== 0 || ptid_equal (inferior_ptid
, get_active_ptid ()))
548 struct target_ops
*beneath
= find_target_beneath (ops
);
550 beneath
->to_fetch_registers (beneath
, regcache
, regno
);
554 res
= dec_thread_get_regsets (tid
, &gregset
, &fpregset
);
558 supply_gregset (regcache
, &gregset
);
559 supply_fpregset (regcache
, &fpregset
);
562 /* Store the registers given in GREGSET and FPREGSET into the associated
563 general purpose and floating point registers of thread TID. Return
564 zero if successful. */
567 dec_thread_set_regsets (pthreadDebugId_t tid
, gdb_gregset_t gregset
,
568 gdb_fpregset_t fpregset
)
571 pthreadDebugRegs_t regs
;
572 pthreadDebugFregs_t fregs
;
574 memcpy (®s
, gregset
.regs
, sizeof (regs
));
575 res
= pthreadDebugThdSetReg (debug_context
, tid
, ®s
);
578 debug ("dec_thread_set_regsets: pthreadDebugThdSetReg -> %d", res
);
582 memcpy (&fregs
, fpregset
.regs
, sizeof (fregs
));
583 res
= pthreadDebugThdSetFreg (debug_context
, tid
, &fregs
);
586 debug ("dec_thread_set_regsets: pthreadDebugThdSetFreg -> %d", res
);
593 /* The "to_store_registers" method of the dec_thread_ops.
595 Because the dec-thread debug API doesn't allow us to store
596 just one register, we store all the registers. */
599 dec_thread_store_registers (struct target_ops
*ops
,
600 struct regcache
*regcache
, int regno
)
602 pthreadDebugId_t tid
= ptid_get_tid (inferior_ptid
);
607 debug ("dec_thread_store_registers (tid=%ld, regno=%d)", tid
, regno
);
609 if (tid
== 0 || ptid_equal (inferior_ptid
, get_active_ptid ()))
611 struct target_ops
*beneath
= find_target_beneath (ops
);
613 beneath
->to_store_registers (beneath
, regcache
, regno
);
617 /* FIXME: brobecker/2008-05-28: I wonder if we could simply check
618 in which register set the register is and then only store the
619 registers for that register set, instead of storing both register
621 fill_gregset (regcache
, &gregset
, -1);
622 fill_fpregset (regcache
, &fpregset
, -1);
624 res
= dec_thread_set_regsets (tid
, gregset
, fpregset
);
626 warning (_("failed to store registers."));
629 /* The "to_mourn_inferior" method of the dec_thread_ops. */
632 dec_thread_mourn_inferior (struct target_ops
*ops
)
634 struct target_ops
*beneath
= find_target_beneath (ops
);
636 debug ("dec_thread_mourn_inferior");
638 disable_dec_thread ();
639 beneath
->to_mourn_inferior (beneath
);
642 /* The "to_thread_alive" method of the dec_thread_ops. */
644 dec_thread_thread_alive (struct target_ops
*ops
, ptid_t ptid
)
646 debug ("dec_thread_thread_alive (tid=%ld)", ptid_get_tid (ptid
));
648 /* The thread list maintained by GDB is up to date, since we update
649 it everytime we stop. So check this list. */
650 return in_thread_list (ptid
);
653 /* The "to_pid_to_str" method of the dec_thread_ops. */
656 dec_thread_pid_to_str (struct target_ops
*ops
, ptid_t ptid
)
658 static char *ret
= NULL
;
660 if (ptid_get_tid (ptid
) == 0)
662 struct target_ops
*beneath
= find_target_beneath (ops
);
664 return beneath
->to_pid_to_str (beneath
, ptid
);
667 /* Free previous return value; a new one will be allocated by
671 ret
= xstrprintf (_("Thread %ld"), ptid_get_tid (ptid
));
675 /* A "new-objfile" observer. Used to activate/deactivate dec-thread
679 dec_thread_new_objfile_observer (struct objfile
*objfile
)
682 enable_dec_thread ();
684 disable_dec_thread ();
687 /* The "to_get_ada_task_ptid" method of the dec_thread_ops. */
690 dec_thread_get_ada_task_ptid (long lwp
, long thread
)
693 struct dec_thread_info
*info
;
695 debug ("dec_thread_get_ada_task_ptid (lwp=0x%lx, thread=0x%lx)",
698 for (i
= 0; VEC_iterate (dec_thread_info_s
, dec_thread_list
, i
, info
);
700 if (info
->info
.teb
== (pthread_t
) thread
)
701 return ptid_build_from_info (*info
);
703 warning (_("Could not find thread id from THREAD = 0x%lx\n"), thread
);
704 return inferior_ptid
;
708 init_dec_thread_ops (void)
710 dec_thread_ops
.to_shortname
= "dec-threads";
711 dec_thread_ops
.to_longname
= _("DEC threads support");
712 dec_thread_ops
.to_doc
= _("DEC threads support");
713 dec_thread_ops
.to_detach
= dec_thread_detach
;
714 dec_thread_ops
.to_wait
= dec_thread_wait
;
715 dec_thread_ops
.to_fetch_registers
= dec_thread_fetch_registers
;
716 dec_thread_ops
.to_store_registers
= dec_thread_store_registers
;
717 dec_thread_ops
.to_mourn_inferior
= dec_thread_mourn_inferior
;
718 dec_thread_ops
.to_thread_alive
= dec_thread_thread_alive
;
719 dec_thread_ops
.to_find_new_threads
= dec_thread_find_new_threads
;
720 dec_thread_ops
.to_pid_to_str
= dec_thread_pid_to_str
;
721 dec_thread_ops
.to_stratum
= thread_stratum
;
722 dec_thread_ops
.to_get_ada_task_ptid
= dec_thread_get_ada_task_ptid
;
723 dec_thread_ops
.to_magic
= OPS_MAGIC
;
727 _initialize_dec_thread (void)
729 init_dec_thread_ops ();
730 add_target (&dec_thread_ops
);
732 observer_attach_new_objfile (dec_thread_new_objfile_observer
);
734 add_setshow_boolean_cmd ("dec-thread", class_maintenance
, &debug_dec_thread
,
735 _("Set debugging of DEC threads module."),
736 _("Show debugging of DEC threads module."),
737 _("Enables debugging output (used to debug GDB)."),
739 &setdebuglist
, &showdebuglist
);