* emulparams/vxworks.sh (OTHER_READONLY_SECTIONS): Move into ...
[deliverable/binutils-gdb.git] / gdb / gdbserver / thread-db.c
CommitLineData
0d62e5e8 1/* Thread management interface, for the remote server for GDB.
0fb0cc75 2 Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009
9b254dd1 3 Free Software Foundation, Inc.
0d62e5e8
DJ
4
5 Contributed by MontaVista Software.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
0d62e5e8
DJ
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0d62e5e8
DJ
21
22#include "server.h"
23
24#include "linux-low.h"
25
26extern int debug_threads;
27
24a09b5f
DJ
28static int thread_db_use_events;
29
0050a760 30#include "gdb_proc_service.h"
cdbfd419 31#include "../gdb_thread_db.h"
0d62e5e8 32
cdbfd419 33#include <dlfcn.h>
186947f7 34#include <stdint.h>
cdbfd419
PP
35#include <limits.h>
36#include <ctype.h>
37
38struct thread_db
39{
40 /* Structure that identifies the child process for the
41 <proc_service.h> interface. */
42 struct ps_prochandle proc_handle;
43
44 /* Connection to the libthread_db library. */
45 td_thragent_t *thread_agent;
46
47 /* Handle of the libthread_db from dlopen. */
48 void *handle;
49
50 /* Addresses of libthread_db functions. */
51 td_err_e (*td_ta_new_p) (struct ps_prochandle * ps, td_thragent_t **ta);
52 td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
53 td_event_msg_t *msg);
54 td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
55 td_thr_events_t *event);
56 td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
57 td_event_e event, td_notify_t *ptr);
58 td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta, lwpid_t lwpid,
59 td_thrhandle_t *th);
60 td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
61 td_thrinfo_t *infop);
62 td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event);
63 td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
64 td_thr_iter_f *callback, void *cbdata_p,
65 td_thr_state_e state, int ti_pri,
66 sigset_t *ti_sigmask_p,
67 unsigned int ti_user_flags);
68 td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
69 void *map_address,
70 size_t offset, void **address);
71 const char ** (*td_symbol_list_p) (void);
72};
73
74static char *libthread_db_search_path;
186947f7 75
95954743 76static int find_one_thread (ptid_t);
0d62e5e8
DJ
77static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data);
78
54363045 79static const char *
0d62e5e8
DJ
80thread_db_err_str (td_err_e err)
81{
82 static char buf[64];
83
84 switch (err)
85 {
86 case TD_OK:
87 return "generic 'call succeeded'";
88 case TD_ERR:
89 return "generic error";
90 case TD_NOTHR:
91 return "no thread to satisfy query";
92 case TD_NOSV:
93 return "no sync handle to satisfy query";
94 case TD_NOLWP:
95 return "no LWP to satisfy query";
96 case TD_BADPH:
97 return "invalid process handle";
98 case TD_BADTH:
99 return "invalid thread handle";
100 case TD_BADSH:
101 return "invalid synchronization handle";
102 case TD_BADTA:
103 return "invalid thread agent";
104 case TD_BADKEY:
105 return "invalid key";
106 case TD_NOMSG:
107 return "no event message for getmsg";
108 case TD_NOFPREGS:
109 return "FPU register set not available";
110 case TD_NOLIBTHREAD:
111 return "application not linked with libthread";
112 case TD_NOEVENT:
113 return "requested event is not supported";
114 case TD_NOCAPAB:
115 return "capability not available";
116 case TD_DBERR:
117 return "debugger service failed";
118 case TD_NOAPLIC:
119 return "operation not applicable to";
120 case TD_NOTSD:
121 return "no thread-specific data for this thread";
122 case TD_MALLOC:
123 return "malloc failed";
124 case TD_PARTIALREG:
125 return "only part of register set was written/read";
126 case TD_NOXREGS:
127 return "X register set not available for this thread";
3db0444b
DJ
128#ifdef HAVE_TD_VERSION
129 case TD_VERSION:
130 return "version mismatch between libthread_db and libpthread";
131#endif
0d62e5e8
DJ
132 default:
133 snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
134 return buf;
135 }
136}
137
138#if 0
139static char *
140thread_db_state_str (td_thr_state_e state)
141{
142 static char buf[64];
143
144 switch (state)
145 {
146 case TD_THR_STOPPED:
147 return "stopped by debugger";
148 case TD_THR_RUN:
149 return "runnable";
150 case TD_THR_ACTIVE:
151 return "active";
152 case TD_THR_ZOMBIE:
153 return "zombie";
154 case TD_THR_SLEEP:
155 return "sleeping";
156 case TD_THR_STOPPED_ASLEEP:
157 return "stopped by debugger AND blocked";
158 default:
159 snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
160 return buf;
161 }
162}
163#endif
164
b65d95c5 165static int
0d62e5e8
DJ
166thread_db_create_event (CORE_ADDR where)
167{
168 td_event_msg_t msg;
169 td_err_e err;
54a0b537 170 struct lwp_info *lwp;
cdbfd419
PP
171 struct thread_db *thread_db = current_process ()->private->thread_db;
172
173 if (thread_db->td_ta_event_getmsg_p == NULL)
174 fatal ("unexpected thread_db->td_ta_event_getmsg_p == NULL");
0d62e5e8
DJ
175
176 if (debug_threads)
177 fprintf (stderr, "Thread creation event.\n");
178
0d62e5e8
DJ
179 /* FIXME: This assumes we don't get another event.
180 In the LinuxThreads implementation, this is safe,
181 because all events come from the manager thread
182 (except for its own creation, of course). */
cdbfd419 183 err = thread_db->td_ta_event_getmsg_p (thread_db->thread_agent, &msg);
0d62e5e8
DJ
184 if (err != TD_OK)
185 fprintf (stderr, "thread getmsg err: %s\n",
186 thread_db_err_str (err));
187
4105de34
DJ
188 /* If we do not know about the main thread yet, this would be a good time to
189 find it. We need to do this to pick up the main thread before any newly
190 created threads. */
54a0b537
PA
191 lwp = get_thread_lwp (current_inferior);
192 if (lwp->thread_known == 0)
95954743 193 find_one_thread (lwp->head.id);
4105de34 194
0d62e5e8
DJ
195 /* msg.event == TD_EVENT_CREATE */
196
197 find_new_threads_callback (msg.th_p, NULL);
b65d95c5
DJ
198
199 return 0;
0d62e5e8
DJ
200}
201
0d62e5e8
DJ
202static int
203thread_db_enable_reporting ()
204{
205 td_thr_events_t events;
206 td_notify_t notify;
207 td_err_e err;
cdbfd419
PP
208 struct thread_db *thread_db = current_process ()->private->thread_db;
209
210 if (thread_db->td_ta_set_event_p == NULL
211 || thread_db->td_ta_event_addr_p == NULL
212 || thread_db->td_ta_event_getmsg_p == NULL)
213 /* This libthread_db is missing required support. */
214 return 0;
0d62e5e8
DJ
215
216 /* Set the process wide mask saying which events we're interested in. */
217 td_event_emptyset (&events);
218 td_event_addset (&events, TD_CREATE);
219
cdbfd419 220 err = thread_db->td_ta_set_event_p (thread_db->thread_agent, &events);
0d62e5e8
DJ
221 if (err != TD_OK)
222 {
223 warning ("Unable to set global thread event mask: %s",
1b3f6016 224 thread_db_err_str (err));
0d62e5e8
DJ
225 return 0;
226 }
227
228 /* Get address for thread creation breakpoint. */
cdbfd419
PP
229 err = thread_db->td_ta_event_addr_p (thread_db->thread_agent, TD_CREATE,
230 &notify);
0d62e5e8
DJ
231 if (err != TD_OK)
232 {
233 warning ("Unable to get location for thread creation breakpoint: %s",
234 thread_db_err_str (err));
235 return 0;
236 }
237 set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr,
238 thread_db_create_event);
239
0d62e5e8
DJ
240 return 1;
241}
242
ae13219e 243static int
95954743 244find_one_thread (ptid_t ptid)
0d62e5e8 245{
ae13219e
DJ
246 td_thrhandle_t th;
247 td_thrinfo_t ti;
0d62e5e8
DJ
248 td_err_e err;
249 struct thread_info *inferior;
54a0b537 250 struct lwp_info *lwp;
cdbfd419 251 struct thread_db *thread_db = current_process ()->private->thread_db;
95954743 252 int lwpid = ptid_get_lwp (ptid);
0d62e5e8 253
95954743 254 inferior = (struct thread_info *) find_inferior_id (&all_threads, ptid);
54a0b537
PA
255 lwp = get_thread_lwp (inferior);
256 if (lwp->thread_known)
ae13219e
DJ
257 return 1;
258
24a09b5f 259 /* Get information about this thread. */
cdbfd419 260 err = thread_db->td_ta_map_lwp2thr_p (thread_db->thread_agent, lwpid, &th);
ae13219e 261 if (err != TD_OK)
24a09b5f
DJ
262 error ("Cannot get thread handle for LWP %d: %s",
263 lwpid, thread_db_err_str (err));
ae13219e 264
cdbfd419 265 err = thread_db->td_thr_get_info_p (&th, &ti);
ae13219e 266 if (err != TD_OK)
24a09b5f
DJ
267 error ("Cannot get thread info for LWP %d: %s",
268 lwpid, thread_db_err_str (err));
ae13219e
DJ
269
270 if (debug_threads)
24a09b5f 271 fprintf (stderr, "Found thread %ld (LWP %d)\n",
ae13219e
DJ
272 ti.ti_tid, ti.ti_lid);
273
95954743 274 if (lwpid != ti.ti_lid)
24a09b5f
DJ
275 {
276 warning ("PID mismatch! Expected %ld, got %ld",
95954743 277 (long) lwpid, (long) ti.ti_lid);
24a09b5f
DJ
278 return 0;
279 }
ae13219e 280
24a09b5f 281 if (thread_db_use_events)
0d62e5e8 282 {
cdbfd419 283 err = thread_db->td_thr_event_enable_p (&th, 1);
ae13219e
DJ
284 if (err != TD_OK)
285 error ("Cannot enable thread event reporting for %d: %s",
286 ti.ti_lid, thread_db_err_str (err));
0d62e5e8 287 }
ae13219e 288
24a09b5f
DJ
289 /* If the new thread ID is zero, a final thread ID will be available
290 later. Do not enable thread debugging yet. */
291 if (ti.ti_tid == 0)
292 return 0;
ae13219e 293
54a0b537
PA
294 lwp->thread_known = 1;
295 lwp->th = th;
ae13219e 296
ae13219e
DJ
297 return 1;
298}
299
5f7d1694
PP
300/* Attach a thread. Return true on success. */
301
302static int
303attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
ae13219e 304{
54a0b537 305 struct lwp_info *lwp;
ae13219e 306
0d62e5e8
DJ
307 if (debug_threads)
308 fprintf (stderr, "Attaching to thread %ld (LWP %d)\n",
309 ti_p->ti_tid, ti_p->ti_lid);
24a09b5f 310 linux_attach_lwp (ti_p->ti_lid);
95954743
PA
311 lwp = find_lwp_pid (pid_to_ptid (ti_p->ti_lid));
312 if (lwp == NULL)
0d62e5e8
DJ
313 {
314 warning ("Could not attach to thread %ld (LWP %d)\n",
315 ti_p->ti_tid, ti_p->ti_lid);
5f7d1694 316 return 0;
0d62e5e8
DJ
317 }
318
54a0b537
PA
319 lwp->thread_known = 1;
320 lwp->th = *th_p;
24a09b5f
DJ
321
322 if (thread_db_use_events)
323 {
5f7d1694 324 td_err_e err;
cdbfd419 325 struct thread_db *thread_db = current_process ()->private->thread_db;
5f7d1694 326
cdbfd419 327 err = thread_db->td_thr_event_enable_p (th_p, 1);
24a09b5f
DJ
328 if (err != TD_OK)
329 error ("Cannot enable thread event reporting for %d: %s",
330 ti_p->ti_lid, thread_db_err_str (err));
331 }
5f7d1694
PP
332
333 return 1;
334}
335
336/* Attach thread if we haven't seen it yet.
337 Increment *COUNTER if we have attached a new thread.
338 Return false on failure. */
339
340static int
341maybe_attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p,
342 int *counter)
343{
344 struct lwp_info *lwp;
345
346 lwp = find_lwp_pid (pid_to_ptid (ti_p->ti_lid));
347 if (lwp != NULL)
348 return 1;
349
350 if (!attach_thread (th_p, ti_p))
351 return 0;
352
353 if (counter != NULL)
354 *counter += 1;
355
356 return 1;
0d62e5e8
DJ
357}
358
359static int
360find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
361{
362 td_thrinfo_t ti;
363 td_err_e err;
cdbfd419 364 struct thread_db *thread_db = current_process ()->private->thread_db;
0d62e5e8 365
cdbfd419 366 err = thread_db->td_thr_get_info_p (th_p, &ti);
0d62e5e8
DJ
367 if (err != TD_OK)
368 error ("Cannot get thread info: %s", thread_db_err_str (err));
369
370 /* Check for zombies. */
371 if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
372 return 0;
373
5f7d1694
PP
374 if (!maybe_attach_thread (th_p, &ti, (int *) data))
375 {
376 /* Terminate iteration early: we might be looking at stale data in
377 the inferior. The thread_db_find_new_threads will retry. */
378 return 1;
379 }
0d62e5e8
DJ
380
381 return 0;
382}
383
384static void
385thread_db_find_new_threads (void)
386{
387 td_err_e err;
95954743 388 ptid_t ptid = ((struct inferior_list_entry *) current_inferior)->id;
cdbfd419 389 struct thread_db *thread_db = current_process ()->private->thread_db;
5f7d1694 390 int loop, iteration;
0d62e5e8 391
ae13219e
DJ
392 /* This function is only called when we first initialize thread_db.
393 First locate the initial thread. If it is not ready for
394 debugging yet, then stop. */
95954743 395 if (find_one_thread (ptid) == 0)
ae13219e
DJ
396 return;
397
5f7d1694
PP
398 /* Require 4 successive iterations which do not find any new threads.
399 The 4 is a heuristic: there is an inherent race here, and I have
400 seen that 2 iterations in a row are not always sufficient to
401 "capture" all threads. */
402 for (loop = 0, iteration = 0; loop < 4; ++loop, ++iteration)
403 {
404 int new_thread_count = 0;
405
406 /* Iterate over all user-space threads to discover new threads. */
407 err = thread_db->td_ta_thr_iter_p (thread_db->thread_agent,
408 find_new_threads_callback,
409 &new_thread_count,
410 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
411 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
412 if (debug_threads)
413 fprintf (stderr, "Found %d threads in iteration %d.\n",
414 new_thread_count, iteration);
415
416 if (new_thread_count != 0)
417 {
418 /* Found new threads. Restart iteration from beginning. */
419 loop = -1;
420 }
421 }
0d62e5e8
DJ
422 if (err != TD_OK)
423 error ("Cannot find new threads: %s", thread_db_err_str (err));
424}
425
fd500816
DJ
426/* Cache all future symbols that thread_db might request. We can not
427 request symbols at arbitrary states in the remote protocol, only
428 when the client tells us that new symbols are available. So when
429 we load the thread library, make sure to check the entire list. */
430
431static void
432thread_db_look_up_symbols (void)
433{
cdbfd419
PP
434 struct thread_db *thread_db = current_process ()->private->thread_db;
435 const char **sym_list;
fd500816
DJ
436 CORE_ADDR unused;
437
cdbfd419 438 for (sym_list = thread_db->td_symbol_list_p (); *sym_list; sym_list++)
fd500816
DJ
439 look_up_one_symbol (*sym_list, &unused);
440}
441
dae5f5cf
DJ
442int
443thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
444 CORE_ADDR load_module, CORE_ADDR *address)
445{
dae5f5cf
DJ
446 psaddr_t addr;
447 td_err_e err;
54a0b537 448 struct lwp_info *lwp;
95954743 449 struct thread_info *saved_inferior;
cdbfd419
PP
450 struct process_info *proc;
451 struct thread_db *thread_db;
452
453 proc = get_thread_process (thread);
454 thread_db = proc->private->thread_db;
dae5f5cf 455
7fe519cb 456 /* If the thread layer is not (yet) initialized, fail. */
cdbfd419 457 if (!proc->all_symbols_looked_up)
7fe519cb
UW
458 return TD_ERR;
459
cdbfd419
PP
460 if (thread_db->td_thr_tls_get_addr_p == NULL)
461 return -1;
462
54a0b537
PA
463 lwp = get_thread_lwp (thread);
464 if (!lwp->thread_known)
95954743 465 find_one_thread (lwp->head.id);
54a0b537 466 if (!lwp->thread_known)
dae5f5cf
DJ
467 return TD_NOTHR;
468
95954743
PA
469 saved_inferior = current_inferior;
470 current_inferior = thread;
186947f7
DJ
471 /* Note the cast through uintptr_t: this interface only works if
472 a target address fits in a psaddr_t, which is a host pointer.
473 So a 32-bit debugger can not access 64-bit TLS through this. */
cdbfd419
PP
474 err = thread_db->td_thr_tls_get_addr_p (&lwp->th,
475 (psaddr_t) (uintptr_t) load_module,
476 offset, &addr);
95954743 477 current_inferior = saved_inferior;
dae5f5cf
DJ
478 if (err == TD_OK)
479 {
186947f7 480 *address = (CORE_ADDR) (uintptr_t) addr;
dae5f5cf
DJ
481 return 0;
482 }
483 else
484 return err;
cdbfd419
PP
485}
486
487static int
488try_thread_db_load_1 (void *handle)
489{
490 td_err_e err;
491 struct thread_db tdb;
492 struct process_info *proc = current_process ();
493
494 if (proc->private->thread_db != NULL)
495 fatal ("unexpected: proc->private->thread_db != NULL");
496
497 tdb.handle = handle;
498
499 /* Initialize pointers to the dynamic library functions we will use.
500 Essential functions first. */
501
502#define CHK(required, a) \
503 do \
504 { \
505 if ((a) == NULL) \
506 { \
507 if (debug_threads) \
508 fprintf (stderr, "dlsym: %s\n", dlerror ()); \
509 if (required) \
510 return 0; \
511 } \
512 } \
513 while (0)
514
515 CHK (1, tdb.td_ta_new_p = dlsym (handle, "td_ta_new"));
516
517 /* Attempt to open a connection to the thread library. */
518 err = tdb.td_ta_new_p (&tdb.proc_handle, &tdb.thread_agent);
519 if (err != TD_OK)
520 {
521 if (debug_threads)
522 fprintf (stderr, "td_ta_new(): %s\n", thread_db_err_str (err));
523 return 0;
524 }
525
526 CHK (1, tdb.td_ta_map_lwp2thr_p = dlsym (handle, "td_ta_map_lwp2thr"));
527 CHK (1, tdb.td_thr_get_info_p = dlsym (handle, "td_thr_get_info"));
528 CHK (1, tdb.td_ta_thr_iter_p = dlsym (handle, "td_ta_thr_iter"));
529 CHK (1, tdb.td_symbol_list_p = dlsym (handle, "td_symbol_list"));
530
531 /* This is required only when thread_db_use_events is on. */
532 CHK (thread_db_use_events,
533 tdb.td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable"));
534
535 /* These are not essential. */
536 CHK (0, tdb.td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr"));
537 CHK (0, tdb.td_ta_set_event_p = dlsym (handle, "td_ta_set_event"));
538 CHK (0, tdb.td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg"));
539 CHK (0, tdb.td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr"));
540
541#undef CHK
542
543 proc->private->thread_db = xmalloc (sizeof (tdb));
544 memcpy (proc->private->thread_db, &tdb, sizeof (tdb));
545
546 return 1;
547}
548
549/* Lookup a library in which given symbol resides.
550 Note: this is looking in the GDBSERVER process, not in the inferior.
551 Returns library name, or NULL. */
552
553static const char *
554dladdr_to_soname (const void *addr)
555{
556 Dl_info info;
557
558 if (dladdr (addr, &info) != 0)
559 return info.dli_fname;
560 return NULL;
561}
562
563static int
564try_thread_db_load (const char *library)
565{
566 void *handle;
567
568 if (debug_threads)
569 fprintf (stderr, "Trying host libthread_db library: %s.\n",
570 library);
571 handle = dlopen (library, RTLD_NOW);
572 if (handle == NULL)
573 {
574 if (debug_threads)
575 fprintf (stderr, "dlopen failed: %s.\n", dlerror ());
576 return 0;
577 }
578
579 if (debug_threads && strchr (library, '/') == NULL)
580 {
581 void *td_init;
582
583 td_init = dlsym (handle, "td_init");
584 if (td_init != NULL)
585 {
586 const char *const libpath = dladdr_to_soname (td_init);
587
588 if (libpath != NULL)
589 fprintf (stderr, "Host %s resolved to: %s.\n",
590 library, libpath);
591 }
592 }
593
594 if (try_thread_db_load_1 (handle))
595 return 1;
596
597 /* This library "refused" to work on current inferior. */
598 dlclose (handle);
599 return 0;
600}
601
602static int
603thread_db_load_search (void)
604{
605 char path[PATH_MAX];
606 const char *search_path;
607 int rc = 0;
608
609 if (libthread_db_search_path == NULL)
610 libthread_db_search_path = xstrdup (LIBTHREAD_DB_SEARCH_PATH);
611
612 search_path = libthread_db_search_path;
613 while (*search_path)
614 {
615 const char *end = strchr (search_path, ':');
616 if (end)
617 {
618 size_t len = end - search_path;
619 if (len + 1 + strlen (LIBTHREAD_DB_SO) + 1 > sizeof (path))
620 {
621 char *cp = xmalloc (len + 1);
622 memcpy (cp, search_path, len);
623 cp[len] = '\0';
624 warning ("libthread_db_search_path component too long, "
625 "ignored: %s.", cp);
626 free (cp);
627 search_path += len + 1;
628 continue;
629 }
630 memcpy (path, search_path, len);
631 path[len] = '\0';
632 search_path += len + 1;
633 }
634 else
635 {
636 size_t len = strlen (search_path);
637
638 if (len + 1 + strlen (LIBTHREAD_DB_SO) + 1 > sizeof (path))
639 {
640 warning ("libthread_db_search_path component too long,"
641 " ignored: %s.", search_path);
642 break;
643 }
644 memcpy (path, search_path, len + 1);
645 search_path += len;
646 }
647 strcat (path, "/");
648 strcat (path, LIBTHREAD_DB_SO);
649 if (debug_threads)
650 fprintf (stderr, "thread_db_load_search trying %s\n", path);
651 if (try_thread_db_load (path))
652 {
653 rc = 1;
654 break;
655 }
656 }
657 if (rc == 0)
658 rc = try_thread_db_load (LIBTHREAD_DB_SO);
659
660 if (debug_threads)
661 fprintf (stderr, "thread_db_load_search returning %d\n", rc);
662 return rc;
dae5f5cf
DJ
663}
664
0d62e5e8 665int
24a09b5f 666thread_db_init (int use_events)
0d62e5e8 667{
95954743 668 struct process_info *proc = current_process ();
0d62e5e8 669
fd500816
DJ
670 /* FIXME drow/2004-10-16: This is the "overall process ID", which
671 GNU/Linux calls tgid, "thread group ID". When we support
672 attaching to threads, the original thread may not be the correct
673 thread. We would have to get the process ID from /proc for NPTL.
674 For LinuxThreads we could do something similar: follow the chain
675 of parent processes until we find the highest one we're attached
676 to, and use its tgid.
677
678 This isn't the only place in gdbserver that assumes that the first
679 process in the list is the thread group leader. */
ea025f5f 680
24a09b5f
DJ
681 thread_db_use_events = use_events;
682
cdbfd419 683 if (thread_db_load_search ())
0d62e5e8 684 {
24a09b5f 685 if (use_events && thread_db_enable_reporting () == 0)
cdbfd419
PP
686 {
687 /* Keep trying; maybe event reporting will work later. */
688 thread_db_free (proc);
689 return 0;
690 }
0d62e5e8 691 thread_db_find_new_threads ();
fd500816 692 thread_db_look_up_symbols ();
95954743 693 proc->all_symbols_looked_up = 1;
0d62e5e8 694 return 1;
cdbfd419 695 }
0d62e5e8 696
cdbfd419
PP
697 return 0;
698}
699
700/* Disconnect from libthread_db and free resources. */
701
702void
703thread_db_free (struct process_info *proc)
704{
705 struct thread_db *thread_db = proc->private->thread_db;
706 if (thread_db)
707 {
708 td_err_e (*td_ta_delete_p) (td_thragent_t *);
709
710 td_ta_delete_p = dlsym (thread_db->handle, "td_ta_delete");
711 if (td_ta_delete_p != NULL)
712 (*td_ta_delete_p) (thread_db->thread_agent);
713
714 dlclose (thread_db->handle);
715 free (thread_db);
716 proc->private->thread_db = NULL;
717 }
718}
719
720/* Handle "set libthread-db-search-path" monitor command and return 1.
721 For any other command, return 0. */
722
723int
724thread_db_handle_monitor_command (char *mon)
725{
726 if (strncmp (mon, "set libthread-db-search-path ", 29) == 0)
727 {
728 const char *cp = mon + 29;
729
730 if (libthread_db_search_path != NULL)
731 free (libthread_db_search_path);
732
733 /* Skip leading space (if any). */
734 while (isspace (*cp))
735 ++cp;
736
737 libthread_db_search_path = xstrdup (cp);
738
739 monitor_output ("libthread-db-search-path set to `");
740 monitor_output (libthread_db_search_path);
741 monitor_output ("'\n");
742 return 1;
0d62e5e8
DJ
743 }
744
cdbfd419 745 /* Tell server.c to perform default processing. */
0d62e5e8
DJ
746 return 0;
747}
This page took 0.540258 seconds and 4 git commands to generate.