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"
28 #include "gdbthread.h"
32 #ifndef LIBTHREAD_DB_SO
33 #define LIBTHREAD_DB_SO "libthread_db.so.1"
36 /* If we're running on Linux, we must explicitly attach to any new threads. */
38 /* FIXME: There is certainly some room for improvements:
40 - Bypass libthread_db when fetching or storing registers for
41 threads bound to a LWP. */
43 /* This module's target vector. */
44 static struct target_ops thread_db_ops;
46 /* The target vector that we call for things this module can't handle. */
47 static struct target_ops *target_beneath;
49 /* Pointer to the next function on the objfile event chain. */
50 static void (*target_new_objfile_chain) (struct objfile *objfile);
52 /* Non-zero if we're using this module's target vector. */
53 static int using_thread_db;
55 /* Non-zero if we have determined the signals used by the threads
57 static int thread_signals;
58 static sigset_t thread_stop_set;
59 static sigset_t thread_print_set;
61 /* Structure that identifies the child process for the
62 <proc_service.h> interface. */
63 static struct ps_prochandle proc_handle;
65 /* Connection to the libthread_db library. */
66 static td_thragent_t *thread_agent;
68 /* Pointers to the libthread_db functions. */
70 static td_err_e (*td_init_p) (void);
72 static td_err_e (*td_ta_new_p) (struct ps_prochandle *ps, td_thragent_t **ta);
73 static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
74 td_thrhandle_t *__th);
75 static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta, lwpid_t lwpid,
77 static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
78 td_thr_iter_f *callback,
79 void *cbdata_p, td_thr_state_e state,
80 int ti_pri, sigset_t *ti_sigmask_p,
81 unsigned int ti_user_flags);
82 static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
83 td_event_e event, td_notify_t *ptr);
84 static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
85 td_thr_events_t *event);
86 static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
89 static td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
90 static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
92 static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
93 gdb_prfpregset_t *regset);
94 static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
96 static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
97 const gdb_prfpregset_t *fpregs);
98 static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
100 static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event);
102 /* Location of the thread creation event breakpoint. The code at this
103 location in the child process will be called by the pthread library
104 whenever a new thread is created. By setting a special breakpoint
105 at this location, GDB can detect when a new thread is created. We
106 obtain this location via the td_ta_event_addr call. */
107 static CORE_ADDR td_create_bp_addr;
109 /* Location of the thread death event breakpoint. */
110 static CORE_ADDR td_death_bp_addr;
112 /* Prototypes for local functions. */
113 static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data);
116 /* Building process ids. */
119 #define TIDGET(PID) (((PID) & 0x7fffffff) >> 16)
120 #define PIDGET(PID) (((PID) & 0xffff))
121 #define MERGEPID(PID, TID) (((PID) & 0xffff) | ((TID) << 16))
124 #define THREAD_FLAG 0x80000000
126 #define is_lwp(pid) (((pid) & THREAD_FLAG) == 0 && TIDGET (pid))
127 #define is_thread(pid) ((pid) & THREAD_FLAG)
129 #define GET_PID(pid) PIDGET (pid)
130 #define GET_LWP(pid) TIDGET (pid)
131 #define GET_THREAD(pid) TIDGET (pid)
133 #define BUILD_LWP(tid, pid) MERGEPID (pid, tid)
134 #define BUILD_THREAD(tid, pid) (MERGEPID (pid, tid) | THREAD_FLAG)
137 struct private_thread_info
139 /* Cached LWP id. Must come first, see lin-lwp.c. */
144 /* Helper functions. */
147 restore_inferior_pid (void *arg)
149 int *saved_pid_ptr = arg;
150 inferior_pid = *saved_pid_ptr;
154 static struct cleanup *
155 save_inferior_pid (void)
159 saved_pid_ptr = xmalloc (sizeof (int));
160 *saved_pid_ptr = inferior_pid;
161 return make_cleanup (restore_inferior_pid, saved_pid_ptr);
166 thread_db_err_str (td_err_e err)
173 return "generic 'call succeeded'";
175 return "generic error";
177 return "no thread to satisfy query";
179 return "no sync handle to satisfy query";
181 return "no LWP to satisfy query";
183 return "invalid process handle";
185 return "invalid thread handle";
187 return "invalid synchronization handle";
189 return "invalid thread agent";
191 return "invalid key";
193 return "no event message for getmsg";
195 return "FPU register set not available";
197 return "application not linked with libthread";
199 return "requested event is not supported";
201 return "capability not available";
203 return "debugger service failed";
205 return "operation not applicable to";
207 return "no thread-specific data for this thread";
209 return "malloc failed";
211 return "only part of register set was written/read";
213 return "X register set not available for this thread";
215 snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
221 thread_db_state_str (td_thr_state_e state)
228 return "stopped by debugger";
237 case TD_THR_STOPPED_ASLEEP:
238 return "stopped by debugger AND blocked";
240 snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
246 /* Convert between user-level thread ids and LWP ids. */
249 thread_from_lwp (int pid)
255 if (GET_LWP (pid) == 0)
256 pid = BUILD_LWP (pid, pid);
258 gdb_assert (is_lwp (pid));
260 err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (pid), &th);
262 error ("Cannot find user-level thread for LWP %d: %s",
263 GET_LWP (pid), thread_db_err_str (err));
265 err = td_thr_get_info_p (&th, &ti);
267 error ("Cannot get thread info: %s", thread_db_err_str (err));
269 return BUILD_THREAD (ti.ti_tid, GET_PID (pid));
273 lwp_from_thread (int pid)
279 if (! is_thread (pid))
282 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (pid), &th);
284 error ("Cannot find thread %ld: %s",
285 (long) GET_THREAD (pid), thread_db_err_str (err));
287 err = td_thr_get_info_p (&th, &ti);
289 error ("Cannot get thread info: %s", thread_db_err_str (err));
291 return BUILD_LWP (ti.ti_lid, GET_PID (pid));
296 thread_db_init (struct target_ops *target)
298 target_beneath = target;
302 thread_db_load (void)
307 handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
311 /* Initialize pointers to the dynamic library functions we will use.
312 Essential functions first. */
314 td_init_p = dlsym (handle, "td_init");
315 if (td_init_p == NULL)
318 td_ta_new_p = dlsym (handle, "td_ta_new");
319 if (td_ta_new_p == NULL)
322 td_ta_map_id2thr_p = dlsym (handle, "td_ta_map_id2thr");
323 if (td_ta_map_id2thr_p == NULL)
326 td_ta_map_lwp2thr_p = dlsym (handle, "td_ta_map_lwp2thr");
327 if (td_ta_map_lwp2thr_p == NULL)
330 td_ta_thr_iter_p = dlsym (handle, "td_ta_thr_iter");
331 if (td_ta_thr_iter_p == NULL)
334 td_thr_validate_p = dlsym (handle, "td_thr_validate");
335 if (td_thr_validate_p == NULL)
338 td_thr_get_info_p = dlsym (handle, "td_thr_get_info");
339 if (td_thr_get_info_p == NULL)
342 td_thr_getfpregs_p = dlsym (handle, "td_thr_getfpregs");
343 if (td_thr_getfpregs_p == NULL)
346 td_thr_getgregs_p = dlsym (handle, "td_thr_getgregs");
347 if (td_thr_getgregs_p == NULL)
350 td_thr_setfpregs_p = dlsym (handle, "td_thr_setfpregs");
351 if (td_thr_setfpregs_p == NULL)
354 td_thr_setgregs_p = dlsym (handle, "td_thr_setgregs");
355 if (td_thr_setgregs_p == NULL)
358 /* Initialize the library. */
362 warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
366 /* These are not essential. */
367 td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
368 td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
369 td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
370 td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
376 enable_thread_event_reporting (void)
378 td_thr_events_t events;
382 /* We cannot use the thread event reporting facility if these
383 functions aren't available. */
384 if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
385 || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
388 /* Set the process wide mask saying which events we're interested in. */
389 td_event_emptyset (&events);
390 td_event_addset (&events, TD_CREATE);
392 /* FIXME: kettenis/2000-04-23: The event reporting facility is
393 broken for TD_DEATH events in glibc 2.1.3, so don't enable it for
395 td_event_addset (&events, TD_DEATH);
398 err = td_ta_set_event_p (thread_agent, &events);
401 warning ("Unable to set global thread event mask: %s",
402 thread_db_err_str (err));
406 /* Delete previous thread event breakpoints, if any. */
407 remove_thread_event_breakpoints ();
409 /* Get address for thread creation breakpoint. */
410 err = td_ta_event_addr_p (thread_agent, TD_CREATE, ¬ify);
413 warning ("Unable to get location for thread creation breakpoint: %s",
414 thread_db_err_str (err));
418 /* Set up the breakpoint. */
419 td_create_bp_addr = (CORE_ADDR) notify.u.bptaddr;
420 create_thread_event_breakpoint (td_create_bp_addr);
422 /* Get address for thread death breakpoint. */
423 err = td_ta_event_addr_p (thread_agent, TD_DEATH, ¬ify);
426 warning ("Unable to get location for thread creation breakpoint: %s",
427 thread_db_err_str (err));
431 /* Set up the breakpoint. */
432 td_death_bp_addr = (CORE_ADDR) notify.u.bptaddr;
433 create_thread_event_breakpoint (td_death_bp_addr);
437 disable_thread_event_reporting (void)
439 td_thr_events_t events;
441 /* Set the process wide mask saying we aren't interested in any
443 td_event_emptyset (&events);
444 td_ta_set_event_p (thread_agent, &events);
446 /* Delete thread event breakpoints, if any. */
447 remove_thread_event_breakpoints ();
448 td_create_bp_addr = 0;
449 td_death_bp_addr = 0;
453 check_thread_signals (void)
455 #ifdef GET_THREAD_SIGNALS
456 if (! thread_signals)
461 GET_THREAD_SIGNALS (&mask);
462 sigemptyset (&thread_stop_set);
463 sigemptyset (&thread_print_set);
465 for (i = 0; i < NSIG; i++)
467 if (sigismember (&mask, i))
469 if (signal_stop_update (target_signal_from_host (i), 0))
470 sigaddset (&thread_stop_set, i);
471 if (signal_print_update (target_signal_from_host (i), 0))
472 sigaddset (&thread_print_set, i);
481 disable_thread_signals (void)
483 #ifdef GET_THREAD_SIGNALS
488 for (i = 0; i < NSIG; i++)
490 if (sigismember (&thread_stop_set, i))
491 signal_stop_update (target_signal_from_host (i), 1);
492 if (sigismember (&thread_print_set, i))
493 signal_print_update (target_signal_from_host (i), 1);
502 thread_db_push_target (void)
506 /* Push this target vector. */
507 push_target (&thread_db_ops);
509 enable_thread_event_reporting ();
513 thread_db_unpush_target (void)
515 /* Unpush this target vector. */
516 unpush_target (&thread_db_ops);
522 thread_db_new_objfile (struct objfile *objfile)
527 /* Nothing to do. The thread library was already detected and the
528 target vector was already activated. */
532 /* Un-interesting object file. */
535 /* Initialize the structure that identifies the child process. */
536 proc_handle.pid = GET_PID (inferior_pid);
538 /* Now attempt to open a connection to the thread library running in
539 the child process. */
540 err = td_ta_new_p (&proc_handle, &thread_agent);
544 /* No thread library found in the child process, probably
545 because the child process isn't running yet. */
549 /* The thread library was detected in the child; we go live now! */
550 thread_db_push_target ();
552 /* Find all user-space threads. */
553 err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback,
554 &inferior_pid, TD_THR_ANY_STATE,
555 TD_THR_LOWEST_PRIORITY, TD_SIGNO_MASK,
556 TD_THR_ANY_USER_FLAGS);
558 error ("Finding new threads failed: %s", thread_db_err_str (err));
562 warning ("Cannot initialize thread debugging library: %s",
563 thread_db_err_str (err));
568 if (target_new_objfile_chain)
569 target_new_objfile_chain (objfile);
573 attach_thread (int pid, const td_thrhandle_t *th_p,
574 const td_thrinfo_t *ti_p, int verbose)
576 struct thread_info *tp;
579 check_thread_signals ();
582 printf_unfiltered ("[New %s]\n", target_pid_to_str (pid));
584 /* Add the thread to GDB's thread list. */
585 tp = add_thread (pid);
586 tp->private = xmalloc (sizeof (struct private_thread_info));
587 tp->private->lwpid = ti_p->ti_lid;
589 /* Under Linux, we have to attach to each and every thread. */
591 if (ti_p->ti_lid != GET_PID (pid))
592 ATTACH_LWP (BUILD_LWP (ti_p->ti_lid, GET_PID (pid)), 0);
595 /* Enable thread event reporting for this thread. */
596 err = td_thr_event_enable_p (th_p, 1);
598 error ("Cannot enable thread event reporting for %s: %s",
599 target_pid_to_str (pid), thread_db_err_str (err));
603 detach_thread (int pid, int verbose)
606 printf_unfiltered ("[%s exited]\n", target_pid_to_str (pid));
610 thread_db_detach (char *args, int from_tty)
612 disable_thread_event_reporting ();
613 thread_db_unpush_target ();
615 target_beneath->to_detach (args, from_tty);
619 thread_db_resume (int pid, int step, enum target_signal signo)
621 struct cleanup *old_chain = save_inferior_pid ();
624 inferior_pid = lwp_from_thread (inferior_pid);
625 else if (is_thread (pid))
626 pid = lwp_from_thread (pid);
628 target_beneath->to_resume (pid, step, signo);
630 do_cleanups (old_chain);
633 /* Check if PID is currently stopped at the location of a thread event
634 breakpoint location. If it is, read the event message and act upon
638 check_event (int pid)
645 /* Bail out early if we're not at a thread event breakpoint. */
646 stop_pc = read_pc_pid (pid) - DECR_PC_AFTER_BREAK;
647 if (stop_pc != td_create_bp_addr && stop_pc != td_death_bp_addr)
650 err = td_ta_event_getmsg_p (thread_agent, &msg);
656 error ("Cannot get thread event message: %s", thread_db_err_str (err));
659 err = td_thr_get_info_p (msg.th_p, &ti);
661 error ("Cannot get thread info: %s", thread_db_err_str (err));
663 pid = BUILD_THREAD (ti.ti_tid, GET_PID (pid));
669 /* FIXME: kettenis/2000-08-26: Since we use td_ta_event_getmsg,
670 there is no guarantee that the breakpoint will match the
671 event. Should we use td_thr_event_getmsg instead? */
673 if (stop_pc != td_create_bp_addr)
674 error ("Thread creation event doesn't match breakpoint.");
677 if (in_thread_list (pid))
678 error ("Spurious thread creation event.");
680 attach_thread (pid, msg.th_p, &ti, 1);
685 /* FIXME: See TD_CREATE. */
687 if (stop_pc != td_death_bp_addr)
688 error ("Thread death event doesn't match breakpoint.");
691 if (! in_thread_list (pid))
692 error ("Spurious thread death event.");
694 detach_thread (pid, 1);
698 error ("Spurious thread event.");
703 thread_db_wait (int pid, struct target_waitstatus *ourstatus)
707 if (pid != -1 && is_thread (pid))
708 pid = lwp_from_thread (pid);
710 pid = target_beneath->to_wait (pid, ourstatus);
712 if (ourstatus->kind == TARGET_WAITKIND_EXITED)
715 if (ourstatus->kind == TARGET_WAITKIND_STOPPED
716 && ourstatus->value.sig == TARGET_SIGNAL_TRAP)
717 /* Check for a thread event. */
721 trap_pid = thread_from_lwp (trap_pid);
723 return thread_from_lwp (pid);
727 thread_db_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
728 struct target_ops *target)
730 struct cleanup *old_chain = save_inferior_pid ();
733 if (is_thread (inferior_pid))
735 /* FIXME: This seems to be necessary to make sure breakpoints
737 if (! target_thread_alive (inferior_pid))
738 inferior_pid = GET_PID (inferior_pid);
740 inferior_pid = lwp_from_thread (inferior_pid);
743 xfer = target_beneath->to_xfer_memory (memaddr, myaddr, len, write, target);
745 do_cleanups (old_chain);
750 thread_db_fetch_registers (int regno)
754 gdb_prfpregset_t fpregset;
757 if (! is_thread (inferior_pid))
759 /* Pass the request to the target beneath us. */
760 target_beneath->to_fetch_registers (regno);
764 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_pid), &th);
766 error ("Cannot find thread %ld: %s",
767 (long) GET_THREAD (inferior_pid), thread_db_err_str (err));
769 err = td_thr_getgregs_p (&th, gregset);
771 error ("Cannot fetch general-purpose registers for thread %ld: %s",
772 (long) GET_THREAD (inferior_pid), thread_db_err_str (err));
774 err = td_thr_getfpregs_p (&th, &fpregset);
776 error ("Cannot get floating-point registers for thread %ld: %s",
777 (long) GET_THREAD (inferior_pid), thread_db_err_str (err));
779 /* Note that we must call supply_gregset after calling the thread_db
780 routines because the thread_db routines call ps_lgetgregs and
781 friends which clobber GDB's register cache. */
782 supply_gregset ((gdb_gregset_t *) gregset);
783 supply_fpregset (&fpregset);
787 thread_db_store_registers (int regno)
791 gdb_prfpregset_t fpregset;
794 if (! is_thread (inferior_pid))
796 /* Pass the request to the target beneath us. */
797 target_beneath->to_store_registers (regno);
801 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_pid), &th);
803 error ("Cannot find thread %ld: %s",
804 (long) GET_THREAD (inferior_pid), thread_db_err_str (err));
808 char raw[MAX_REGISTER_RAW_SIZE];
810 read_register_gen (regno, raw);
811 thread_db_fetch_registers (-1);
812 supply_register (regno, raw);
815 fill_gregset ((gdb_gregset_t *) gregset, -1);
816 fill_fpregset (&fpregset, -1);
818 err = td_thr_setgregs_p (&th, gregset);
820 error ("Cannot store general-purpose registers for thread %ld: %s",
821 (long) GET_THREAD (inferior_pid), thread_db_err_str (err));
822 err = td_thr_setfpregs_p (&th, &fpregset);
824 error ("Cannot store floating-point registers for thread %ld: %s",
825 (long) GET_THREAD (inferior_pid), thread_db_err_str (err));
829 thread_db_kill (void)
831 target_beneath->to_kill ();
835 thread_db_create_inferior (char *exec_file, char *allargs, char **env)
837 /* We never want to actually create the inferior! If this is ever
838 called, it means we were on the target stack when the user said
839 "run". But we don't want to be on the new inferior's target
840 stack until the libthread_db connection is ready to be made. So
841 we unpush ourselves from the stack, and then invoke
842 find_default_create_inferior, which will invoke the appropriate
843 process_stratum target to do the create. */
845 thread_db_unpush_target ();
847 find_default_create_inferior (exec_file, allargs, env);
851 thread_db_mourn_inferior (void)
853 remove_thread_event_breakpoints ();
854 thread_db_unpush_target ();
856 target_beneath->to_mourn_inferior ();
860 thread_db_thread_alive (int pid)
867 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (pid), &th);
871 err = td_thr_validate_p (&th);
878 if (target_beneath->to_thread_alive)
879 return target_beneath->to_thread_alive (pid);
885 find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
891 err = td_thr_get_info_p (th_p, &ti);
893 error ("Cannot get thread info: %s", thread_db_err_str (err));
895 pid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_pid));
897 if (! in_thread_list (pid))
898 attach_thread (pid, th_p, &ti, 1);
904 thread_db_find_new_threads (void)
908 /* Iterate over all user-space threads to discover new threads. */
909 err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
910 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
911 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
913 error ("Cannot find new threads: %s", thread_db_err_str (err));
917 thread_db_pid_to_str (int pid)
926 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (pid), &th);
928 error ("Cannot find thread %ld: %s",
929 (long) GET_THREAD (pid), thread_db_err_str (err));
931 err = td_thr_get_info_p (&th, &ti);
933 error ("Cannot get thread info for thread %ld: %s",
934 (long) GET_THREAD (pid), thread_db_err_str (err));
936 if (ti.ti_state == TD_THR_ACTIVE && ti.ti_lid != 0)
938 snprintf (buf, sizeof (buf), "Thread %ld (LWP %d)",
939 (long) ti.ti_tid, ti.ti_lid);
943 snprintf (buf, sizeof (buf), "Thread %ld (%s)",
944 (long) ti.ti_tid, thread_db_state_str (ti.ti_state));
950 if (target_beneath->to_pid_to_str (pid))
951 return target_beneath->to_pid_to_str (pid);
953 return normal_pid_to_str (pid);
957 init_thread_db_ops (void)
959 thread_db_ops.to_shortname = "multi-thread";
960 thread_db_ops.to_longname = "multi-threaded child process.";
961 thread_db_ops.to_doc = "Threads and pthreads support.";
962 thread_db_ops.to_detach = thread_db_detach;
963 thread_db_ops.to_resume = thread_db_resume;
964 thread_db_ops.to_wait = thread_db_wait;
965 thread_db_ops.to_fetch_registers = thread_db_fetch_registers;
966 thread_db_ops.to_store_registers = thread_db_store_registers;
967 thread_db_ops.to_xfer_memory = thread_db_xfer_memory;
968 thread_db_ops.to_kill = thread_db_kill;
969 thread_db_ops.to_create_inferior = thread_db_create_inferior;
970 thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
971 thread_db_ops.to_thread_alive = thread_db_thread_alive;
972 thread_db_ops.to_find_new_threads = thread_db_find_new_threads;
973 thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
974 thread_db_ops.to_stratum = thread_stratum;
975 thread_db_ops.to_has_thread_control = tc_schedlock;
976 thread_db_ops.to_magic = OPS_MAGIC;
980 _initialize_thread_db (void)
982 /* Only initialize the module if we can load libthread_db. */
983 if (thread_db_load ())
985 init_thread_db_ops ();
986 add_target (&thread_db_ops);
988 /* Add ourselves to objfile event chain. */
989 target_new_objfile_chain = target_new_objfile_hook;
990 target_new_objfile_hook = thread_db_new_objfile;