1 /* libthread_db assisted debugging support, generic parts.
2 Copyright 1999, 2000 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
23 #include "gdb_assert.h"
25 #include "gdb_proc_service.h"
26 #include "gdb_thread_db.h"
29 #include "gdbthread.h"
35 #ifndef LIBTHREAD_DB_SO
36 #define LIBTHREAD_DB_SO "libthread_db.so.1"
39 /* If we're running on Linux, we must explicitly attach to any new threads. */
41 /* FIXME: There is certainly some room for improvements:
43 - Bypass libthread_db when fetching or storing registers for
44 threads bound to a LWP. */
46 /* This module's target vector. */
47 static struct target_ops thread_db_ops
;
49 /* The target vector that we call for things this module can't handle. */
50 static struct target_ops
*target_beneath
;
52 /* Pointer to the next function on the objfile event chain. */
53 static void (*target_new_objfile_chain
) (struct objfile
*objfile
);
55 /* Non-zero if we're using this module's target vector. */
56 static int using_thread_db
;
58 /* Non-zero if we musn't deactivate this module's target vector. */
59 static int keep_thread_db
;
61 /* Non-zero if we have determined the signals used by the threads
63 static int thread_signals
;
64 static sigset_t thread_stop_set
;
65 static sigset_t thread_print_set
;
67 /* Structure that identifies the child process for the
68 <proc_service.h> interface. */
69 static struct ps_prochandle proc_handle
;
71 /* Connection to the libthread_db library. */
72 static td_thragent_t
*thread_agent
;
74 /* Pointers to the libthread_db functions. */
76 static td_err_e (*td_init_p
) (void);
78 static td_err_e (*td_ta_new_p
) (struct ps_prochandle
*ps
, td_thragent_t
**ta
);
79 static td_err_e (*td_ta_map_id2thr_p
) (const td_thragent_t
*ta
, thread_t pt
,
80 td_thrhandle_t
*__th
);
81 static td_err_e (*td_ta_map_lwp2thr_p
) (const td_thragent_t
*ta
, lwpid_t lwpid
,
83 static td_err_e (*td_ta_thr_iter_p
) (const td_thragent_t
*ta
,
84 td_thr_iter_f
*callback
,
85 void *cbdata_p
, td_thr_state_e state
,
86 int ti_pri
, sigset_t
*ti_sigmask_p
,
87 unsigned int ti_user_flags
);
88 static td_err_e (*td_ta_event_addr_p
) (const td_thragent_t
*ta
,
89 td_event_e event
, td_notify_t
*ptr
);
90 static td_err_e (*td_ta_set_event_p
) (const td_thragent_t
*ta
,
91 td_thr_events_t
*event
);
92 static td_err_e (*td_ta_event_getmsg_p
) (const td_thragent_t
*ta
,
95 static td_err_e (*td_thr_validate_p
) (const td_thrhandle_t
*th
);
96 static td_err_e (*td_thr_get_info_p
) (const td_thrhandle_t
*th
,
98 static td_err_e (*td_thr_getfpregs_p
) (const td_thrhandle_t
*th
,
99 gdb_prfpregset_t
*regset
);
100 static td_err_e (*td_thr_getgregs_p
) (const td_thrhandle_t
*th
,
102 static td_err_e (*td_thr_setfpregs_p
) (const td_thrhandle_t
*th
,
103 const gdb_prfpregset_t
*fpregs
);
104 static td_err_e (*td_thr_setgregs_p
) (const td_thrhandle_t
*th
,
106 static td_err_e (*td_thr_event_enable_p
) (const td_thrhandle_t
*th
, int event
);
108 /* Location of the thread creation event breakpoint. The code at this
109 location in the child process will be called by the pthread library
110 whenever a new thread is created. By setting a special breakpoint
111 at this location, GDB can detect when a new thread is created. We
112 obtain this location via the td_ta_event_addr call. */
113 static CORE_ADDR td_create_bp_addr
;
115 /* Location of the thread death event breakpoint. */
116 static CORE_ADDR td_death_bp_addr
;
118 /* Prototypes for local functions. */
119 static void thread_db_find_new_threads (void);
122 /* Building process ids. */
125 #define TIDGET(PID) (((PID) & 0x7fffffff) >> 16)
126 #define PIDGET(PID) (((PID) & 0xffff))
127 #define MERGEPID(PID, TID) (((PID) & 0xffff) | ((TID) << 16))
130 #define THREAD_FLAG 0x80000000
132 #define is_lwp(pid) (((pid) & THREAD_FLAG) == 0 && TIDGET (pid))
133 #define is_thread(pid) ((pid) & THREAD_FLAG)
135 #define GET_PID(pid) PIDGET (pid)
136 #define GET_LWP(pid) TIDGET (pid)
137 #define GET_THREAD(pid) TIDGET (pid)
139 #define BUILD_LWP(tid, pid) MERGEPID (pid, tid)
140 #define BUILD_THREAD(tid, pid) (MERGEPID (pid, tid) | THREAD_FLAG)
143 struct private_thread_info
145 /* Cached LWP id. Must come first, see lin-lwp.c. */
150 /* Helper functions. */
153 restore_inferior_pid (void *arg
)
155 int *saved_pid_ptr
= arg
;
156 inferior_pid
= *saved_pid_ptr
;
160 static struct cleanup
*
161 save_inferior_pid (void)
165 saved_pid_ptr
= xmalloc (sizeof (int));
166 *saved_pid_ptr
= inferior_pid
;
167 return make_cleanup (restore_inferior_pid
, saved_pid_ptr
);
172 thread_db_err_str (td_err_e err
)
179 return "generic 'call succeeded'";
181 return "generic error";
183 return "no thread to satisfy query";
185 return "no sync handle to satisfy query";
187 return "no LWP to satisfy query";
189 return "invalid process handle";
191 return "invalid thread handle";
193 return "invalid synchronization handle";
195 return "invalid thread agent";
197 return "invalid key";
199 return "no event message for getmsg";
201 return "FPU register set not available";
203 return "application not linked with libthread";
205 return "requested event is not supported";
207 return "capability not available";
209 return "debugger service failed";
211 return "operation not applicable to";
213 return "no thread-specific data for this thread";
215 return "malloc failed";
217 return "only part of register set was written/read";
219 return "X register set not available for this thread";
221 snprintf (buf
, sizeof (buf
), "unknown thread_db error '%d'", err
);
227 thread_db_state_str (td_thr_state_e state
)
234 return "stopped by debugger";
243 case TD_THR_STOPPED_ASLEEP
:
244 return "stopped by debugger AND blocked";
246 snprintf (buf
, sizeof (buf
), "unknown thread_db state %d", state
);
252 /* Convert between user-level thread ids and LWP ids. */
255 thread_from_lwp (int pid
)
261 if (GET_LWP (pid
) == 0)
262 pid
= BUILD_LWP (pid
, pid
);
264 gdb_assert (is_lwp (pid
));
266 err
= td_ta_map_lwp2thr_p (thread_agent
, GET_LWP (pid
), &th
);
268 error ("Cannot find user-level thread for LWP %d: %s",
269 GET_LWP (pid
), thread_db_err_str (err
));
271 err
= td_thr_get_info_p (&th
, &ti
);
273 error ("Cannot get thread info: %s", thread_db_err_str (err
));
275 return BUILD_THREAD (ti
.ti_tid
, GET_PID (pid
));
279 lwp_from_thread (int pid
)
285 if (! is_thread (pid
))
288 err
= td_ta_map_id2thr_p (thread_agent
, GET_THREAD (pid
), &th
);
290 error ("Cannot find thread %ld: %s",
291 (long) GET_THREAD (pid
), thread_db_err_str (err
));
293 err
= td_thr_get_info_p (&th
, &ti
);
295 error ("Cannot get thread info: %s", thread_db_err_str (err
));
297 return BUILD_LWP (ti
.ti_lid
, GET_PID (pid
));
302 thread_db_init (struct target_ops
*target
)
304 target_beneath
= target
;
308 thread_db_load (void)
313 handle
= dlopen (LIBTHREAD_DB_SO
, RTLD_NOW
);
317 /* Initialize pointers to the dynamic library functions we will use.
318 Essential functions first. */
320 td_init_p
= dlsym (handle
, "td_init");
321 if (td_init_p
== NULL
)
324 td_ta_new_p
= dlsym (handle
, "td_ta_new");
325 if (td_ta_new_p
== NULL
)
328 td_ta_map_id2thr_p
= dlsym (handle
, "td_ta_map_id2thr");
329 if (td_ta_map_id2thr_p
== NULL
)
332 td_ta_map_lwp2thr_p
= dlsym (handle
, "td_ta_map_lwp2thr");
333 if (td_ta_map_lwp2thr_p
== NULL
)
336 td_ta_thr_iter_p
= dlsym (handle
, "td_ta_thr_iter");
337 if (td_ta_thr_iter_p
== NULL
)
340 td_thr_validate_p
= dlsym (handle
, "td_thr_validate");
341 if (td_thr_validate_p
== NULL
)
344 td_thr_get_info_p
= dlsym (handle
, "td_thr_get_info");
345 if (td_thr_get_info_p
== NULL
)
348 td_thr_getfpregs_p
= dlsym (handle
, "td_thr_getfpregs");
349 if (td_thr_getfpregs_p
== NULL
)
352 td_thr_getgregs_p
= dlsym (handle
, "td_thr_getgregs");
353 if (td_thr_getgregs_p
== NULL
)
356 td_thr_setfpregs_p
= dlsym (handle
, "td_thr_setfpregs");
357 if (td_thr_setfpregs_p
== NULL
)
360 td_thr_setgregs_p
= dlsym (handle
, "td_thr_setgregs");
361 if (td_thr_setgregs_p
== NULL
)
364 /* Initialize the library. */
368 warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err
));
372 /* These are not essential. */
373 td_ta_event_addr_p
= dlsym (handle
, "td_ta_event_addr");
374 td_ta_set_event_p
= dlsym (handle
, "td_ta_set_event");
375 td_ta_event_getmsg_p
= dlsym (handle
, "td_ta_event_getmsg");
376 td_thr_event_enable_p
= dlsym (handle
, "td_thr_event_enable");
382 enable_thread_event_reporting (void)
384 td_thr_events_t events
;
388 /* We cannot use the thread event reporting facility if these
389 functions aren't available. */
390 if (td_ta_event_addr_p
== NULL
|| td_ta_set_event_p
== NULL
391 || td_ta_event_getmsg_p
== NULL
|| td_thr_event_enable_p
== NULL
)
394 /* Set the process wide mask saying which events we're interested in. */
395 td_event_emptyset (&events
);
396 td_event_addset (&events
, TD_CREATE
);
398 /* FIXME: kettenis/2000-04-23: The event reporting facility is
399 broken for TD_DEATH events in glibc 2.1.3, so don't enable it for
401 td_event_addset (&events
, TD_DEATH
);
404 err
= td_ta_set_event_p (thread_agent
, &events
);
407 warning ("Unable to set global thread event mask: %s",
408 thread_db_err_str (err
));
412 /* Delete previous thread event breakpoints, if any. */
413 remove_thread_event_breakpoints ();
415 /* Get address for thread creation breakpoint. */
416 err
= td_ta_event_addr_p (thread_agent
, TD_CREATE
, ¬ify
);
419 warning ("Unable to get location for thread creation breakpoint: %s",
420 thread_db_err_str (err
));
424 /* Set up the breakpoint. */
425 td_create_bp_addr
= (CORE_ADDR
) notify
.u
.bptaddr
;
426 create_thread_event_breakpoint (td_create_bp_addr
);
428 /* Get address for thread death breakpoint. */
429 err
= td_ta_event_addr_p (thread_agent
, TD_DEATH
, ¬ify
);
432 warning ("Unable to get location for thread creation breakpoint: %s",
433 thread_db_err_str (err
));
437 /* Set up the breakpoint. */
438 td_death_bp_addr
= (CORE_ADDR
) notify
.u
.bptaddr
;
439 create_thread_event_breakpoint (td_death_bp_addr
);
443 disable_thread_event_reporting (void)
445 td_thr_events_t events
;
447 /* Set the process wide mask saying we aren't interested in any
449 td_event_emptyset (&events
);
450 td_ta_set_event_p (thread_agent
, &events
);
452 /* Delete thread event breakpoints, if any. */
453 remove_thread_event_breakpoints ();
454 td_create_bp_addr
= 0;
455 td_death_bp_addr
= 0;
459 check_thread_signals (void)
461 #ifdef GET_THREAD_SIGNALS
462 if (! thread_signals
)
467 GET_THREAD_SIGNALS (&mask
);
468 sigemptyset (&thread_stop_set
);
469 sigemptyset (&thread_print_set
);
471 for (i
= 0; i
< NSIG
; i
++)
473 if (sigismember (&mask
, i
))
475 if (signal_stop_update (target_signal_from_host (i
), 0))
476 sigaddset (&thread_stop_set
, i
);
477 if (signal_print_update (target_signal_from_host (i
), 0))
478 sigaddset (&thread_print_set
, i
);
487 disable_thread_signals (void)
489 #ifdef GET_THREAD_SIGNALS
494 for (i
= 0; i
< NSIG
; i
++)
496 if (sigismember (&thread_stop_set
, i
))
497 signal_stop_update (target_signal_from_host (i
), 1);
498 if (sigismember (&thread_print_set
, i
))
499 signal_print_update (target_signal_from_host (i
), 1);
508 deactivate_target (void)
510 /* Forget about the child's process ID. We shouldn't need it
514 if (! keep_thread_db
)
517 unpush_target (&thread_db_ops
);
522 thread_db_new_objfile (struct objfile
*objfile
)
528 /* All symbols have been discarded. If the thread_db target is
529 active, deactivate it now, even if the application was linked
530 statically against the thread library. */
533 deactivate_target ();
539 /* Nothing to do. The thread library was already detected and the
540 target vector was already activated. */
543 /* Initialize the structure that identifies the child process. Note
544 that at this point there is no guarantee that we actually have a
546 proc_handle
.pid
= GET_PID (inferior_pid
);
548 /* Now attempt to open a connection to the thread library. */
549 err
= td_ta_new_p (&proc_handle
, &thread_agent
);
553 /* No thread library was detected. */
557 /* The thread library was detected. Activate the thread_db target. */
558 push_target (&thread_db_ops
);
561 /* If the thread library was detected in the main symbol file
562 itself, we assume that the program was statically linked
563 against the thread library and well have to keep this
564 module's target vector activated until forever... Well, at
565 least until all symbols have been discarded anyway (see
567 if (objfile
== symfile_objfile
)
569 gdb_assert (proc_handle
.pid
== 0);
573 /* We can only poke around if there actually is a child process.
574 If there is no child process alive, postpone the steps below
575 until one has been created. */
576 if (proc_handle
.pid
!= 0)
578 enable_thread_event_reporting ();
579 thread_db_find_new_threads ();
584 warning ("Cannot initialize thread debugging library: %s",
585 thread_db_err_str (err
));
590 if (target_new_objfile_chain
)
591 target_new_objfile_chain (objfile
);
595 attach_thread (int pid
, const td_thrhandle_t
*th_p
,
596 const td_thrinfo_t
*ti_p
, int verbose
)
598 struct thread_info
*tp
;
601 check_thread_signals ();
604 printf_unfiltered ("[New %s]\n", target_pid_to_str (pid
));
606 /* Add the thread to GDB's thread list. */
607 tp
= add_thread (pid
);
608 tp
->private = xmalloc (sizeof (struct private_thread_info
));
609 tp
->private->lwpid
= ti_p
->ti_lid
;
611 /* Under Linux, we have to attach to each and every thread. */
613 if (ti_p
->ti_lid
!= GET_PID (pid
))
614 ATTACH_LWP (BUILD_LWP (ti_p
->ti_lid
, GET_PID (pid
)), 0);
617 /* Enable thread event reporting for this thread. */
618 err
= td_thr_event_enable_p (th_p
, 1);
620 error ("Cannot enable thread event reporting for %s: %s",
621 target_pid_to_str (pid
), thread_db_err_str (err
));
625 detach_thread (int pid
, int verbose
)
628 printf_unfiltered ("[%s exited]\n", target_pid_to_str (pid
));
632 thread_db_detach (char *args
, int from_tty
)
634 disable_thread_event_reporting ();
635 deactivate_target ();
637 target_beneath
->to_detach (args
, from_tty
);
641 thread_db_resume (int pid
, int step
, enum target_signal signo
)
643 struct cleanup
*old_chain
= save_inferior_pid ();
646 inferior_pid
= lwp_from_thread (inferior_pid
);
647 else if (is_thread (pid
))
648 pid
= lwp_from_thread (pid
);
650 target_beneath
->to_resume (pid
, step
, signo
);
652 do_cleanups (old_chain
);
655 /* Check if PID is currently stopped at the location of a thread event
656 breakpoint location. If it is, read the event message and act upon
660 check_event (int pid
)
667 /* Bail out early if we're not at a thread event breakpoint. */
668 stop_pc
= read_pc_pid (pid
) - DECR_PC_AFTER_BREAK
;
669 if (stop_pc
!= td_create_bp_addr
&& stop_pc
!= td_death_bp_addr
)
672 err
= td_ta_event_getmsg_p (thread_agent
, &msg
);
678 error ("Cannot get thread event message: %s", thread_db_err_str (err
));
681 err
= td_thr_get_info_p (msg
.th_p
, &ti
);
683 error ("Cannot get thread info: %s", thread_db_err_str (err
));
685 pid
= BUILD_THREAD (ti
.ti_tid
, GET_PID (pid
));
691 /* FIXME: kettenis/2000-08-26: Since we use td_ta_event_getmsg,
692 there is no guarantee that the breakpoint will match the
693 event. Should we use td_thr_event_getmsg instead? */
695 if (stop_pc
!= td_create_bp_addr
)
696 error ("Thread creation event doesn't match breakpoint.");
699 if (in_thread_list (pid
))
700 error ("Spurious thread creation event.");
702 attach_thread (pid
, msg
.th_p
, &ti
, 1);
707 /* FIXME: See TD_CREATE. */
709 if (stop_pc
!= td_death_bp_addr
)
710 error ("Thread death event doesn't match breakpoint.");
713 if (! in_thread_list (pid
))
714 error ("Spurious thread death event.");
716 detach_thread (pid
, 1);
720 error ("Spurious thread event.");
725 thread_db_wait (int pid
, struct target_waitstatus
*ourstatus
)
729 if (pid
!= -1 && is_thread (pid
))
730 pid
= lwp_from_thread (pid
);
732 pid
= target_beneath
->to_wait (pid
, ourstatus
);
734 if (proc_handle
.pid
== 0)
735 /* The current child process isn't the actual multi-threaded
736 program yet, so don't try to do any special thread-specific
737 post-processing and bail out early. */
740 if (ourstatus
->kind
== TARGET_WAITKIND_EXITED
)
743 if (ourstatus
->kind
== TARGET_WAITKIND_STOPPED
744 && ourstatus
->value
.sig
== TARGET_SIGNAL_TRAP
)
745 /* Check for a thread event. */
749 trap_pid
= thread_from_lwp (trap_pid
);
751 return thread_from_lwp (pid
);
755 thread_db_xfer_memory (CORE_ADDR memaddr
, char *myaddr
, int len
, int write
,
756 struct target_ops
*target
)
758 struct cleanup
*old_chain
= save_inferior_pid ();
761 if (is_thread (inferior_pid
))
763 /* FIXME: This seems to be necessary to make sure breakpoints
765 if (! target_thread_alive (inferior_pid
))
766 inferior_pid
= GET_PID (inferior_pid
);
768 inferior_pid
= lwp_from_thread (inferior_pid
);
771 xfer
= target_beneath
->to_xfer_memory (memaddr
, myaddr
, len
, write
, target
);
773 do_cleanups (old_chain
);
778 thread_db_fetch_registers (int regno
)
782 gdb_prfpregset_t fpregset
;
785 if (! is_thread (inferior_pid
))
787 /* Pass the request to the target beneath us. */
788 target_beneath
->to_fetch_registers (regno
);
792 err
= td_ta_map_id2thr_p (thread_agent
, GET_THREAD (inferior_pid
), &th
);
794 error ("Cannot find thread %ld: %s",
795 (long) GET_THREAD (inferior_pid
), thread_db_err_str (err
));
797 err
= td_thr_getgregs_p (&th
, gregset
);
799 error ("Cannot fetch general-purpose registers for thread %ld: %s",
800 (long) GET_THREAD (inferior_pid
), thread_db_err_str (err
));
802 err
= td_thr_getfpregs_p (&th
, &fpregset
);
804 error ("Cannot get floating-point registers for thread %ld: %s",
805 (long) GET_THREAD (inferior_pid
), thread_db_err_str (err
));
807 /* Note that we must call supply_gregset after calling the thread_db
808 routines because the thread_db routines call ps_lgetgregs and
809 friends which clobber GDB's register cache. */
810 supply_gregset ((gdb_gregset_t
*) gregset
);
811 supply_fpregset (&fpregset
);
815 thread_db_store_registers (int regno
)
819 gdb_prfpregset_t fpregset
;
822 if (! is_thread (inferior_pid
))
824 /* Pass the request to the target beneath us. */
825 target_beneath
->to_store_registers (regno
);
829 err
= td_ta_map_id2thr_p (thread_agent
, GET_THREAD (inferior_pid
), &th
);
831 error ("Cannot find thread %ld: %s",
832 (long) GET_THREAD (inferior_pid
), thread_db_err_str (err
));
836 char raw
[MAX_REGISTER_RAW_SIZE
];
838 read_register_gen (regno
, raw
);
839 thread_db_fetch_registers (-1);
840 supply_register (regno
, raw
);
843 fill_gregset ((gdb_gregset_t
*) gregset
, -1);
844 fill_fpregset (&fpregset
, -1);
846 err
= td_thr_setgregs_p (&th
, gregset
);
848 error ("Cannot store general-purpose registers for thread %ld: %s",
849 (long) GET_THREAD (inferior_pid
), thread_db_err_str (err
));
850 err
= td_thr_setfpregs_p (&th
, &fpregset
);
852 error ("Cannot store floating-point registers for thread %ld: %s",
853 (long) GET_THREAD (inferior_pid
), thread_db_err_str (err
));
857 thread_db_kill (void)
859 target_beneath
->to_kill ();
863 thread_db_create_inferior (char *exec_file
, char *allargs
, char **env
)
865 target_beneath
->to_create_inferior (exec_file
, allargs
, env
);
869 thread_db_post_startup_inferior (int pid
)
871 if (proc_handle
.pid
== 0)
873 /* The child process is now the actual multi-threaded
874 program. Snatch its process ID... */
875 proc_handle
.pid
= GET_PID (pid
);
877 /* ...and perform the remaining initialization steps. */
878 enable_thread_event_reporting ();
879 thread_db_find_new_threads();
884 thread_db_mourn_inferior (void)
886 remove_thread_event_breakpoints ();
887 deactivate_target ();
889 target_beneath
->to_mourn_inferior ();
893 thread_db_thread_alive (int pid
)
900 err
= td_ta_map_id2thr_p (thread_agent
, GET_THREAD (pid
), &th
);
904 err
= td_thr_validate_p (&th
);
911 if (target_beneath
->to_thread_alive
)
912 return target_beneath
->to_thread_alive (pid
);
918 find_new_threads_callback (const td_thrhandle_t
*th_p
, void *data
)
924 err
= td_thr_get_info_p (th_p
, &ti
);
926 error ("Cannot get thread info: %s", thread_db_err_str (err
));
928 pid
= BUILD_THREAD (ti
.ti_tid
, GET_PID (inferior_pid
));
930 if (! in_thread_list (pid
))
931 attach_thread (pid
, th_p
, &ti
, 1);
937 thread_db_find_new_threads (void)
941 /* Iterate over all user-space threads to discover new threads. */
942 err
= td_ta_thr_iter_p (thread_agent
, find_new_threads_callback
, NULL
,
943 TD_THR_ANY_STATE
, TD_THR_LOWEST_PRIORITY
,
944 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
);
946 error ("Cannot find new threads: %s", thread_db_err_str (err
));
950 thread_db_pid_to_str (int pid
)
959 err
= td_ta_map_id2thr_p (thread_agent
, GET_THREAD (pid
), &th
);
961 error ("Cannot find thread %ld: %s",
962 (long) GET_THREAD (pid
), thread_db_err_str (err
));
964 err
= td_thr_get_info_p (&th
, &ti
);
966 error ("Cannot get thread info for thread %ld: %s",
967 (long) GET_THREAD (pid
), thread_db_err_str (err
));
969 if (ti
.ti_state
== TD_THR_ACTIVE
&& ti
.ti_lid
!= 0)
971 snprintf (buf
, sizeof (buf
), "Thread %ld (LWP %d)",
972 (long) ti
.ti_tid
, ti
.ti_lid
);
976 snprintf (buf
, sizeof (buf
), "Thread %ld (%s)",
977 (long) ti
.ti_tid
, thread_db_state_str (ti
.ti_state
));
983 if (target_beneath
->to_pid_to_str (pid
))
984 return target_beneath
->to_pid_to_str (pid
);
986 return normal_pid_to_str (pid
);
990 init_thread_db_ops (void)
992 thread_db_ops
.to_shortname
= "multi-thread";
993 thread_db_ops
.to_longname
= "multi-threaded child process.";
994 thread_db_ops
.to_doc
= "Threads and pthreads support.";
995 thread_db_ops
.to_detach
= thread_db_detach
;
996 thread_db_ops
.to_resume
= thread_db_resume
;
997 thread_db_ops
.to_wait
= thread_db_wait
;
998 thread_db_ops
.to_fetch_registers
= thread_db_fetch_registers
;
999 thread_db_ops
.to_store_registers
= thread_db_store_registers
;
1000 thread_db_ops
.to_xfer_memory
= thread_db_xfer_memory
;
1001 thread_db_ops
.to_kill
= thread_db_kill
;
1002 thread_db_ops
.to_create_inferior
= thread_db_create_inferior
;
1003 thread_db_ops
.to_post_startup_inferior
= thread_db_post_startup_inferior
;
1004 thread_db_ops
.to_mourn_inferior
= thread_db_mourn_inferior
;
1005 thread_db_ops
.to_thread_alive
= thread_db_thread_alive
;
1006 thread_db_ops
.to_find_new_threads
= thread_db_find_new_threads
;
1007 thread_db_ops
.to_pid_to_str
= thread_db_pid_to_str
;
1008 thread_db_ops
.to_stratum
= thread_stratum
;
1009 thread_db_ops
.to_has_thread_control
= tc_schedlock
;
1010 thread_db_ops
.to_magic
= OPS_MAGIC
;
1014 _initialize_thread_db (void)
1016 /* Only initialize the module if we can load libthread_db. */
1017 if (thread_db_load ())
1019 init_thread_db_ops ();
1020 add_target (&thread_db_ops
);
1022 /* Add ourselves to objfile event chain. */
1023 target_new_objfile_chain
= target_new_objfile_hook
;
1024 target_new_objfile_hook
= thread_db_new_objfile
;