34 #ifndef USE_LIBTHREAD_DB_DIRECTLY
54 #ifndef USE_LIBTHREAD_DB_DIRECTLY
85 sigset_t *ti_sigmask_p,
86 unsigned int ti_user_flags);
91 unsigned long int modid,
93 const char ** (*td_symbol_list_p) (void);
109 return "generic 'call succeeded'";
111 return "generic error";
113 return "no thread to satisfy query";
115 return "no sync handle to satisfy query";
117 return "no LWP to satisfy query";
119 return "invalid process handle";
121 return "invalid thread handle";
123 return "invalid synchronization handle";
125 return "invalid thread agent";
127 return "invalid key";
129 return "no event message for getmsg";
131 return "FPU register set not available";
133 return "application not linked with libthread";
135 return "requested event is not supported";
137 return "capability not available";
139 return "debugger service failed";
141 return "operation not applicable to";
143 return "no thread-specific data for this thread";
145 return "malloc failed";
147 return "only part of register set was written/read";
149 return "X register set not available for this thread";
150 #ifdef HAVE_TD_VERSION
152 return "version mismatch between libthread_db and libpthread";
155 xsnprintf (buf,
sizeof (buf),
"unknown thread_db error '%d'", err);
169 return "stopped by debugger";
179 return "stopped by debugger AND blocked";
181 xsnprintf (buf,
sizeof (buf),
"unknown thread_db state %d", state);
206 fprintf (stderr,
"thread getmsg err: %s\n",
213 if (lwp->thread_known == 0)
244 warning (
"Unable to set global thread event mask: %s",
254 warning (
"Unable to get location for thread creation breakpoint: %s",
278 if (lwp->thread_known)
284 error (
"Cannot get thread handle for LWP %d: %s",
289 error (
"Cannot get thread info for LWP %d: %s",
298 warning (
"PID mismatch! Expected %ld, got %ld",
299 (
long) lwpid, (
long) ti.
ti_lid);
303 if (thread_db_use_events)
307 error (
"Cannot enable thread event reporting for %d: %s",
316 lwp->thread_known = 1;
339 warning (
"Could not attach to thread %ld (LWP %d): %s\n",
347 lwp->thread_known = 1;
350 if (thread_db_use_events)
357 error (
"Cannot enable thread event reporting for %d: %s",
408 "joined thread (0x%lx)\n", ti.
ti_tid);
444 for (loop = 0, iteration = 0; loop < 4; ++loop, ++iteration)
446 int new_thread_count = 0;
457 new_thread_count, iteration);
459 if (new_thread_count != 0)
478 const char **sym_list;
528 if (!lwp->thread_known)
530 if (!lwp->thread_known)
536 if (load_module != 0)
554 addr = (
char *) addr + offset;
567 #ifdef USE_LIBTHREAD_DB_DIRECTLY
578 tdb =
xcalloc (1,
sizeof (*tdb));
623 tdb =
xcalloc (1,
sizeof (*tdb));
631 #define CHK(required, a) \
637 debug_printf ("dlsym: %s\n", dlerror ()); \
641 proc->priv->thread_db = NULL; \
667 CHK (thread_db_use_events,
689 dladdr_to_soname (
const void *addr)
693 if (dladdr (addr, &info) != 0)
694 return info.dli_fname;
706 debug_printf (
"Trying host libthread_db library: %s.\n",
708 handle = dlopen (library, RTLD_NOW);
717 if (debug_threads && strchr (library,
'/') == NULL)
721 td_init = dlsym (handle,
"td_init");
724 const char *
const libpath = dladdr_to_soname (td_init);
727 fprintf (stderr,
"Host %s resolved to: %s.\n",
762 char *cp =
xmalloc (dir_len + 1);
764 memcpy (cp, dir, dir_len);
766 warning (
_(
"libthread-db-search-path component too long,"
767 " ignored: %s."), cp);
772 memcpy (path, dir, dir_len);
789 if (libthread_db_search_path == NULL)
792 dir_vec = dirnames_to_char_ptr_vec (libthread_db_search_path);
796 const int pdir_len =
sizeof (
"$pdir") - 1;
799 this_dir_len = strlen (this_dir);
801 if (strncmp (this_dir,
"$pdir", pdir_len) == 0
802 && (this_dir[pdir_len] ==
'\0'
803 || this_dir[pdir_len] ==
'/'))
809 else if (strcmp (this_dir,
"$sdir") == 0)
829 debug_printf (
"thread_db_load_search returning %d\n", rc);
851 thread_db_use_events = use_events;
916 #ifndef USE_LIBTHREAD_DB_DIRECTLY
917 td_ta_clear_event_p = dlsym (thread_db->
handle,
"td_ta_clear_event");
922 if (td_ta_clear_event_p != NULL)
932 (*td_ta_clear_event_p) (thread_db->
thread_agent, &events);
979 #ifndef USE_LIBTHREAD_DB_DIRECTLY
980 td_ta_delete_p = dlsym (thread_db->
handle,
"td_ta_delete");
985 if (td_ta_delete_p != NULL)
988 #ifndef USE_LIBTHREAD_DB_DIRECTLY
989 dlclose (thread_db->
handle);
1003 const char *cmd =
"set libthread-db-search-path";
1004 size_t cmd_len = strlen (cmd);
1006 if (strncmp (mon, cmd, cmd_len) == 0
1007 && (mon[cmd_len] ==
'\0'
1008 || mon[cmd_len] ==
' '))
1010 const char *cp = mon + cmd_len;
1012 if (libthread_db_search_path != NULL)
1013 free (libthread_db_search_path);
1016 while (isspace (*cp))
1021 libthread_db_search_path =
xstrdup (cp);
#define TD_THR_LOWEST_PRIORITY
struct thread_info * current_thread
static int attach_thread(const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
void monitor_output(const char *msg)
td_err_e(* td_thr_tls_get_addr_p)(const td_thrhandle_t *th, psaddr_t map_address, size_t offset, psaddr_t *address)
void free_char_ptr_vec(VEC(char_ptr)*char_ptr_vec)
int linux_proc_task_list_dir_exists(pid_t pid)
td_err_e(* td_ta_event_getmsg_p)(const td_thragent_t *ta, td_event_msg_t *msg)
static char * libthread_db_search_path
td_err_e(* td_ta_thr_iter_p)(const td_thragent_t *ta, td_thr_iter_f *callback, void *cbdata_p, td_thr_state_e state, int ti_pri, sigset_t *ti_sigmask_p, unsigned int ti_user_flags)
td_err_e(* td_thr_tlsbase_p)(const td_thrhandle_t *th, unsigned long int modid, psaddr_t *base)
td_err_e td_thr_event_enable(const td_thrhandle_t *__th, int __event)
void warning(const char *fmt,...)
struct lwp_info * find_lwp_pid(ptid_t ptid)
struct inferior_list_entry entry
int all_symbols_looked_up
struct process_info * get_thread_process(struct thread_info *thread)
static void thread_db_look_up_symbols(void)
static void switch_to_process(struct process_info *proc)
int thread_db_handle_monitor_command(char *mon)
#define get_thread_lwp(thr)
static int try_thread_db_load_1(void *handle)
td_err_e td_ta_map_lwp2thr(const td_thragent_t *__ta, lwpid_t __lwpid, td_thrhandle_t *__th)
td_err_e td_thr_tlsbase(const td_thrhandle_t *__th, unsigned long int __modid, psaddr_t *__base)
void thread_db_mourn(struct process_info *proc)
struct inferior_list_entry entry
char * xstrdup(const char *s)
ptid_t ptid_build(int pid, long lwp, long tid)
static int maybe_attach_thread(const td_thrhandle_t *th_p, td_thrinfo_t *ti_p, int *counter)
static int try_thread_db_load(const char *library)
#define td_event_addset(setp, n)
#define VEC_iterate(T, V, I, P)
const char ** td_symbol_list(void)
#define td_event_emptyset(setp)
static int thread_db_use_events
char * linux_ptrace_attach_fail_reason_string(ptid_t ptid, int err)
struct thread_db * thread_db
int td_thr_iter_f(const td_thrhandle_t *, void *)
td_err_e(* td_thr_get_info_p)(const td_thrhandle_t *th, td_thrinfo_t *infop)
ptid_t pid_to_ptid(int pid)
struct td_thragent td_thragent_t
static int find_one_thread(ptid_t)
int look_up_one_symbol(const char *name, CORE_ADDR *addrp, int may_ask_gdb)
td_err_e td_ta_delete(td_thragent_t *__ta)
td_err_e td_ta_clear_event(const td_thragent_t *__ta, td_thr_events_t *__event)
static int try_thread_db_load_from_sdir(void)
#define td_event_fillset(setp)
static int thread_db_create_event(CORE_ADDR where)
td_err_e td_ta_event_getmsg(const td_thragent_t *__ta, td_event_msg_t *__msg)
static int thread_db_load_search(void)
td_thragent_t * thread_agent
td_err_e(* td_ta_map_lwp2thr_p)(const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
struct process_info * current_process(void)
struct process_info_private * priv
struct inferior_list all_threads
static int try_thread_db_load_from_dir(const char *dir, size_t dir_len)
#define TD_THR_ANY_USER_FLAGS
td_err_e(* td_thr_event_enable_p)(const td_thrhandle_t *th, int event)
struct inferior_list_entry * find_inferior_id(struct inferior_list *list, ptid_t id)
int ptid_get_pid(ptid_t ptid)
int thread_db_get_tls_address(struct thread_info *thread, CORE_ADDR offset, CORE_ADDR load_module, CORE_ADDR *address)
int linux_attach_lwp(ptid_t ptid)
td_err_e td_ta_thr_iter(const td_thragent_t *__ta, td_thr_iter_f *__callback, void *__cbdata_p, td_thr_state_e __state, int __ti_pri, sigset_t *__ti_sigmask_p, unsigned int __ti_user_flags)
int thread_db_look_up_one_symbol(const char *name, CORE_ADDR *addrp)
static void thread_db_find_new_threads(void)
td_err_e td_ta_set_event(const td_thragent_t *__ta, td_thr_events_t *__event)
int xsnprintf(char *str, size_t size, const char *format,...)
td_err_e(* td_ta_new_p)(struct ps_prochandle *ps, td_thragent_t **ta)
td_err_e td_thr_get_info(const td_thrhandle_t *__th, td_thrinfo_t *__infop)
td_err_e td_ta_new(struct ps_prochandle *__ps, td_thragent_t **__ta)
static const char * thread_db_err_str(td_err_e err)
td_err_e td_ta_event_addr(const td_thragent_t *__ta, td_event_e __event, td_notify_t *__ptr)
static void disable_thread_event_reporting(struct process_info *proc)
td_err_e(* td_ta_set_event_p)(const td_thragent_t *ta, td_thr_events_t *event)
static int find_new_threads_callback(const td_thrhandle_t *th_p, void *data)
td_err_e td_thr_tls_get_addr(const td_thrhandle_t *__th, psaddr_t __map_address, size_t __offset, psaddr_t *__address)
const char **(* td_symbol_list_p)(void)
static void remove_thread_event_breakpoints(struct process_info *proc)
void thread_db_detach(struct process_info *proc)
struct breakpoint * set_breakpoint_at(CORE_ADDR where, int(*handler)(CORE_ADDR))
static int thread_db_enable_reporting(void)
long ptid_get_lwp(ptid_t ptid)
const td_thrhandle_t * th_p
static int any_thread_of(struct inferior_list_entry *entry, void *args)
void debug_printf(const char *fmt,...)
td_err_e(* td_ta_event_addr_p)(const td_thragent_t *ta, td_event_e event, td_notify_t *ptr)
struct ps_prochandle proc_handle
PTR xcalloc(size_t number, size_t size)
void error(const char *fmt,...)
#define LIBTHREAD_DB_SEARCH_PATH
int delete_breakpoint(struct breakpoint *todel)
int thread_db_init(int use_events)
struct inferior_list_entry * find_inferior(struct inferior_list *list, int(*func)(struct inferior_list_entry *, void *), void *arg)
struct breakpoint * td_create_bp