123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 |
- Support loading two libthread_db DSOs. In this case, the LinuxThreads
- and NPTL ones.
- Index: gdb-6.3/gdb/thread-db.c
- ===================================================================
- --- gdb-6.3.orig/gdb/thread-db.c 2004-11-10 10:46:24.000000000 -0500
- +++ gdb-6.3/gdb/thread-db.c 2004-11-10 11:22:34.858812426 -0500
- @@ -79,53 +79,63 @@ static td_thragent_t *thread_agent;
-
- /* Pointers to the libthread_db functions. */
-
- -static td_err_e (*td_init_p) (void);
- +struct thread_db_pointers
- +{
- + const char *filename;
- +
- + td_err_e (*td_init_p) (void);
-
- -static td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
- - td_thragent_t **ta);
- -static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
- - td_thrhandle_t *__th);
- -static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
- - lwpid_t lwpid, td_thrhandle_t *th);
- -static 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);
- -static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
- - td_event_e event, td_notify_t *ptr);
- -static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
- - td_thr_events_t *event);
- -static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
- - td_event_msg_t *msg);
- -
- -static td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
- -static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
- - td_thrinfo_t *infop);
- -static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
- - gdb_prfpregset_t *regset);
- -static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
- - prgregset_t gregs);
- -static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
- - const gdb_prfpregset_t *fpregs);
- -static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
- - prgregset_t gregs);
- -static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
- - int event);
- -
- -static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
- - void *map_address,
- - size_t offset, void **address);
- + td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
- + td_thragent_t **ta);
- + td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
- + td_thrhandle_t *__th);
- + td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
- + lwpid_t lwpid, td_thrhandle_t *th);
- +
- + 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_ta_event_addr_p) (const td_thragent_t *ta,
- + td_event_e event, td_notify_t *ptr);
- + td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
- + td_thr_events_t *event);
- + td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
- + td_event_msg_t *msg);
- +
- + td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
- + td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
- + td_thrinfo_t *infop);
- + td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
- + gdb_prfpregset_t *regset);
- + td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
- + prgregset_t gregs);
- + td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
- + const gdb_prfpregset_t *fpregs);
- + td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
- + prgregset_t gregs);
- + td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
- + int event);
- +
- + td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
- + void *map_address,
- + size_t offset, void **address);
- +
- + struct thread_db_pointers *next;
- +};
-
- /* Location of the thread creation event breakpoint. The code at this
- location in the child process will be called by the pthread library
- whenever a new thread is created. By setting a special breakpoint
- at this location, GDB can detect when a new thread is created. We
- obtain this location via the td_ta_event_addr call. */
- -static CORE_ADDR td_create_bp_addr;
- +CORE_ADDR td_create_bp_addr;
-
- /* Location of the thread death event breakpoint. */
- -static CORE_ADDR td_death_bp_addr;
- +CORE_ADDR td_death_bp_addr;
- +
- +static struct thread_db_pointers *current_pointers, *all_pointers;
-
- /* Prototypes for local functions. */
- static void thread_db_find_new_threads (void);
- @@ -262,7 +272,7 @@ thread_get_info_callback (const td_thrha
- struct thread_info *thread_info;
- ptid_t thread_ptid;
-
- - err = td_thr_get_info_p (thp, &ti);
- + err = current_pointers->td_thr_get_info_p (thp, &ti);
- if (err != TD_OK)
- error ("thread_get_info_callback: cannot get thread info: %s",
- thread_db_err_str (err));
- @@ -316,8 +326,9 @@ thread_db_map_id2thr (struct thread_info
- if (thread_info->private->th_valid)
- return;
-
- - err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (thread_info->ptid),
- - &thread_info->private->th);
- + err = current_pointers->td_ta_map_id2thr_p (thread_agent,
- + GET_THREAD (thread_info->ptid),
- + &thread_info->private->th);
- if (err != TD_OK)
- {
- if (fatal)
- @@ -340,8 +351,8 @@ thread_db_get_info (struct thread_info *
- if (!thread_info->private->th_valid)
- thread_db_map_id2thr (thread_info, 1);
-
- - err =
- - td_thr_get_info_p (&thread_info->private->th, &thread_info->private->ti);
- + err = current_pointers->td_thr_get_info_p (&thread_info->private->th,
- + &thread_info->private->ti);
- if (err != TD_OK)
- error ("thread_db_get_info: cannot get thread info: %s",
- thread_db_err_str (err));
- @@ -365,7 +376,8 @@ thread_from_lwp (ptid_t ptid)
-
- gdb_assert (is_lwp (ptid));
-
- - err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
- + err = current_pointers->td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid),
- + &th);
- if (err != TD_OK)
- error ("Cannot find user-level thread for LWP %ld: %s",
- GET_LWP (ptid), thread_db_err_str (err));
- @@ -420,85 +432,102 @@ verbose_dlsym (void *handle, const char
- return sym;
- }
-
- -static int
- -thread_db_load (void)
- +static struct thread_db_pointers *
- +thread_db_load (const char *name)
- {
- + struct thread_db_pointers *ptrs;
- + Dl_info info;
- void *handle;
- td_err_e err;
-
- - handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
- + ptrs = xcalloc (1, sizeof (struct thread_db_pointers));
- +
- + handle = dlopen (name, RTLD_NOW);
- if (handle == NULL)
- {
- - fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
- - LIBTHREAD_DB_SO, dlerror ());
- - fprintf_filtered (gdb_stderr,
- - "GDB will not be able to debug pthreads.\n\n");
- + if (all_pointers == NULL)
- + {
- + fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
- + name, dlerror ());
- + fprintf_filtered (gdb_stderr,
- + "GDB will not be able to debug pthreads.\n\n");
- + }
- return 0;
- }
-
- /* Initialize pointers to the dynamic library functions we will use.
- Essential functions first. */
-
- - td_init_p = verbose_dlsym (handle, "td_init");
- - if (td_init_p == NULL)
- + ptrs->td_init_p = verbose_dlsym (handle, "td_init");
- + if (ptrs->td_init_p == NULL)
- return 0;
-
- - td_ta_new_p = verbose_dlsym (handle, "td_ta_new");
- - if (td_ta_new_p == NULL)
- + ptrs->td_ta_new_p = verbose_dlsym (handle, "td_ta_new");
- + if (ptrs->td_ta_new_p == NULL)
- return 0;
-
- - td_ta_map_id2thr_p = verbose_dlsym (handle, "td_ta_map_id2thr");
- - if (td_ta_map_id2thr_p == NULL)
- + ptrs->td_ta_map_id2thr_p = verbose_dlsym (handle, "td_ta_map_id2thr");
- + if (ptrs->td_ta_map_id2thr_p == NULL)
- return 0;
-
- - td_ta_map_lwp2thr_p = verbose_dlsym (handle, "td_ta_map_lwp2thr");
- - if (td_ta_map_lwp2thr_p == NULL)
- + ptrs->td_ta_map_lwp2thr_p = verbose_dlsym (handle, "td_ta_map_lwp2thr");
- + if (ptrs->td_ta_map_lwp2thr_p == NULL)
- return 0;
-
- - td_ta_thr_iter_p = verbose_dlsym (handle, "td_ta_thr_iter");
- - if (td_ta_thr_iter_p == NULL)
- + ptrs->td_ta_thr_iter_p = verbose_dlsym (handle, "td_ta_thr_iter");
- + if (ptrs->td_ta_thr_iter_p == NULL)
- return 0;
-
- - td_thr_validate_p = verbose_dlsym (handle, "td_thr_validate");
- - if (td_thr_validate_p == NULL)
- + ptrs->td_thr_validate_p = verbose_dlsym (handle, "td_thr_validate");
- + if (ptrs->td_thr_validate_p == NULL)
- return 0;
-
- - td_thr_get_info_p = verbose_dlsym (handle, "td_thr_get_info");
- - if (td_thr_get_info_p == NULL)
- + ptrs->td_thr_get_info_p = verbose_dlsym (handle, "td_thr_get_info");
- + if (ptrs->td_thr_get_info_p == NULL)
- return 0;
-
- - td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs");
- - if (td_thr_getfpregs_p == NULL)
- + ptrs->td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs");
- + if (ptrs->td_thr_getfpregs_p == NULL)
- return 0;
-
- - td_thr_getgregs_p = verbose_dlsym (handle, "td_thr_getgregs");
- - if (td_thr_getgregs_p == NULL)
- + ptrs->td_thr_getgregs_p = verbose_dlsym (handle, "td_thr_getgregs");
- + if (ptrs->td_thr_getgregs_p == NULL)
- return 0;
-
- - td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs");
- - if (td_thr_setfpregs_p == NULL)
- + ptrs->td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs");
- + if (ptrs->td_thr_setfpregs_p == NULL)
- return 0;
-
- - td_thr_setgregs_p = verbose_dlsym (handle, "td_thr_setgregs");
- - if (td_thr_setgregs_p == NULL)
- + ptrs->td_thr_setgregs_p = verbose_dlsym (handle, "td_thr_setgregs");
- + if (ptrs->td_thr_setgregs_p == NULL)
- return 0;
-
- /* Initialize the library. */
- - err = td_init_p ();
- + err = ptrs->td_init_p ();
- if (err != TD_OK)
- {
- warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
- + xfree (ptrs);
- return 0;
- }
-
- /* These are not essential. */
- - td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
- - td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
- - td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
- - td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
- - td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
- + ptrs->td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
- + ptrs->td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
- + ptrs->td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
- + ptrs->td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
- + ptrs->td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
- +
- + if (dladdr (ptrs->td_ta_new_p, &info) != 0)
- + ptrs->filename = info.dli_fname;
- +
- + /* Try dlinfo? */
- +
- + if (ptrs->filename == NULL)
- + /* Paranoid - don't let a NULL path slip through. */
- + ptrs->filename = name;
-
- - return 1;
- + return ptrs;
- }
-
- static td_err_e
- @@ -508,7 +537,7 @@ enable_thread_event (td_thragent_t *thre
- td_err_e err;
-
- /* Get the breakpoint address for thread EVENT. */
- - err = td_ta_event_addr_p (thread_agent, event, ¬ify);
- + err = current_pointers->td_ta_event_addr_p (thread_agent, event, ¬ify);
- if (err != TD_OK)
- return err;
-
- @@ -534,8 +563,10 @@ enable_thread_event_reporting (void)
-
- /* We cannot use the thread event reporting facility if these
- functions aren't available. */
- - if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
- - || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
- + if (current_pointers->td_ta_event_addr_p == NULL
- + || current_pointers->td_ta_set_event_p == NULL
- + || current_pointers->td_ta_event_getmsg_p == NULL
- + || current_pointers->td_thr_event_enable_p == NULL)
- return;
-
- /* Set the process wide mask saying which events we're interested in. */
- @@ -552,7 +583,7 @@ enable_thread_event_reporting (void)
- #endif
- td_event_addset (&events, TD_DEATH);
-
- - err = td_ta_set_event_p (thread_agent, &events);
- + err = current_pointers->td_ta_set_event_p (thread_agent, &events);
- if (err != TD_OK)
- {
- warning ("Unable to set global thread event mask: %s",
- @@ -592,7 +623,7 @@ disable_thread_event_reporting (void)
- /* Set the process wide mask saying we aren't interested in any
- events anymore. */
- td_event_emptyset (&events);
- - td_ta_set_event_p (thread_agent, &events);
- + current_pointers->td_ta_set_event_p (thread_agent, &events);
-
- /* Delete thread event breakpoints, if any. */
- remove_thread_event_breakpoints ();
- @@ -635,7 +666,6 @@ check_thread_signals (void)
- static void
- check_for_thread_db (void)
- {
- - td_err_e err;
- static int already_loaded;
-
- /* First time through, report that libthread_db was successfuly
- @@ -644,19 +674,8 @@ check_for_thread_db (void)
-
- if (!already_loaded)
- {
- - Dl_info info;
- - const char *library = NULL;
- - if (dladdr ((*td_ta_new_p), &info) != 0)
- - library = info.dli_fname;
- -
- - /* Try dlinfo? */
- -
- - if (library == NULL)
- - /* Paranoid - don't let a NULL path slip through. */
- - library = LIBTHREAD_DB_SO;
- -
- printf_unfiltered ("Using host libthread_db library \"%s\".\n",
- - library);
- + all_pointers->filename);
- already_loaded = 1;
- }
-
- @@ -674,28 +693,34 @@ check_for_thread_db (void)
- proc_handle.pid = GET_PID (inferior_ptid);
-
- /* Now attempt to open a connection to the thread library. */
- - err = td_ta_new_p (&proc_handle, &thread_agent);
- - switch (err)
- + for (current_pointers = all_pointers;
- + current_pointers != NULL;
- + current_pointers = current_pointers->next)
- {
- - case TD_NOLIBTHREAD:
- - /* No thread library was detected. */
- - break;
- -
- - case TD_OK:
- - printf_unfiltered ("[Thread debugging using libthread_db enabled]\n");
- + td_err_e err;
- + err = current_pointers->td_ta_new_p (&proc_handle, &thread_agent);
- + switch (err)
- + {
- + case TD_NOLIBTHREAD:
- + /* No thread library was detected. */
- + break;
-
- - /* The thread library was detected. Activate the thread_db target. */
- - push_target (&thread_db_ops);
- - using_thread_db = 1;
- + case TD_OK:
- + printf_unfiltered ("[Thread debugging using libthread_db enabled]\n");
-
- - enable_thread_event_reporting ();
- - thread_db_find_new_threads ();
- - break;
- + /* The thread library was detected. Activate the thread_db target. */
- + push_target (&thread_db_ops);
- + using_thread_db = 1;
- +
- + enable_thread_event_reporting ();
- + thread_db_find_new_threads ();
- + return;
-
- - default:
- - warning ("Cannot initialize thread debugging library: %s",
- - thread_db_err_str (err));
- - break;
- + default:
- + warning ("Cannot initialize thread debugging library: %s",
- + thread_db_err_str (err));
- + break;
- + }
- }
- }
-
- @@ -766,7 +791,7 @@ attach_thread (ptid_t ptid, const td_thr
- #endif
-
- /* Enable thread event reporting for this thread. */
- - err = td_thr_event_enable_p (th_p, 1);
- + err = current_pointers->td_thr_event_enable_p (th_p, 1);
- if (err != TD_OK)
- error ("Cannot enable thread event reporting for %s: %s",
- target_pid_to_str (ptid), thread_db_err_str (err));
- @@ -892,7 +917,7 @@ check_event (ptid_t ptid)
-
- do
- {
- - err = td_ta_event_getmsg_p (thread_agent, &msg);
- + err = current_pointers->td_ta_event_getmsg_p (thread_agent, &msg);
- if (err != TD_OK)
- {
- if (err == TD_NOMSG)
- @@ -902,7 +927,7 @@ check_event (ptid_t ptid)
- thread_db_err_str (err));
- }
-
- - err = td_thr_get_info_p (msg.th_p, &ti);
- + err = current_pointers->td_thr_get_info_p (msg.th_p, &ti);
- if (err != TD_OK)
- error ("Cannot get thread info: %s", thread_db_err_str (err));
-
- @@ -1015,12 +1040,14 @@ thread_db_fetch_registers (int regno)
- thread_info = find_thread_pid (inferior_ptid);
- thread_db_map_id2thr (thread_info, 1);
-
- - err = td_thr_getgregs_p (&thread_info->private->th, gregset);
- + err = current_pointers->td_thr_getgregs_p (&thread_info->private->th,
- + gregset);
- if (err != TD_OK)
- error ("Cannot fetch general-purpose registers for thread %ld: %s",
- (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
-
- - err = td_thr_getfpregs_p (&thread_info->private->th, &fpregset);
- + err = current_pointers->td_thr_getfpregs_p (&thread_info->private->th,
- + &fpregset);
- if (err != TD_OK)
- error ("Cannot get floating-point registers for thread %ld: %s",
- (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
- @@ -1062,11 +1089,13 @@ thread_db_store_registers (int regno)
- fill_gregset ((gdb_gregset_t *) gregset, -1);
- fill_fpregset (&fpregset, -1);
-
- - err = td_thr_setgregs_p (&thread_info->private->th, gregset);
- + err = current_pointers->td_thr_setgregs_p (&thread_info->private->th,
- + gregset);
- if (err != TD_OK)
- error ("Cannot store general-purpose registers for thread %ld: %s",
- (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
- - err = td_thr_setfpregs_p (&thread_info->private->th, &fpregset);
- + err = current_pointers->td_thr_setfpregs_p (&thread_info->private->th,
- + &fpregset);
- if (err != TD_OK)
- error ("Cannot store floating-point registers for thread %ld: %s",
- (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
- @@ -1136,15 +1165,14 @@ thread_db_thread_alive (ptid_t ptid)
- if (!thread_info->private->th_valid)
- return 0;
-
- - err = td_thr_validate_p (&thread_info->private->th);
- + err = current_pointers->td_thr_validate_p (&thread_info->private->th);
- if (err != TD_OK)
- return 0;
-
- if (!thread_info->private->ti_valid)
- {
- - err =
- - td_thr_get_info_p (&thread_info->private->th,
- - &thread_info->private->ti);
- + err = current_pointers->td_thr_get_info_p
- + (&thread_info->private->th, &thread_info->private->ti);
- if (err != TD_OK)
- return 0;
- thread_info->private->ti_valid = 1;
- @@ -1170,7 +1198,7 @@ find_new_threads_callback (const td_thrh
- td_err_e err;
- ptid_t ptid;
-
- - err = td_thr_get_info_p (th_p, &ti);
- + err = current_pointers->td_thr_get_info_p (th_p, &ti);
- if (err != TD_OK)
- error ("find_new_threads_callback: cannot get thread info: %s",
- thread_db_err_str (err));
- @@ -1192,9 +1220,10 @@ thread_db_find_new_threads (void)
- td_err_e err;
-
- /* Iterate over all user-space threads to discover new threads. */
- - err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
- - TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
- - TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
- + err = current_pointers->td_ta_thr_iter_p
- + (thread_agent, find_new_threads_callback, NULL,
- + TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
- + TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
- if (err != TD_OK)
- error ("Cannot find new threads: %s", thread_db_err_str (err));
- }
- @@ -1257,7 +1286,7 @@ thread_db_get_thread_local_address (ptid
- struct thread_info *thread_info;
-
- /* glibc doesn't provide the needed interface. */
- - if (!td_thr_tls_get_addr_p)
- + if (!current_pointers->td_thr_tls_get_addr_p)
- error ("Cannot find thread-local variables in this thread library.");
-
- /* Get the address of the link map for this objfile. */
- @@ -1279,8 +1308,8 @@ thread_db_get_thread_local_address (ptid
- thread_db_map_id2thr (thread_info, 1);
-
- /* Finally, get the address of the variable. */
- - err = td_thr_tls_get_addr_p (&thread_info->private->th, (void *) lm,
- - offset, &address);
- + err = current_pointers->td_thr_tls_get_addr_p
- + (&thread_info->private->th, (void *) lm, offset, &address);
-
- #ifdef THREAD_DB_HAS_TD_NOTALLOC
- /* The memory hasn't been allocated, yet. */
- @@ -1360,17 +1389,49 @@ init_thread_db_ops (void)
- void
- _initialize_thread_db (void)
- {
- + struct thread_db_pointers *ptrs;
- + const char *p;
- +
- /* Only initialize the module if we can load libthread_db. */
- - if (thread_db_load ())
- - {
- - init_thread_db_ops ();
- - add_target (&thread_db_ops);
- + ptrs = thread_db_load (LIBTHREAD_DB_SO);
- + if (ptrs == NULL)
- + return;
- +
- + all_pointers = ptrs;
-
- - /* Add ourselves to objfile event chain. */
- - target_new_objfile_chain = deprecated_target_new_objfile_hook;
- - deprecated_target_new_objfile_hook = thread_db_new_objfile;
- + /* Some GNU/Linux systems have more than one binary-compatible copy
- + of libthread_db. If we can find a second one, load that too.
- + The inferior may force the use of a different threading package
- + than we expect. Our guess for the location is somewhat hokey:
- + strip out anything between /lib (or /lib64) and LIBTHREAD_DB_SO.
- + If we loaded the NPTL libthread_db by default, this may find us
- + the LinuxThreads copy. */
- + p = strrchr (ptrs->filename, '/');
- + while (p != NULL && p > ptrs->filename)
- + {
- + const char *component;
-
- - /* Register ourselves for the new inferior observer. */
- - observer_attach_inferior_created (check_for_thread_db_observer);
- + component = memrchr (ptrs->filename, '/', p - ptrs->filename);
- + if (component != NULL && strncmp (component, "/lib", 4) == 0)
- + {
- + char *new_name = xmalloc (p - ptrs->filename + 2
- + + strlen (LIBTHREAD_DB_SO));
- + memcpy (new_name, ptrs->filename, p - ptrs->filename + 1);
- + strcpy (new_name + (p - ptrs->filename) + 1, LIBTHREAD_DB_SO);
- + ptrs->next = thread_db_load (new_name);
- + xfree (new_name);
- + break;
- + }
- + p = component;
- }
- +
- + init_thread_db_ops ();
- + add_target (&thread_db_ops);
- +
- + /* Add ourselves to objfile event chain. */
- + target_new_objfile_chain = deprecated_target_new_objfile_hook;
- + deprecated_target_new_objfile_hook = thread_db_new_objfile;
- +
- + /* Register ourselves for the new inferior observer. */
- + observer_attach_inferior_created (check_for_thread_db_observer);
- }
|