1 /* Copyright (C) 2008, 2009 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 /* A copy of the target_ops over which our dec_thread_ops is pushed. */
44 static struct target_ops base_target;
46 /* Print a debug trace if DEBUG_DEC_THREAD is set (its value is adjusted
47 by the user using "set debug dec-thread ..."). */
50 debug (char *format, ...)
56 va_start (args, format);
57 printf_unfiltered ("DEC Threads: ");
58 vprintf_unfiltered (format, args);
59 printf_unfiltered ("\n");
64 /* pthread debug callbacks. */
67 suspend_clbk (void *caller_context)
73 resume_clbk (void *caller_context)
79 hold_clbk (void *caller_context, pthreadDebugKId_t kernel_tid)
85 unhold_clbk (void *caller_context, pthreadDebugKId_t kernel_tid)
91 read_clbk (void *caller_context, void *address, void *buffer,
94 int status = target_read_memory ((CORE_ADDR) address, buffer, size);
103 write_clbk (void *caller_context, void *address, void *buffer,
106 int status = target_write_memory ((CORE_ADDR) address, buffer, size);
114 /* Get integer regs */
117 get_reg_clbk(void *caller_context, pthreadDebugGetRegRtn_t regs,
118 pthreadDebugKId_t kernel_tid)
120 debug ("get_reg_clbk");
122 /* Not sure that we actually need to do anything in this callback. */
126 /* Set integer regs */
129 set_reg_clbk(void *caller_context, const pthreadDebugRegs_t *regs,
130 pthreadDebugKId_t kernel_tid)
132 debug ("set_reg_clbk");
134 /* Not sure that we actually need to do anything in this callback. */
139 output_clbk (void *caller_context, char *line)
141 printf_filtered ("%s\n", line);
146 error_clbk (void *caller_context, char *line)
148 fprintf_filtered (gdb_stderr, "%s\n", line);
152 /* Get floating-point regs. */
155 get_fpreg_clbk (void *caller_context, pthreadDebugFregs_p fregs,
156 pthreadDebugKId_t kernel_tid)
158 debug ("get_fpreg_clbk");
160 /* Not sure that we actually need to do anything in this callback. */
164 /* Set floating-point regs. */
167 set_fpreg_clbk (void *caller_context, const pthreadDebugFregs_t *fregs,
168 pthreadDebugKId_t kernel_tid)
170 debug ("set_fpreg_clbk");
172 /* Not sure that we actually need to do anything in this callback. */
177 malloc_clbk (void *caller_context, size_t size)
179 return xmalloc (size);
183 free_clbk (void *caller_context, void *address)
189 kthdinfo_clbk (pthreadDebugClient_t caller_context,
190 pthreadDebugKId_t kernel_tid,
191 pthreadDebugKThreadInfo_p thread_info)
197 speckthd_clbk (pthreadDebugClient_t caller_context,
198 pthreadDebugSpecialType_t type,
199 pthreadDebugKId_t *kernel_tid)
204 static pthreadDebugCallbacks_t debug_callbacks =
206 PTHREAD_DEBUG_VERSION,
207 (pthreadDebugGetMemRtn_t) read_clbk,
208 (pthreadDebugSetMemRtn_t) write_clbk,
214 (pthreadDebugGetFregRtn_t) get_fpreg_clbk,
215 (pthreadDebugSetFregRtn_t) set_fpreg_clbk,
216 (pthreadDebugGetRegRtn_t) get_reg_clbk,
217 (pthreadDebugSetRegRtn_t) set_reg_clbk,
218 (pthreadDebugOutputRtn_t) output_clbk,
219 (pthreadDebugOutputRtn_t) error_clbk,
225 /* Activate thread support if appropriate. Do nothing if thread
226 support is already active. */
229 enable_dec_thread (void)
231 struct minimal_symbol *msym;
232 void* caller_context;
235 /* If already active, nothing more to do. */
236 if (dec_thread_active)
239 msym = lookup_minimal_symbol ("__pthread_dbg_symtable", NULL, NULL);
242 debug ("enable_dec_thread: No __pthread_dbg_symtable");
246 status = pthreadDebugContextInit (&caller_context, &debug_callbacks,
247 (void *) SYMBOL_VALUE_ADDRESS (msym),
249 if (status != ESUCCESS)
251 debug ("enable_dec_thread: pthreadDebugContextInit -> %d",
256 base_target = current_target;
257 push_target (&dec_thread_ops);
258 dec_thread_active = 1;
260 debug ("enable_dec_thread: Thread support enabled.");
263 /* Deactivate thread support. Do nothing is thread support is
267 disable_dec_thread (void)
269 if (!dec_thread_active)
272 pthreadDebugContextDestroy (debug_context);
273 unpush_target (&dec_thread_ops);
274 dec_thread_active = 0;
277 /* A structure that contains a thread ID and is associated
278 pthreadDebugThreadInfo_t data. */
280 struct dec_thread_info
282 pthreadDebugId_t thread;
283 pthreadDebugThreadInfo_t info;
285 typedef struct dec_thread_info dec_thread_info_s;
287 /* The list of user threads. */
289 DEF_VEC_O (dec_thread_info_s);
290 VEC(dec_thread_info_s) *dec_thread_list;
292 /* Release the memory used by the given VECP thread list pointer.
293 Then set *VECP to NULL. */
296 free_dec_thread_info_vec (VEC(dec_thread_info_s) **vecp)
299 struct dec_thread_info *item;
300 VEC(dec_thread_info_s) *vec = *vecp;
302 for (i = 0; VEC_iterate (dec_thread_info_s, vec, i, item); i++)
304 VEC_free (dec_thread_info_s, vec);
308 /* Return a thread's ptid given its associated INFO. */
311 ptid_build_from_info (struct dec_thread_info info)
313 int pid = ptid_get_pid (inferior_ptid);
315 return ptid_build (pid, 0, (long) info.thread);
318 /* Recompute the list of user threads and store the result in
322 update_dec_thread_list (void)
324 pthreadDebugId_t thread;
325 pthreadDebugThreadInfo_t info;
328 free_dec_thread_info_vec (&dec_thread_list);
329 res = pthreadDebugThdSeqInit (debug_context, &thread);
330 while (res == ESUCCESS)
333 res = pthreadDebugThdGetInfo (debug_context, thread, &info);
335 warning (_("unable to get thread info, ignoring thread %ld"),
337 else if (info.kind == PTHREAD_DEBUG_THD_KIND_INITIAL
338 || info.kind == PTHREAD_DEBUG_THD_KIND_NORMAL)
340 struct dec_thread_info *item =
341 xmalloc (sizeof (struct dec_thread_info));
343 item->thread = thread;
345 VEC_safe_push (dec_thread_info_s, dec_thread_list, item);
347 res = pthreadDebugThdSeqNext (debug_context, &thread);
349 pthreadDebugThdSeqDestroy (debug_context);
352 /* A callback to count the number of threads known to GDB. */
355 dec_thread_count_gdb_threads (struct thread_info *ignored, void *context)
357 int *count = (int *) context;
363 /* A callback that saves the given thread INFO at the end of an
364 array. The end of the array is given in the CONTEXT and is
365 incremented once the info has been added. */
368 dec_thread_add_gdb_thread (struct thread_info *info, void *context)
370 struct thread_info ***listp = (struct thread_info ***) context;
377 /* Resynchronize the list of threads known by GDB with the actual
378 list of threads reported by libpthread_debug. */
381 resync_thread_list (void)
384 struct dec_thread_info *info;
385 int num_gdb_threads = 0;
386 struct thread_info **gdb_thread_list;
387 struct thread_info **next_thread_info;
389 update_dec_thread_list ();
391 /* Add new threads. */
393 for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
396 ptid_t ptid = ptid_build_from_info (*info);
398 if (!in_thread_list (ptid))
402 /* Remove threads that no longer exist. To help with the search,
403 we build an array of GDB threads, and then iterate over this
406 iterate_over_threads (dec_thread_count_gdb_threads,
407 (void *) &num_gdb_threads);
408 gdb_thread_list = alloca (num_gdb_threads * sizeof (struct thread_info *));
409 next_thread_info = gdb_thread_list;
410 iterate_over_threads (dec_thread_add_gdb_thread, (void *) &next_thread_info);
411 for (i = 0; i < num_gdb_threads; i++)
415 for (j = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, j, info);
417 if (ptid_equal (gdb_thread_list[i]->ptid,
418 ptid_build_from_info (*info)))
420 delete_thread (gdb_thread_list[i]->ptid);
424 /* The "to_detach" method of the dec_thread_ops. */
427 dec_thread_detach (char *args, int from_tty)
429 debug ("dec_thread_detach");
431 disable_dec_thread ();
432 base_target.to_detach (&base_target, args, from_tty);
435 /* Return the ptid of the thread that is currently active. */
438 get_active_ptid (void)
441 struct dec_thread_info *info;
443 for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
445 if (info->info.state == PTHREAD_DEBUG_STATE_RUNNING)
446 return ptid_build_from_info (*info);
448 /* No active thread found. This can happen when the program
453 /* The "to_wait" method of the dec_thread_ops. */
456 dec_thread_wait (struct target_ops *ops,
457 ptid_t ptid, struct target_waitstatus *status)
461 debug ("dec_thread_wait");
463 ptid = base_target.to_wait (&base_target, ptid, status);
465 /* The ptid returned by the base_target is the ptid of the process.
466 We need to find which thread is currently active and return its
468 resync_thread_list ();
469 active_ptid = get_active_ptid ();
470 if (ptid_equal (active_ptid, null_ptid))
475 /* Fetch the general purpose and floating point registers for the given
476 thread TID, and store the result in GREGSET and FPREGSET. Return
477 zero if successful. */
480 dec_thread_get_regsets (pthreadDebugId_t tid, gdb_gregset_t *gregset,
481 gdb_fpregset_t *fpregset)
484 pthreadDebugRegs_t regs;
485 pthreadDebugFregs_t fregs;
487 res = pthreadDebugThdGetReg (debug_context, tid, ®s);
490 debug ("dec_thread_fetch_registers: pthreadDebugThdGetReg -> %d", res);
493 memcpy (gregset->regs, ®s, sizeof (regs));
495 res = pthreadDebugThdGetFreg (debug_context, tid, &fregs);
498 debug ("dec_thread_fetch_registers: pthreadDebugThdGetFreg -> %d", res);
501 memcpy (fpregset->regs, &fregs, sizeof (fregs));
506 /* The "to_fetch_registers" method of the dec_thread_ops.
508 Because the dec-thread debug API doesn't allow us to fetch
509 only one register, we simply ignore regno and fetch+supply all
513 dec_thread_fetch_registers (struct regcache *regcache, int regno)
515 pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
520 debug ("dec_thread_fetch_registers (tid=%ld, regno=%d)", tid, regno);
523 if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
525 base_target.to_fetch_registers (regcache, regno);
529 res = dec_thread_get_regsets (tid, &gregset, &fpregset);
533 supply_gregset (regcache, &gregset);
534 supply_fpregset (regcache, &fpregset);
537 /* Store the registers given in GREGSET and FPREGSET into the associated
538 general purpose and floating point registers of thread TID. Return
539 zero if successful. */
542 dec_thread_set_regsets (pthreadDebugId_t tid, gdb_gregset_t gregset,
543 gdb_fpregset_t fpregset)
546 pthreadDebugRegs_t regs;
547 pthreadDebugFregs_t fregs;
549 memcpy (®s, gregset.regs, sizeof (regs));
550 res = pthreadDebugThdSetReg (debug_context, tid, ®s);
553 debug ("dec_thread_fetch_registers: pthreadDebugThdSetReg -> %d", res);
557 memcpy (&fregs, fpregset.regs, sizeof (fregs));
558 res = pthreadDebugThdSetFreg (debug_context, tid, &fregs);
561 debug ("dec_thread_fetch_registers: pthreadDebugThdSetFreg -> %d", res);
568 /* The "to_store_registers" method of the dec_thread_ops.
570 Because the dec-thread debug API doesn't allow us to store
571 just one register, we store all the registers. */
574 dec_thread_store_registers (struct regcache *regcache, int regno)
576 pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
581 debug ("dec_thread_store_registers (tid=%ld, regno=%d)", tid, regno);
583 if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
585 base_target.to_store_registers (regcache, regno);
589 /* FIXME: brobecker/2008-05-28: I wonder if we could simply check
590 in which register set the register is and then only store the
591 registers for that register set, instead of storing both register
593 fill_gregset (regcache, &gregset, -1);
594 fill_fpregset (regcache, &fpregset, -1);
596 res = dec_thread_set_regsets (tid, gregset, fpregset);
598 warning (_("failed to store registers."));
601 /* The "to_mourn_inferior" method of the dec_thread_ops. */
604 dec_thread_mourn_inferior (void)
606 debug ("dec_thread_mourn_inferior");
608 disable_dec_thread ();
609 base_target.to_mourn_inferior (&base_target);
612 /* The "to_thread_alive" method of the dec_thread_ops. */
614 dec_thread_thread_alive (ptid_t ptid)
616 debug ("dec_thread_thread_alive (tid=%ld)", ptid_get_tid (ptid));
618 /* The thread list maintained by GDB is up to date, since we update
619 it everytime we stop. So check this list. */
620 return in_thread_list (ptid);
623 /* The "to_pid_to_str" method of the dec_thread_ops. */
626 dec_thread_pid_to_str (struct target_ops *ops, ptid_t ptid)
628 static char *ret = NULL;
630 if (ptid_get_tid (ptid) == 0)
631 return base_target.to_pid_to_str (&base_target, ptid);
633 /* Free previous return value; a new one will be allocated by
637 ret = xstrprintf (_("Thread %ld"), ptid_get_tid (ptid));
641 /* A "new-objfile" observer. Used to activate/deactivate dec-thread
645 dec_thread_new_objfile_observer (struct objfile *objfile)
648 enable_dec_thread ();
650 disable_dec_thread ();
654 init_dec_thread_ops (void)
656 dec_thread_ops.to_shortname = "dec-threads";
657 dec_thread_ops.to_longname = _("DEC threads support");
658 dec_thread_ops.to_doc = _("DEC threads support");
659 dec_thread_ops.to_detach = dec_thread_detach;
660 dec_thread_ops.to_wait = dec_thread_wait;
661 dec_thread_ops.to_fetch_registers = dec_thread_fetch_registers;
662 dec_thread_ops.to_store_registers = dec_thread_store_registers;
663 dec_thread_ops.to_mourn_inferior = dec_thread_mourn_inferior;
664 dec_thread_ops.to_thread_alive = dec_thread_thread_alive;
665 dec_thread_ops.to_pid_to_str = dec_thread_pid_to_str;
666 dec_thread_ops.to_stratum = thread_stratum;
667 dec_thread_ops.to_magic = OPS_MAGIC;
671 _initialize_dec_thread (void)
673 init_dec_thread_ops ();
674 add_target (&dec_thread_ops);
676 observer_attach_new_objfile (dec_thread_new_objfile_observer);
678 add_setshow_boolean_cmd ("dec-thread", class_maintenance, &debug_dec_thread,
679 _("Set debugging of DEC threads module."),
680 _("Show debugging of DEC threads module."),
681 _("Enables debugging output (used to debug GDB)."),
683 &setdebuglist, &showdebuglist);