710-debian_thread-db-multiple-libraries.patch 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. Support loading two libthread_db DSOs. In this case, the LinuxThreads
  2. and NPTL ones.
  3. Index: gdb-6.3/gdb/thread-db.c
  4. ===================================================================
  5. --- gdb-6.3.orig/gdb/thread-db.c 2004-11-10 10:46:24.000000000 -0500
  6. +++ gdb-6.3/gdb/thread-db.c 2004-11-10 11:22:34.858812426 -0500
  7. @@ -79,53 +79,63 @@ static td_thragent_t *thread_agent;
  8. /* Pointers to the libthread_db functions. */
  9. -static td_err_e (*td_init_p) (void);
  10. +struct thread_db_pointers
  11. +{
  12. + const char *filename;
  13. +
  14. + td_err_e (*td_init_p) (void);
  15. -static td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
  16. - td_thragent_t **ta);
  17. -static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
  18. - td_thrhandle_t *__th);
  19. -static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
  20. - lwpid_t lwpid, td_thrhandle_t *th);
  21. -static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
  22. - td_thr_iter_f *callback, void *cbdata_p,
  23. - td_thr_state_e state, int ti_pri,
  24. - sigset_t *ti_sigmask_p,
  25. - unsigned int ti_user_flags);
  26. -static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
  27. - td_event_e event, td_notify_t *ptr);
  28. -static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
  29. - td_thr_events_t *event);
  30. -static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
  31. - td_event_msg_t *msg);
  32. -
  33. -static td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
  34. -static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
  35. - td_thrinfo_t *infop);
  36. -static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
  37. - gdb_prfpregset_t *regset);
  38. -static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
  39. - prgregset_t gregs);
  40. -static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
  41. - const gdb_prfpregset_t *fpregs);
  42. -static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
  43. - prgregset_t gregs);
  44. -static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
  45. - int event);
  46. -
  47. -static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
  48. - void *map_address,
  49. - size_t offset, void **address);
  50. + td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
  51. + td_thragent_t **ta);
  52. + td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
  53. + td_thrhandle_t *__th);
  54. + td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
  55. + lwpid_t lwpid, td_thrhandle_t *th);
  56. +
  57. + td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
  58. + td_thr_iter_f *callback, void *cbdata_p,
  59. + td_thr_state_e state, int ti_pri,
  60. + sigset_t *ti_sigmask_p,
  61. + unsigned int ti_user_flags);
  62. + td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
  63. + td_event_e event, td_notify_t *ptr);
  64. + td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
  65. + td_thr_events_t *event);
  66. + td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
  67. + td_event_msg_t *msg);
  68. +
  69. + td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
  70. + td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
  71. + td_thrinfo_t *infop);
  72. + td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
  73. + gdb_prfpregset_t *regset);
  74. + td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
  75. + prgregset_t gregs);
  76. + td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
  77. + const gdb_prfpregset_t *fpregs);
  78. + td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
  79. + prgregset_t gregs);
  80. + td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
  81. + int event);
  82. +
  83. + td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
  84. + void *map_address,
  85. + size_t offset, void **address);
  86. +
  87. + struct thread_db_pointers *next;
  88. +};
  89. /* Location of the thread creation event breakpoint. The code at this
  90. location in the child process will be called by the pthread library
  91. whenever a new thread is created. By setting a special breakpoint
  92. at this location, GDB can detect when a new thread is created. We
  93. obtain this location via the td_ta_event_addr call. */
  94. -static CORE_ADDR td_create_bp_addr;
  95. +CORE_ADDR td_create_bp_addr;
  96. /* Location of the thread death event breakpoint. */
  97. -static CORE_ADDR td_death_bp_addr;
  98. +CORE_ADDR td_death_bp_addr;
  99. +
  100. +static struct thread_db_pointers *current_pointers, *all_pointers;
  101. /* Prototypes for local functions. */
  102. static void thread_db_find_new_threads (void);
  103. @@ -262,7 +272,7 @@ thread_get_info_callback (const td_thrha
  104. struct thread_info *thread_info;
  105. ptid_t thread_ptid;
  106. - err = td_thr_get_info_p (thp, &ti);
  107. + err = current_pointers->td_thr_get_info_p (thp, &ti);
  108. if (err != TD_OK)
  109. error ("thread_get_info_callback: cannot get thread info: %s",
  110. thread_db_err_str (err));
  111. @@ -316,8 +326,9 @@ thread_db_map_id2thr (struct thread_info
  112. if (thread_info->private->th_valid)
  113. return;
  114. - err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (thread_info->ptid),
  115. - &thread_info->private->th);
  116. + err = current_pointers->td_ta_map_id2thr_p (thread_agent,
  117. + GET_THREAD (thread_info->ptid),
  118. + &thread_info->private->th);
  119. if (err != TD_OK)
  120. {
  121. if (fatal)
  122. @@ -340,8 +351,8 @@ thread_db_get_info (struct thread_info *
  123. if (!thread_info->private->th_valid)
  124. thread_db_map_id2thr (thread_info, 1);
  125. - err =
  126. - td_thr_get_info_p (&thread_info->private->th, &thread_info->private->ti);
  127. + err = current_pointers->td_thr_get_info_p (&thread_info->private->th,
  128. + &thread_info->private->ti);
  129. if (err != TD_OK)
  130. error ("thread_db_get_info: cannot get thread info: %s",
  131. thread_db_err_str (err));
  132. @@ -365,7 +376,8 @@ thread_from_lwp (ptid_t ptid)
  133. gdb_assert (is_lwp (ptid));
  134. - err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
  135. + err = current_pointers->td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid),
  136. + &th);
  137. if (err != TD_OK)
  138. error ("Cannot find user-level thread for LWP %ld: %s",
  139. GET_LWP (ptid), thread_db_err_str (err));
  140. @@ -420,85 +432,102 @@ verbose_dlsym (void *handle, const char
  141. return sym;
  142. }
  143. -static int
  144. -thread_db_load (void)
  145. +static struct thread_db_pointers *
  146. +thread_db_load (const char *name)
  147. {
  148. + struct thread_db_pointers *ptrs;
  149. + Dl_info info;
  150. void *handle;
  151. td_err_e err;
  152. - handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
  153. + ptrs = xcalloc (1, sizeof (struct thread_db_pointers));
  154. +
  155. + handle = dlopen (name, RTLD_NOW);
  156. if (handle == NULL)
  157. {
  158. - fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
  159. - LIBTHREAD_DB_SO, dlerror ());
  160. - fprintf_filtered (gdb_stderr,
  161. - "GDB will not be able to debug pthreads.\n\n");
  162. + if (all_pointers == NULL)
  163. + {
  164. + fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
  165. + name, dlerror ());
  166. + fprintf_filtered (gdb_stderr,
  167. + "GDB will not be able to debug pthreads.\n\n");
  168. + }
  169. return 0;
  170. }
  171. /* Initialize pointers to the dynamic library functions we will use.
  172. Essential functions first. */
  173. - td_init_p = verbose_dlsym (handle, "td_init");
  174. - if (td_init_p == NULL)
  175. + ptrs->td_init_p = verbose_dlsym (handle, "td_init");
  176. + if (ptrs->td_init_p == NULL)
  177. return 0;
  178. - td_ta_new_p = verbose_dlsym (handle, "td_ta_new");
  179. - if (td_ta_new_p == NULL)
  180. + ptrs->td_ta_new_p = verbose_dlsym (handle, "td_ta_new");
  181. + if (ptrs->td_ta_new_p == NULL)
  182. return 0;
  183. - td_ta_map_id2thr_p = verbose_dlsym (handle, "td_ta_map_id2thr");
  184. - if (td_ta_map_id2thr_p == NULL)
  185. + ptrs->td_ta_map_id2thr_p = verbose_dlsym (handle, "td_ta_map_id2thr");
  186. + if (ptrs->td_ta_map_id2thr_p == NULL)
  187. return 0;
  188. - td_ta_map_lwp2thr_p = verbose_dlsym (handle, "td_ta_map_lwp2thr");
  189. - if (td_ta_map_lwp2thr_p == NULL)
  190. + ptrs->td_ta_map_lwp2thr_p = verbose_dlsym (handle, "td_ta_map_lwp2thr");
  191. + if (ptrs->td_ta_map_lwp2thr_p == NULL)
  192. return 0;
  193. - td_ta_thr_iter_p = verbose_dlsym (handle, "td_ta_thr_iter");
  194. - if (td_ta_thr_iter_p == NULL)
  195. + ptrs->td_ta_thr_iter_p = verbose_dlsym (handle, "td_ta_thr_iter");
  196. + if (ptrs->td_ta_thr_iter_p == NULL)
  197. return 0;
  198. - td_thr_validate_p = verbose_dlsym (handle, "td_thr_validate");
  199. - if (td_thr_validate_p == NULL)
  200. + ptrs->td_thr_validate_p = verbose_dlsym (handle, "td_thr_validate");
  201. + if (ptrs->td_thr_validate_p == NULL)
  202. return 0;
  203. - td_thr_get_info_p = verbose_dlsym (handle, "td_thr_get_info");
  204. - if (td_thr_get_info_p == NULL)
  205. + ptrs->td_thr_get_info_p = verbose_dlsym (handle, "td_thr_get_info");
  206. + if (ptrs->td_thr_get_info_p == NULL)
  207. return 0;
  208. - td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs");
  209. - if (td_thr_getfpregs_p == NULL)
  210. + ptrs->td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs");
  211. + if (ptrs->td_thr_getfpregs_p == NULL)
  212. return 0;
  213. - td_thr_getgregs_p = verbose_dlsym (handle, "td_thr_getgregs");
  214. - if (td_thr_getgregs_p == NULL)
  215. + ptrs->td_thr_getgregs_p = verbose_dlsym (handle, "td_thr_getgregs");
  216. + if (ptrs->td_thr_getgregs_p == NULL)
  217. return 0;
  218. - td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs");
  219. - if (td_thr_setfpregs_p == NULL)
  220. + ptrs->td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs");
  221. + if (ptrs->td_thr_setfpregs_p == NULL)
  222. return 0;
  223. - td_thr_setgregs_p = verbose_dlsym (handle, "td_thr_setgregs");
  224. - if (td_thr_setgregs_p == NULL)
  225. + ptrs->td_thr_setgregs_p = verbose_dlsym (handle, "td_thr_setgregs");
  226. + if (ptrs->td_thr_setgregs_p == NULL)
  227. return 0;
  228. /* Initialize the library. */
  229. - err = td_init_p ();
  230. + err = ptrs->td_init_p ();
  231. if (err != TD_OK)
  232. {
  233. warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
  234. + xfree (ptrs);
  235. return 0;
  236. }
  237. /* These are not essential. */
  238. - td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
  239. - td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
  240. - td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
  241. - td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
  242. - td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
  243. + ptrs->td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
  244. + ptrs->td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
  245. + ptrs->td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
  246. + ptrs->td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
  247. + ptrs->td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
  248. +
  249. + if (dladdr (ptrs->td_ta_new_p, &info) != 0)
  250. + ptrs->filename = info.dli_fname;
  251. +
  252. + /* Try dlinfo? */
  253. +
  254. + if (ptrs->filename == NULL)
  255. + /* Paranoid - don't let a NULL path slip through. */
  256. + ptrs->filename = name;
  257. - return 1;
  258. + return ptrs;
  259. }
  260. static td_err_e
  261. @@ -508,7 +537,7 @@ enable_thread_event (td_thragent_t *thre
  262. td_err_e err;
  263. /* Get the breakpoint address for thread EVENT. */
  264. - err = td_ta_event_addr_p (thread_agent, event, &notify);
  265. + err = current_pointers->td_ta_event_addr_p (thread_agent, event, &notify);
  266. if (err != TD_OK)
  267. return err;
  268. @@ -534,8 +563,10 @@ enable_thread_event_reporting (void)
  269. /* We cannot use the thread event reporting facility if these
  270. functions aren't available. */
  271. - if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
  272. - || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
  273. + if (current_pointers->td_ta_event_addr_p == NULL
  274. + || current_pointers->td_ta_set_event_p == NULL
  275. + || current_pointers->td_ta_event_getmsg_p == NULL
  276. + || current_pointers->td_thr_event_enable_p == NULL)
  277. return;
  278. /* Set the process wide mask saying which events we're interested in. */
  279. @@ -552,7 +583,7 @@ enable_thread_event_reporting (void)
  280. #endif
  281. td_event_addset (&events, TD_DEATH);
  282. - err = td_ta_set_event_p (thread_agent, &events);
  283. + err = current_pointers->td_ta_set_event_p (thread_agent, &events);
  284. if (err != TD_OK)
  285. {
  286. warning ("Unable to set global thread event mask: %s",
  287. @@ -592,7 +623,7 @@ disable_thread_event_reporting (void)
  288. /* Set the process wide mask saying we aren't interested in any
  289. events anymore. */
  290. td_event_emptyset (&events);
  291. - td_ta_set_event_p (thread_agent, &events);
  292. + current_pointers->td_ta_set_event_p (thread_agent, &events);
  293. /* Delete thread event breakpoints, if any. */
  294. remove_thread_event_breakpoints ();
  295. @@ -635,7 +666,6 @@ check_thread_signals (void)
  296. static void
  297. check_for_thread_db (void)
  298. {
  299. - td_err_e err;
  300. static int already_loaded;
  301. /* First time through, report that libthread_db was successfuly
  302. @@ -644,19 +674,8 @@ check_for_thread_db (void)
  303. if (!already_loaded)
  304. {
  305. - Dl_info info;
  306. - const char *library = NULL;
  307. - if (dladdr ((*td_ta_new_p), &info) != 0)
  308. - library = info.dli_fname;
  309. -
  310. - /* Try dlinfo? */
  311. -
  312. - if (library == NULL)
  313. - /* Paranoid - don't let a NULL path slip through. */
  314. - library = LIBTHREAD_DB_SO;
  315. -
  316. printf_unfiltered ("Using host libthread_db library \"%s\".\n",
  317. - library);
  318. + all_pointers->filename);
  319. already_loaded = 1;
  320. }
  321. @@ -674,28 +693,34 @@ check_for_thread_db (void)
  322. proc_handle.pid = GET_PID (inferior_ptid);
  323. /* Now attempt to open a connection to the thread library. */
  324. - err = td_ta_new_p (&proc_handle, &thread_agent);
  325. - switch (err)
  326. + for (current_pointers = all_pointers;
  327. + current_pointers != NULL;
  328. + current_pointers = current_pointers->next)
  329. {
  330. - case TD_NOLIBTHREAD:
  331. - /* No thread library was detected. */
  332. - break;
  333. -
  334. - case TD_OK:
  335. - printf_unfiltered ("[Thread debugging using libthread_db enabled]\n");
  336. + td_err_e err;
  337. + err = current_pointers->td_ta_new_p (&proc_handle, &thread_agent);
  338. + switch (err)
  339. + {
  340. + case TD_NOLIBTHREAD:
  341. + /* No thread library was detected. */
  342. + break;
  343. - /* The thread library was detected. Activate the thread_db target. */
  344. - push_target (&thread_db_ops);
  345. - using_thread_db = 1;
  346. + case TD_OK:
  347. + printf_unfiltered ("[Thread debugging using libthread_db enabled]\n");
  348. - enable_thread_event_reporting ();
  349. - thread_db_find_new_threads ();
  350. - break;
  351. + /* The thread library was detected. Activate the thread_db target. */
  352. + push_target (&thread_db_ops);
  353. + using_thread_db = 1;
  354. +
  355. + enable_thread_event_reporting ();
  356. + thread_db_find_new_threads ();
  357. + return;
  358. - default:
  359. - warning ("Cannot initialize thread debugging library: %s",
  360. - thread_db_err_str (err));
  361. - break;
  362. + default:
  363. + warning ("Cannot initialize thread debugging library: %s",
  364. + thread_db_err_str (err));
  365. + break;
  366. + }
  367. }
  368. }
  369. @@ -766,7 +791,7 @@ attach_thread (ptid_t ptid, const td_thr
  370. #endif
  371. /* Enable thread event reporting for this thread. */
  372. - err = td_thr_event_enable_p (th_p, 1);
  373. + err = current_pointers->td_thr_event_enable_p (th_p, 1);
  374. if (err != TD_OK)
  375. error ("Cannot enable thread event reporting for %s: %s",
  376. target_pid_to_str (ptid), thread_db_err_str (err));
  377. @@ -892,7 +917,7 @@ check_event (ptid_t ptid)
  378. do
  379. {
  380. - err = td_ta_event_getmsg_p (thread_agent, &msg);
  381. + err = current_pointers->td_ta_event_getmsg_p (thread_agent, &msg);
  382. if (err != TD_OK)
  383. {
  384. if (err == TD_NOMSG)
  385. @@ -902,7 +927,7 @@ check_event (ptid_t ptid)
  386. thread_db_err_str (err));
  387. }
  388. - err = td_thr_get_info_p (msg.th_p, &ti);
  389. + err = current_pointers->td_thr_get_info_p (msg.th_p, &ti);
  390. if (err != TD_OK)
  391. error ("Cannot get thread info: %s", thread_db_err_str (err));
  392. @@ -1015,12 +1040,14 @@ thread_db_fetch_registers (int regno)
  393. thread_info = find_thread_pid (inferior_ptid);
  394. thread_db_map_id2thr (thread_info, 1);
  395. - err = td_thr_getgregs_p (&thread_info->private->th, gregset);
  396. + err = current_pointers->td_thr_getgregs_p (&thread_info->private->th,
  397. + gregset);
  398. if (err != TD_OK)
  399. error ("Cannot fetch general-purpose registers for thread %ld: %s",
  400. (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
  401. - err = td_thr_getfpregs_p (&thread_info->private->th, &fpregset);
  402. + err = current_pointers->td_thr_getfpregs_p (&thread_info->private->th,
  403. + &fpregset);
  404. if (err != TD_OK)
  405. error ("Cannot get floating-point registers for thread %ld: %s",
  406. (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
  407. @@ -1062,11 +1089,13 @@ thread_db_store_registers (int regno)
  408. fill_gregset ((gdb_gregset_t *) gregset, -1);
  409. fill_fpregset (&fpregset, -1);
  410. - err = td_thr_setgregs_p (&thread_info->private->th, gregset);
  411. + err = current_pointers->td_thr_setgregs_p (&thread_info->private->th,
  412. + gregset);
  413. if (err != TD_OK)
  414. error ("Cannot store general-purpose registers for thread %ld: %s",
  415. (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
  416. - err = td_thr_setfpregs_p (&thread_info->private->th, &fpregset);
  417. + err = current_pointers->td_thr_setfpregs_p (&thread_info->private->th,
  418. + &fpregset);
  419. if (err != TD_OK)
  420. error ("Cannot store floating-point registers for thread %ld: %s",
  421. (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
  422. @@ -1136,15 +1165,14 @@ thread_db_thread_alive (ptid_t ptid)
  423. if (!thread_info->private->th_valid)
  424. return 0;
  425. - err = td_thr_validate_p (&thread_info->private->th);
  426. + err = current_pointers->td_thr_validate_p (&thread_info->private->th);
  427. if (err != TD_OK)
  428. return 0;
  429. if (!thread_info->private->ti_valid)
  430. {
  431. - err =
  432. - td_thr_get_info_p (&thread_info->private->th,
  433. - &thread_info->private->ti);
  434. + err = current_pointers->td_thr_get_info_p
  435. + (&thread_info->private->th, &thread_info->private->ti);
  436. if (err != TD_OK)
  437. return 0;
  438. thread_info->private->ti_valid = 1;
  439. @@ -1170,7 +1198,7 @@ find_new_threads_callback (const td_thrh
  440. td_err_e err;
  441. ptid_t ptid;
  442. - err = td_thr_get_info_p (th_p, &ti);
  443. + err = current_pointers->td_thr_get_info_p (th_p, &ti);
  444. if (err != TD_OK)
  445. error ("find_new_threads_callback: cannot get thread info: %s",
  446. thread_db_err_str (err));
  447. @@ -1192,9 +1220,10 @@ thread_db_find_new_threads (void)
  448. td_err_e err;
  449. /* Iterate over all user-space threads to discover new threads. */
  450. - err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
  451. - TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
  452. - TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
  453. + err = current_pointers->td_ta_thr_iter_p
  454. + (thread_agent, find_new_threads_callback, NULL,
  455. + TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
  456. + TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
  457. if (err != TD_OK)
  458. error ("Cannot find new threads: %s", thread_db_err_str (err));
  459. }
  460. @@ -1257,7 +1286,7 @@ thread_db_get_thread_local_address (ptid
  461. struct thread_info *thread_info;
  462. /* glibc doesn't provide the needed interface. */
  463. - if (!td_thr_tls_get_addr_p)
  464. + if (!current_pointers->td_thr_tls_get_addr_p)
  465. error ("Cannot find thread-local variables in this thread library.");
  466. /* Get the address of the link map for this objfile. */
  467. @@ -1279,8 +1308,8 @@ thread_db_get_thread_local_address (ptid
  468. thread_db_map_id2thr (thread_info, 1);
  469. /* Finally, get the address of the variable. */
  470. - err = td_thr_tls_get_addr_p (&thread_info->private->th, (void *) lm,
  471. - offset, &address);
  472. + err = current_pointers->td_thr_tls_get_addr_p
  473. + (&thread_info->private->th, (void *) lm, offset, &address);
  474. #ifdef THREAD_DB_HAS_TD_NOTALLOC
  475. /* The memory hasn't been allocated, yet. */
  476. @@ -1360,17 +1389,49 @@ init_thread_db_ops (void)
  477. void
  478. _initialize_thread_db (void)
  479. {
  480. + struct thread_db_pointers *ptrs;
  481. + const char *p;
  482. +
  483. /* Only initialize the module if we can load libthread_db. */
  484. - if (thread_db_load ())
  485. - {
  486. - init_thread_db_ops ();
  487. - add_target (&thread_db_ops);
  488. + ptrs = thread_db_load (LIBTHREAD_DB_SO);
  489. + if (ptrs == NULL)
  490. + return;
  491. +
  492. + all_pointers = ptrs;
  493. - /* Add ourselves to objfile event chain. */
  494. - target_new_objfile_chain = deprecated_target_new_objfile_hook;
  495. - deprecated_target_new_objfile_hook = thread_db_new_objfile;
  496. + /* Some GNU/Linux systems have more than one binary-compatible copy
  497. + of libthread_db. If we can find a second one, load that too.
  498. + The inferior may force the use of a different threading package
  499. + than we expect. Our guess for the location is somewhat hokey:
  500. + strip out anything between /lib (or /lib64) and LIBTHREAD_DB_SO.
  501. + If we loaded the NPTL libthread_db by default, this may find us
  502. + the LinuxThreads copy. */
  503. + p = strrchr (ptrs->filename, '/');
  504. + while (p != NULL && p > ptrs->filename)
  505. + {
  506. + const char *component;
  507. - /* Register ourselves for the new inferior observer. */
  508. - observer_attach_inferior_created (check_for_thread_db_observer);
  509. + component = memrchr (ptrs->filename, '/', p - ptrs->filename);
  510. + if (component != NULL && strncmp (component, "/lib", 4) == 0)
  511. + {
  512. + char *new_name = xmalloc (p - ptrs->filename + 2
  513. + + strlen (LIBTHREAD_DB_SO));
  514. + memcpy (new_name, ptrs->filename, p - ptrs->filename + 1);
  515. + strcpy (new_name + (p - ptrs->filename) + 1, LIBTHREAD_DB_SO);
  516. + ptrs->next = thread_db_load (new_name);
  517. + xfree (new_name);
  518. + break;
  519. + }
  520. + p = component;
  521. }
  522. +
  523. + init_thread_db_ops ();
  524. + add_target (&thread_db_ops);
  525. +
  526. + /* Add ourselves to objfile event chain. */
  527. + target_new_objfile_chain = deprecated_target_new_objfile_hook;
  528. + deprecated_target_new_objfile_hook = thread_db_new_objfile;
  529. +
  530. + /* Register ourselves for the new inferior observer. */
  531. + observer_attach_inferior_created (check_for_thread_db_observer);
  532. }