186 sigset_t *ti_sigmask_p,
187 unsigned int ti_user_flags);
206 unsigned long int modid,
234 info =
xcalloc (1,
sizeof (*info));
244 thread_db_list = info;
257 for (info = thread_db_list; info; info = info->
next)
258 if (pid == info->
pid)
276 for (info = thread_db_list; info; info_prev = info, info = info->
next)
277 if (pid == info->pid)
283 if (info->handle != NULL)
284 dlclose (info->handle);
286 xfree (info->filename);
291 thread_db_list = info->
next;
324 return "generic 'call succeeded'";
326 return "generic error";
328 return "no thread to satisfy query";
330 return "no sync handle to satisfy query";
332 return "no LWP to satisfy query";
334 return "invalid process handle";
336 return "invalid thread handle";
338 return "invalid synchronization handle";
340 return "invalid thread agent";
342 return "invalid key";
344 return "no event message for getmsg";
346 return "FPU register set not available";
348 return "application not linked with libthread";
350 return "requested event is not supported";
352 return "capability not available";
354 return "debugger service failed";
356 return "operation not applicable to";
358 return "no thread-specific data for this thread";
360 return "malloc failed";
362 return "only part of register set was written/read";
364 return "X register set not available for this thread";
365 #ifdef THREAD_DB_HAS_TD_NOTALLOC
367 return "thread has not yet allocated TLS for given module";
369 #ifdef THREAD_DB_HAS_TD_VERSION
371 return "versions of libpthread and libthread_db do not match";
373 #ifdef THREAD_DB_HAS_TD_NOTLS
375 return "there is no TLS segment in the given module";
378 snprintf (buf,
sizeof (buf),
"unknown thread_db error '%d'", err);
389 int pid = * (
int *) args;
394 return thread->
priv != NULL;
431 error (
_(
"Cannot find user-level thread for LWP %ld: %s"),
436 error (
_(
"thread_get_info_callback: cannot get thread info: %s"),
471 void *sym = dlsym (handle, name);
473 warning (
_(
"Symbol \"%s\" not found in libthread_db: %s"),
500 (bfd_get_sign_extend_vma (
exec_bfd) > 0
519 int err, got, retval = 0;
522 if (version_msym.
minsym == NULL)
527 if (err == 0 && memchr (version, 0, got) == &version[got -1])
531 retval = (sscanf (version,
"%d.%d", &major, &minor) == 2
532 && (major < ver_major_min
533 || (major == ver_major_min && minor < ver_minor_min)));
573 warning (
_(
"Unable to set global thread event mask: %s"),
587 warning (
_(
"Unable to get location for thread creation breakpoint: %s"),
596 warning (
_(
"Unable to get location for thread death breakpoint: %s"),
621 "Warning: thread_db_find_new_threads_silently: ");
642 _(
"Warning: couldn't activate thread debugging "
643 "using libthread_db: "));
661 if (dladdr (addr, &info) != 0)
662 return info.dli_fname;
687 warning (
_(
"Cannot initialize libthread_db: %s"),
710 #ifdef THREAD_DB_HAS_TD_VERSION
724 "td_ta_map_lwp2thr");
798 if (thread_db_list->
next == NULL)
819 _(
"Trying host libthread_db library: %s.\n"),
822 if (check_auto_load_safe)
824 if (access (library, R_OK) != 0)
835 "library \"%s\" from explicit "
841 handle = dlopen (library, RTLD_NOW);
853 td_init = dlsym (handle,
"td_init");
867 if (strchr (library,
'/') != NULL)
891 if (obj_name[0] !=
'/')
893 warning (
_(
"Expected absolute pathname for libpthread in the"
894 " inferior, but got %s."), obj_name);
898 path =
xmalloc (strlen (obj_name) + (subdir ? strlen (subdir) + 1 : 0)
902 strcpy (path, obj_name);
903 cp = strrchr (path,
'/');
979 memcpy (path, dir, dir_len);
1006 const int pdir_len =
sizeof (
"$pdir") - 1;
1007 size_t this_dir_len;
1009 this_dir_len = strlen (this_dir);
1011 if (strncmp (this_dir,
"$pdir", pdir_len) == 0
1012 && (this_dir[pdir_len] ==
'\0'
1013 || this_dir[pdir_len] ==
'/'))
1015 char *subdir = NULL;
1016 struct cleanup *free_subdir_cleanup
1019 if (this_dir[pdir_len] ==
'/')
1021 subdir =
xmalloc (strlen (this_dir));
1023 strcpy (subdir, this_dir + pdir_len + 1);
1030 else if (strcmp (this_dir,
"$sdir") == 0)
1051 _(
"thread_db_load_search returning %d\n"), rc);
1098 warning (
_(
"Unable to find libthread_db matching inferior's thread"
1099 " library, thread debugging will not be available."));
1138 for (i = 1; i < NSIG; i++)
1140 if (sigismember (&mask, i))
1205 warning (
_ (
"Target and debugger are in different PID "
1206 "namespaces; thread lists and other data are "
1207 "likely unreliable"));
1264 if (tp->
priv != NULL)
1344 error (
_(
"Cannot enable thread event reporting for %s: %s"),
1395 target_beneath->
to_detach (target_beneath, args, from_tty);
1401 if (!thread_db_list)
1465 error (
_(
"Cannot get thread event message: %s"),
1487 error (
_(
"Spurious thread death event."));
1494 error (
_(
"Spurious thread event."));
1508 ptid = beneath->
to_wait (beneath, ptid, ourstatus, options);
1528 if (!thread_db_list)
1538 && ourstatus->
value.
sig == GDB_SIGNAL_TRAP)
1562 if (!thread_db_list)
1584 error (
_(
"find_new_threads_callback: cannot get thread info: %s"),
1597 "thread_db: skipping exited and "
1598 "joined thread (0x%lx)\n", ti.
ti_tid);
1618 error (
_(
"Cannot enable thread event reporting for LWP %d: %s"),
1632 if (tgid != -1 && tgid != info->
pid)
1638 if (tp == NULL || tp->
priv == NULL)
1693 "Warning: find_new_threads_once: ");
1701 _(
"Found %d new threads in iteration %d.\n"),
1733 for (i = 0, loop = 0; loop < 4 && err ==
TD_OK; ++i, ++loop)
1782 if (thread == NULL || thread->
executing)
1822 if (thread_info != NULL && thread_info->
priv != NULL)
1824 static char buf[64];
1828 snprintf (buf,
sizeof (buf),
"Thread 0x%lx (LWP %ld)",
1845 if (info->
priv == NULL)
1873 if (thread_info != NULL && thread_info->
priv != NULL)
1887 _(
"No TLS library support"));
1902 _(
"TLS load module not found"));
1912 address = (
char *) address + offset;
1915 #ifdef THREAD_DB_HAS_TD_NOTALLOC
1922 _(
"TLS not allocated yet"));
1933 return (bfd_get_sign_extend_vma (
exec_bfd) > 0
1953 ptid_t ptid,
int step,
enum gdb_signal signo)
1969 beneath->
to_resume (beneath, ptid, step, signo);
1996 const char *cs = args ? args :
"";
1998 unsigned info_count, unique_filenames;
1999 size_t max_filename_len, max_pids_len, pids_len;
2006 error (
_(
"'info auto-load libthread-db' does not accept any parameters"));
2009 for (info = thread_db_list; info; info = info->
next)
2013 array =
xmalloc (
sizeof (*array) * info_count);
2017 for (info = thread_db_list; info; info = info->
next)
2019 array[info_count++] = info;
2023 qsort (array, info_count,
sizeof (*array),
2029 unique_filenames = 0;
2030 max_filename_len = 0;
2033 for (i = 0; i < info_count; i++)
2036 size_t this_pid_len;
2038 for (this_pid_len = 0; pid != 0; pid /= 10)
2041 if (i == 0 || strcmp (array[i - 1]->filename, array[i]->filename) != 0)
2044 max_filename_len =
max (max_filename_len,
2045 strlen (array[i]->filename));
2049 pids_len -= strlen (
", ");
2050 max_pids_len =
max (max_pids_len, pids_len);
2054 pids_len += this_pid_len + strlen (
", ");
2058 pids_len -= strlen (
", ");
2059 max_pids_len =
max (max_pids_len, pids_len);
2068 "LinuxThreadDbTable");
2075 pids =
xmalloc (max_pids_len + 1);
2079 for (i = 0; i < info_count;)
2090 if (pids_end != pids)
2095 pids_end +=
xsnprintf (pids_end, &pids[max_pids_len + 1] - pids_end,
2096 "%u", array[i]->
pid);
2097 gdb_assert (pids_end < &pids[max_pids_len + 1]);
2111 if (info_count == 0)
2158 Set search path for libthread_db."),
_(
"\
2159 Show the current search path or libthread_db."),
_(
"\
2160 This path is used to search for libthread_db to be loaded into \
2162 Its value is a colon (':') separate list of directories to search.\n\
2163 Setting the search path to an empty list resets it to its default value."),
2170 Set libthread-db debugging."),
_(
"\
2171 Show libthread-db debugging."),
_(
"\
2172 When non-zero, libthread-db debugging is enabled."),
2179 Enable or disable auto-loading of inferior specific libthread_db."),
_(
"\
2180 Show whether auto-loading inferior specific libthread_db is enabled."),
_(
"\
2181 If enabled, libthread_db will be searched in 'set libthread-db-search-path'\n\
2182 locations to load libthread_db compatible with the inferior.\n\
2183 Standard system libthread_db still gets loaded even with this option off.\n\
2184 This options has security implications for untrusted inferiors."),
2190 _(
"Print the list of loaded inferior specific libthread_db.\n\
2191 Usage: info auto-load libthread-db"),
td_err_e(* td_ta_new_p)(struct ps_prochandle *ps, td_thragent_t **ta)
struct gdbarch * target_gdbarch(void)
static int try_thread_db_load_1(struct thread_db_info *info)
void linux_unstop_all_lwps(void)
CORE_ADDR td_create_bp_addr
static void disable_thread_event_reporting(struct thread_db_info *info)
static void thread_db_resume(struct target_ops *ops, ptid_t ptid, int step, enum gdb_signal signo)
#define TD_THR_LOWEST_PRIORITY
static void thread_db_find_new_threads_1(ptid_t ptid)
struct private_thread_info * priv
#define target_has_registers
static const char * dladdr_to_soname(const void *addr)
char * gdb_realpath(const char *filename)
struct thread_info * find_thread_ptid(ptid_t ptid)
td_thragent_t * thread_agent
static int auto_load_thread_db
static int update_thread_core(struct lwp_info *info, void *closure)
int linux_proc_task_list_dir_exists(pid_t pid)
static struct target_ops thread_db_ops
void add_setshow_zuinteger_cmd(const char *name, enum command_class theclass, unsigned int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_sfunc_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
static int thread_db_find_new_threads_silently(ptid_t ptid)
int ptid_equal(ptid_t ptid1, ptid_t ptid2)
void lin_thread_get_thread_signals(sigset_t *set)
struct regcache * get_thread_regcache(ptid_t ptid)
td_err_e(* td_ta_map_lwp2thr_p)(const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
void delete_thread(ptid_t)
static void thread_db_mourn_inferior(struct target_ops *ops)
struct objfile * separate_debug_objfile_backlink
struct gdbarch * get_regcache_arch(const struct regcache *regcache)
#define BMSYMBOL_VALUE_ADDRESS(symbol)
void warning(const char *fmt,...)
CORE_ADDR td_death_bp_addr
char *(* to_pid_to_str)(struct target_ops *, ptid_t) TARGET_DEFAULT_FUNC(default_pid_to_str)
static int try_thread_db_load_from_dir(const char *dir, size_t dir_len)
int lin_lwp_attach_lwp(ptid_t ptid)
struct cleanup * make_cleanup_ui_out_table_begin_end(struct ui_out *ui_out, int nr_cols, int nr_rows, const char *tblid)
void push_target(struct target_ops *t)
static void * verbose_dlsym(void *handle, const char *name)
char *(* to_extra_thread_info)(struct target_ops *, struct thread_info *) TARGET_DEFAULT_RETURN(NULL)
static void init_thread_db_ops(void)
static void thread_db_update_thread_list_td_ta_thr_iter(struct target_ops *ops)
struct ui_file * gdb_stdout
struct thread_info * add_thread_with_info(ptid_t ptid, struct private_thread_info *)
int unpush_target(struct target_ops *t)
static void check_thread_signals(void)
#define target_supports_stopped_by_sw_breakpoint()
struct cmd_list_element ** auto_load_set_cmdlist_get(void)
static int have_threads(ptid_t ptid)
#define target_can_run(t)
static void info_auto_load_libthread_db(char *args, int from_tty)
char auto_load_info_scripts_pattern_nl[]
int need_stale_parent_threads_check
struct breakpoint * create_thread_event_breakpoint(struct gdbarch *gdbarch, CORE_ADDR address)
ptid_t(* to_wait)(struct target_ops *, ptid_t, struct target_waitstatus *, int TARGET_DEBUG_PRINTER(target_debug_print_options)) TARGET_DEFAULT_NORETURN(noprocess())
char * target_pid_to_str(ptid_t ptid)
static int have_threads_callback(struct thread_info *thread, void *args)
static ptid_t thread_db_wait(struct target_ops *ops, ptid_t ptid, struct target_waitstatus *ourstatus, int options)
td_err_e(* td_ta_set_event_p)(const td_thragent_t *ta, td_thr_events_t *event)
static int info_auto_load_libthread_db_compare(const void *ap, const void *bp)
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)
void ui_out_text(struct ui_out *uiout, const char *string)
int thread_db_notice_clone(ptid_t parent, ptid_t child)
static void thread_from_lwp(ptid_t ptid)
ptid_t ptid_build(int pid, long lwp, long tid)
void null_cleanup(void *arg)
struct observer * observer_attach_inferior_created(observer_inferior_created_ftype *f)
int in_thread_list(ptid_t ptid)
initialize_file_ftype _initialize_thread_db
#define td_event_addset(setp, n)
struct thread_info * iterate_over_threads(thread_callback_func, void *)
static void detach_thread(ptid_t ptid)
struct cmd_list_element * setlist
#define ALL_OBJFILES(obj)
static int try_thread_db_load_from_pdir_1(struct objfile *obj, const char *subdir)
#define VEC_iterate(T, V, I, P)
CORE_ADDR gdbarch_decr_pc_after_break(struct gdbarch *gdbarch)
static int inferior_has_bug(const char *ver_symbol, int ver_major_min, int ver_minor_min)
static int thread_db_load(void)
#define CATCH(EXCEPTION, MASK)
static td_err_e enable_thread_event(int event, CORE_ADDR *bp)
#define td_event_emptyset(setp)
int linux_supports_traceclone(void)
struct target_ops current_target
void initialize_file_ftype(void)
struct thread_db_info * info
int linux_ns_same(pid_t pid, enum linux_ns_type type)
struct cleanup * make_cleanup_ui_out_tuple_begin_end(struct ui_out *uiout, const char *id)
void remove_thread_event_breakpoints(void)
int td_thr_iter_f(const td_thrhandle_t *, void *)
void complete_target_initialization(struct target_ops *t)
void fprintf_filtered(struct ui_file *stream, const char *format,...)
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t err
const char * skip_spaces_const(const char *chp)
struct thread_info * any_live_thread_of_process(int pid)
CORE_ADDR gdbarch_convert_from_func_ptr_addr(struct gdbarch *gdbarch, CORE_ADDR addr, struct target_ops *targ)
void fprintf_unfiltered(struct ui_file *stream, const char *format,...)
void(* to_resume)(struct target_ops *, ptid_t, int TARGET_DEBUG_PRINTER(target_debug_print_step), enum gdb_signal) TARGET_DEFAULT_NORETURN(noprocess())
struct cmd_list_element * showlist
void ui_out_message(struct ui_out *uiout, int verbosity, const char *format,...)
td_err_e(* td_thr_event_enable_p)(const td_thrhandle_t *th, int event)
struct cmd_list_element * add_cmd(const char *name, enum command_class theclass, cmd_cfunc_ftype *fun, const char *doc, struct cmd_list_element **list)
CORE_ADDR(* to_get_thread_local_address)(struct target_ops *ops, ptid_t ptid, CORE_ADDR load_module_addr, CORE_ADDR offset) TARGET_DEFAULT_NORETURN(generic_tls_error())
static void enable_thread_event_reporting(void)
struct cleanup * make_cleanup(make_cleanup_ftype *function, void *arg)
union target_waitstatus::@161 value
struct td_thragent td_thragent_t
int linux_proc_get_tgid(pid_t lwpid)
struct cleanup * make_cleanup_free_char_ptr_vec(VEC(char_ptr)*char_ptr_vec)
enum gdb_signal gdb_signal_from_host(int)
struct ps_prochandle proc_handle
static int find_new_threads_callback(const td_thrhandle_t *th_p, void *data)
#define td_event_fillset(setp)
static sigset_t thread_print_set
int linux_common_core_of_thread(ptid_t ptid)
void exception_fprintf(struct ui_file *file, struct gdb_exception e, const char *prefix,...)
static int thread_db_load_search(void)
#define target_has_execution
static void thread_db_inferior_created(struct target_ops *target, int from_tty)
static void thread_db_update_thread_list(struct target_ops *ops)
void linux_stop_and_wait_all_lwps(void)
struct target_ops * find_target_beneath(struct target_ops *t)
td_err_e(* td_thr_tls_get_addr_p)(const td_thrhandle_t *th, psaddr_t map_address, size_t offset, psaddr_t *address)
int file_is_auto_load_safe(const char *filename, const char *debug_fmt,...)
static struct thread_db_info * add_thread_db_info(void *handle)
static struct thread_info * new_thread(ptid_t ptid)
static int try_thread_db_load(const char *library, int check_auto_load_safe)
void printf_unfiltered(const char *format,...)
struct cmd_list_element * setdebuglist
void(* to_detach)(struct target_ops *ops, const char *, int) TARGET_DEFAULT_IGNORE()
const char * objfile_name(const struct objfile *objfile)
struct ui_file * gdb_stdlog
td_err_e(* td_thr_get_info_p)(const td_thrhandle_t *th, td_thrinfo_t *infop)
static int find_new_threads_once(struct thread_db_info *info, int iteration, td_err_e *errp)
td_err_e(* td_ta_event_getmsg_p)(const td_thragent_t *ta, td_event_msg_t *msg)
void check_for_thread_db(void)
#define TD_THR_ANY_USER_FLAGS
static void delete_thread_db_info(int pid)
td_err_e(* td_thr_tlsbase_p)(const td_thrhandle_t *th, unsigned long int modid, psaddr_t *base)
int ptid_get_pid(ptid_t ptid)
static ptid_t thread_db_get_ada_task_ptid(struct target_ops *self, long lwp, long thread)
static void show_auto_load_thread_db(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
void(* to_mourn_inferior)(struct target_ops *) TARGET_DEFAULT_FUNC(default_mourn_inferior)
static void thread_db_find_new_threads_2(ptid_t ptid, int until_no_new)
int xsnprintf(char *str, size_t size, const char *format,...)
static char * thread_db_pid_to_str(struct target_ops *ops, ptid_t ptid)
static void thread_db_detach(struct target_ops *ops, const char *args, int from_tty)
enum target_waitkind kind
struct ui_file * gdb_stderr
CORE_ADDR regcache_read_pc(struct regcache *regcache)
struct minimal_symbol * minsym
char * safe_strerror(int)
td_err_e(* td_ta_clear_event_p)(const td_thragent_t *ta, td_thr_events_t *event)
int libpthread_name_p(const char *name)
void ui_out_table_header(struct ui_out *uiout, int width, enum ui_align alignment, const char *col_name, const char *colhdr)
static void show_libthread_db_debug(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
static void record_thread(struct thread_db_info *info, struct thread_info *tp, ptid_t ptid, const td_thrhandle_t *th_p, const td_thrinfo_t *ti_p)
struct thread_db_info * thread_db_list
mach_port_t kern_return_t mach_port_t msgports mach_port_t kern_return_t pid_t pid mach_port_t kern_return_t mach_port_t task mach_port_t kern_return_t int procinfo_t mach_msg_type_number_t data_t mach_msg_type_number_t threadwaitsCnt mach_port_t kern_return_t data_t mach_msg_type_number_t procenvCnt mach_port_t kern_return_t pidarray_t pids
static int has_libpthread(void)
static int thread_db_use_events(void)
const char * to_shortname
static char * libthread_db_search_path
static void check_event(ptid_t ptid)
static int try_thread_db_load_from_pdir(const char *subdir)
static CORE_ADDR thread_db_get_thread_local_address(struct target_ops *ops, ptid_t ptid, CORE_ADDR lm, CORE_ADDR offset)
static void set_libthread_db_search_path(char *ignored, int from_tty, struct cmd_list_element *c)
static int try_thread_db_load_from_sdir(void)
struct observer * observer_attach_new_objfile(observer_new_objfile_ftype *f)
long ptid_get_lwp(ptid_t ptid)
struct cmd_list_element * showdebuglist
int signal_print_update(int signo, int state)
td_err_e(* td_ta_event_addr_p)(const td_thragent_t *ta, td_event_e event, td_notify_t *ptr)
void ui_out_field_string(struct ui_out *uiout, const char *fldname, const char *string)
static void update_thread_state(struct private_thread_info *priv, const td_thrinfo_t *ti_p)
struct thread_db_info * next
static unsigned int libthread_db_debug
int to_has_thread_control
static void thread_db_new_objfile(struct objfile *objfile)
void ui_out_table_body(struct ui_out *uiout)
const td_thrhandle_t * th_p
int signal_stop_update(int signo, int state)
struct ui_out * current_uiout
struct cmd_list_element ** auto_load_show_cmdlist_get(void)
static void check_pid_namespace_match(void)
void(* to_update_thread_list)(struct target_ops *) TARGET_DEFAULT_IGNORE()
static int attach_thread(ptid_t ptid, const td_thrhandle_t *th_p, const td_thrinfo_t *ti_p)
struct lwp_info * iterate_over_lwps(ptid_t filter, iterate_over_lwps_ftype callback, void *data)
struct bound_minimal_symbol lookup_minimal_symbol(const char *name, const char *sfile, struct objfile *objf)
PTR xcalloc(size_t number, size_t size)
td_err_e(* td_init_p)(void)
static char * thread_db_extra_thread_info(struct target_ops *self, struct thread_info *info)
ptid_t(* to_get_ada_task_ptid)(struct target_ops *, long lwp, long thread) TARGET_DEFAULT_FUNC(default_get_ada_task_ptid)
int target_read_string(CORE_ADDR memaddr, char **string, int len, int *errnop)
void error(const char *fmt,...)
#define LIBTHREAD_DB_SEARCH_PATH
void add_setshow_optional_filename_cmd(const char *name, enum command_class theclass, char **var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_sfunc_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t int int rusage_t pid_t pid
void throw_error(enum errors error, const char *fmt,...)
static struct thread_db_info * get_thread_db_info(int pid)
struct target_ops * beneath
void do_cleanups(struct cleanup *old_chain)
void add_setshow_boolean_cmd(const char *name, enum command_class theclass, int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_sfunc_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
static sigset_t thread_stop_set
struct cmd_list_element ** auto_load_info_cmdlist_get(void)
static char * thread_db_err_str(td_err_e err)
static int thread_signals