1 /* Thread management interface, for the remote server for GDB.
2 Copyright (C) 2002, 2004-2012 Free Software Foundation, Inc.
4 Contributed by MontaVista Software.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #include "linux-low.h"
25 extern int debug_threads
;
27 static int thread_db_use_events
;
29 #include "gdb_proc_service.h"
30 #include "gdb_thread_db.h"
32 #ifndef USE_LIBTHREAD_DB_DIRECTLY
42 /* Structure that identifies the child process for the
43 <proc_service.h> interface. */
44 struct ps_prochandle proc_handle
;
46 /* Connection to the libthread_db library. */
47 td_thragent_t
*thread_agent
;
49 /* If this flag has been set, we've already asked GDB for all
50 symbols we might need; assume symbol cache misses are
52 int all_symbols_looked_up
;
54 #ifndef USE_LIBTHREAD_DB_DIRECTLY
55 /* Handle of the libthread_db from dlopen. */
59 /* Thread creation event breakpoint. The code at this location in
60 the child process will be called by the pthread library whenever
61 a new thread is created. By setting a special breakpoint at this
62 location, GDB can detect when a new thread is created. We obtain
63 this location via the td_ta_event_addr call. Note that if the
64 running kernel supports tracing clones, then we don't need to use
65 (and in fact don't use) this magic thread event breakpoint to
66 learn about threads. */
67 struct breakpoint
*td_create_bp
;
69 /* Addresses of libthread_db functions. */
70 td_err_e (*td_ta_new_p
) (struct ps_prochandle
* ps
, td_thragent_t
**ta
);
71 td_err_e (*td_ta_event_getmsg_p
) (const td_thragent_t
*ta
,
73 td_err_e (*td_ta_set_event_p
) (const td_thragent_t
*ta
,
74 td_thr_events_t
*event
);
75 td_err_e (*td_ta_event_addr_p
) (const td_thragent_t
*ta
,
76 td_event_e event
, td_notify_t
*ptr
);
77 td_err_e (*td_ta_map_lwp2thr_p
) (const td_thragent_t
*ta
, lwpid_t lwpid
,
79 td_err_e (*td_thr_get_info_p
) (const td_thrhandle_t
*th
,
81 td_err_e (*td_thr_event_enable_p
) (const td_thrhandle_t
*th
, int event
);
82 td_err_e (*td_ta_thr_iter_p
) (const td_thragent_t
*ta
,
83 td_thr_iter_f
*callback
, void *cbdata_p
,
84 td_thr_state_e state
, int ti_pri
,
85 sigset_t
*ti_sigmask_p
,
86 unsigned int ti_user_flags
);
87 td_err_e (*td_thr_tls_get_addr_p
) (const td_thrhandle_t
*th
,
89 size_t offset
, psaddr_t
*address
);
90 const char ** (*td_symbol_list_p
) (void);
93 static char *libthread_db_search_path
;
95 static int find_one_thread (ptid_t
);
96 static int find_new_threads_callback (const td_thrhandle_t
*th_p
, void *data
);
99 thread_db_err_str (td_err_e err
)
106 return "generic 'call succeeded'";
108 return "generic error";
110 return "no thread to satisfy query";
112 return "no sync handle to satisfy query";
114 return "no LWP to satisfy query";
116 return "invalid process handle";
118 return "invalid thread handle";
120 return "invalid synchronization handle";
122 return "invalid thread agent";
124 return "invalid key";
126 return "no event message for getmsg";
128 return "FPU register set not available";
130 return "application not linked with libthread";
132 return "requested event is not supported";
134 return "capability not available";
136 return "debugger service failed";
138 return "operation not applicable to";
140 return "no thread-specific data for this thread";
142 return "malloc failed";
144 return "only part of register set was written/read";
146 return "X register set not available for this thread";
147 #ifdef HAVE_TD_VERSION
149 return "version mismatch between libthread_db and libpthread";
152 xsnprintf (buf
, sizeof (buf
), "unknown thread_db error '%d'", err
);
159 thread_db_state_str (td_thr_state_e state
)
166 return "stopped by debugger";
175 case TD_THR_STOPPED_ASLEEP
:
176 return "stopped by debugger AND blocked";
178 xsnprintf (buf
, sizeof (buf
), "unknown thread_db state %d", state
);
185 thread_db_create_event (CORE_ADDR where
)
189 struct lwp_info
*lwp
;
190 struct thread_db
*thread_db
= current_process ()->private->thread_db
;
192 if (thread_db
->td_ta_event_getmsg_p
== NULL
)
193 fatal ("unexpected thread_db->td_ta_event_getmsg_p == NULL");
196 fprintf (stderr
, "Thread creation event.\n");
198 /* FIXME: This assumes we don't get another event.
199 In the LinuxThreads implementation, this is safe,
200 because all events come from the manager thread
201 (except for its own creation, of course). */
202 err
= thread_db
->td_ta_event_getmsg_p (thread_db
->thread_agent
, &msg
);
204 fprintf (stderr
, "thread getmsg err: %s\n",
205 thread_db_err_str (err
));
207 /* If we do not know about the main thread yet, this would be a good time to
208 find it. We need to do this to pick up the main thread before any newly
210 lwp
= get_thread_lwp (current_inferior
);
211 if (lwp
->thread_known
== 0)
212 find_one_thread (lwp
->head
.id
);
214 /* msg.event == TD_EVENT_CREATE */
216 find_new_threads_callback (msg
.th_p
, NULL
);
222 thread_db_enable_reporting (void)
224 td_thr_events_t events
;
227 struct thread_db
*thread_db
= current_process ()->private->thread_db
;
229 if (thread_db
->td_ta_set_event_p
== NULL
230 || thread_db
->td_ta_event_addr_p
== NULL
231 || thread_db
->td_ta_event_getmsg_p
== NULL
)
232 /* This libthread_db is missing required support. */
235 /* Set the process wide mask saying which events we're interested in. */
236 td_event_emptyset (&events
);
237 td_event_addset (&events
, TD_CREATE
);
239 err
= thread_db
->td_ta_set_event_p (thread_db
->thread_agent
, &events
);
242 warning ("Unable to set global thread event mask: %s",
243 thread_db_err_str (err
));
247 /* Get address for thread creation breakpoint. */
248 err
= thread_db
->td_ta_event_addr_p (thread_db
->thread_agent
, TD_CREATE
,
252 warning ("Unable to get location for thread creation breakpoint: %s",
253 thread_db_err_str (err
));
256 thread_db
->td_create_bp
257 = set_breakpoint_at ((CORE_ADDR
) (unsigned long) notify
.u
.bptaddr
,
258 thread_db_create_event
);
264 find_one_thread (ptid_t ptid
)
269 struct thread_info
*inferior
;
270 struct lwp_info
*lwp
;
271 struct thread_db
*thread_db
= current_process ()->private->thread_db
;
272 int lwpid
= ptid_get_lwp (ptid
);
274 inferior
= (struct thread_info
*) find_inferior_id (&all_threads
, ptid
);
275 lwp
= get_thread_lwp (inferior
);
276 if (lwp
->thread_known
)
279 /* Get information about this thread. */
280 err
= thread_db
->td_ta_map_lwp2thr_p (thread_db
->thread_agent
, lwpid
, &th
);
282 error ("Cannot get thread handle for LWP %d: %s",
283 lwpid
, thread_db_err_str (err
));
285 err
= thread_db
->td_thr_get_info_p (&th
, &ti
);
287 error ("Cannot get thread info for LWP %d: %s",
288 lwpid
, thread_db_err_str (err
));
291 fprintf (stderr
, "Found thread %ld (LWP %d)\n",
292 ti
.ti_tid
, ti
.ti_lid
);
294 if (lwpid
!= ti
.ti_lid
)
296 warning ("PID mismatch! Expected %ld, got %ld",
297 (long) lwpid
, (long) ti
.ti_lid
);
301 if (thread_db_use_events
)
303 err
= thread_db
->td_thr_event_enable_p (&th
, 1);
305 error ("Cannot enable thread event reporting for %d: %s",
306 ti
.ti_lid
, thread_db_err_str (err
));
309 /* If the new thread ID is zero, a final thread ID will be available
310 later. Do not enable thread debugging yet. */
314 lwp
->thread_known
= 1;
320 /* Attach a thread. Return true on success. */
323 attach_thread (const td_thrhandle_t
*th_p
, td_thrinfo_t
*ti_p
)
325 struct lwp_info
*lwp
;
328 fprintf (stderr
, "Attaching to thread %ld (LWP %d)\n",
329 ti_p
->ti_tid
, ti_p
->ti_lid
);
330 linux_attach_lwp (ti_p
->ti_lid
);
331 lwp
= find_lwp_pid (pid_to_ptid (ti_p
->ti_lid
));
334 warning ("Could not attach to thread %ld (LWP %d)\n",
335 ti_p
->ti_tid
, ti_p
->ti_lid
);
339 lwp
->thread_known
= 1;
342 if (thread_db_use_events
)
345 struct thread_db
*thread_db
= current_process ()->private->thread_db
;
347 err
= thread_db
->td_thr_event_enable_p (th_p
, 1);
349 error ("Cannot enable thread event reporting for %d: %s",
350 ti_p
->ti_lid
, thread_db_err_str (err
));
356 /* Attach thread if we haven't seen it yet.
357 Increment *COUNTER if we have attached a new thread.
358 Return false on failure. */
361 maybe_attach_thread (const td_thrhandle_t
*th_p
, td_thrinfo_t
*ti_p
,
364 struct lwp_info
*lwp
;
366 lwp
= find_lwp_pid (pid_to_ptid (ti_p
->ti_lid
));
370 if (!attach_thread (th_p
, ti_p
))
380 find_new_threads_callback (const td_thrhandle_t
*th_p
, void *data
)
384 struct thread_db
*thread_db
= current_process ()->private->thread_db
;
386 err
= thread_db
->td_thr_get_info_p (th_p
, &ti
);
388 error ("Cannot get thread info: %s", thread_db_err_str (err
));
390 /* Check for zombies. */
391 if (ti
.ti_state
== TD_THR_UNKNOWN
|| ti
.ti_state
== TD_THR_ZOMBIE
)
394 if (!maybe_attach_thread (th_p
, &ti
, (int *) data
))
396 /* Terminate iteration early: we might be looking at stale data in
397 the inferior. The thread_db_find_new_threads will retry. */
405 thread_db_find_new_threads (void)
408 ptid_t ptid
= ((struct inferior_list_entry
*) current_inferior
)->id
;
409 struct thread_db
*thread_db
= current_process ()->private->thread_db
;
412 /* This function is only called when we first initialize thread_db.
413 First locate the initial thread. If it is not ready for
414 debugging yet, then stop. */
415 if (find_one_thread (ptid
) == 0)
418 /* Require 4 successive iterations which do not find any new threads.
419 The 4 is a heuristic: there is an inherent race here, and I have
420 seen that 2 iterations in a row are not always sufficient to
421 "capture" all threads. */
422 for (loop
= 0, iteration
= 0; loop
< 4; ++loop
, ++iteration
)
424 int new_thread_count
= 0;
426 /* Iterate over all user-space threads to discover new threads. */
427 err
= thread_db
->td_ta_thr_iter_p (thread_db
->thread_agent
,
428 find_new_threads_callback
,
431 TD_THR_LOWEST_PRIORITY
,
432 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
);
434 fprintf (stderr
, "Found %d threads in iteration %d.\n",
435 new_thread_count
, iteration
);
437 if (new_thread_count
!= 0)
439 /* Found new threads. Restart iteration from beginning. */
444 error ("Cannot find new threads: %s", thread_db_err_str (err
));
447 /* Cache all future symbols that thread_db might request. We can not
448 request symbols at arbitrary states in the remote protocol, only
449 when the client tells us that new symbols are available. So when
450 we load the thread library, make sure to check the entire list. */
453 thread_db_look_up_symbols (void)
455 struct thread_db
*thread_db
= current_process ()->private->thread_db
;
456 const char **sym_list
;
459 for (sym_list
= thread_db
->td_symbol_list_p (); *sym_list
; sym_list
++)
460 look_up_one_symbol (*sym_list
, &unused
, 1);
462 /* We're not interested in any other libraries loaded after this
463 point, only in symbols in libpthread.so. */
464 thread_db
->all_symbols_looked_up
= 1;
468 thread_db_look_up_one_symbol (const char *name
, CORE_ADDR
*addrp
)
470 struct thread_db
*thread_db
= current_process ()->private->thread_db
;
471 int may_ask_gdb
= !thread_db
->all_symbols_looked_up
;
473 /* If we've passed the call to thread_db_look_up_symbols, then
474 anything not in the cache must not exist; we're not interested
475 in any libraries loaded after that point, only in symbols in
476 libpthread.so. It might not be an appropriate time to look
477 up a symbol, e.g. while we're trying to fetch registers. */
478 return look_up_one_symbol (name
, addrp
, may_ask_gdb
);
482 thread_db_get_tls_address (struct thread_info
*thread
, CORE_ADDR offset
,
483 CORE_ADDR load_module
, CORE_ADDR
*address
)
487 struct lwp_info
*lwp
;
488 struct thread_info
*saved_inferior
;
489 struct process_info
*proc
;
490 struct thread_db
*thread_db
;
492 proc
= get_thread_process (thread
);
493 thread_db
= proc
->private->thread_db
;
495 /* If the thread layer is not (yet) initialized, fail. */
496 if (!thread_db
->all_symbols_looked_up
)
499 if (thread_db
->td_thr_tls_get_addr_p
== NULL
)
502 lwp
= get_thread_lwp (thread
);
503 if (!lwp
->thread_known
)
504 find_one_thread (lwp
->head
.id
);
505 if (!lwp
->thread_known
)
508 saved_inferior
= current_inferior
;
509 current_inferior
= thread
;
510 /* Note the cast through uintptr_t: this interface only works if
511 a target address fits in a psaddr_t, which is a host pointer.
512 So a 32-bit debugger can not access 64-bit TLS through this. */
513 err
= thread_db
->td_thr_tls_get_addr_p (&lwp
->th
,
514 (psaddr_t
) (uintptr_t) load_module
,
516 current_inferior
= saved_inferior
;
519 *address
= (CORE_ADDR
) (uintptr_t) addr
;
526 #ifdef USE_LIBTHREAD_DB_DIRECTLY
529 thread_db_load_search (void)
532 struct thread_db
*tdb
;
533 struct process_info
*proc
= current_process ();
535 if (proc
->private->thread_db
!= NULL
)
536 fatal ("unexpected: proc->private->thread_db != NULL");
538 tdb
= xcalloc (1, sizeof (*tdb
));
539 proc
->private->thread_db
= tdb
;
541 tdb
->td_ta_new_p
= &td_ta_new
;
543 /* Attempt to open a connection to the thread library. */
544 err
= tdb
->td_ta_new_p (&tdb
->proc_handle
, &tdb
->thread_agent
);
548 fprintf (stderr
, "td_ta_new(): %s\n", thread_db_err_str (err
));
550 proc
->private->thread_db
= NULL
;
554 tdb
->td_ta_map_lwp2thr_p
= &td_ta_map_lwp2thr
;
555 tdb
->td_thr_get_info_p
= &td_thr_get_info
;
556 tdb
->td_ta_thr_iter_p
= &td_ta_thr_iter
;
557 tdb
->td_symbol_list_p
= &td_symbol_list
;
559 /* This is required only when thread_db_use_events is on. */
560 tdb
->td_thr_event_enable_p
= &td_thr_event_enable
;
562 /* These are not essential. */
563 tdb
->td_ta_event_addr_p
= &td_ta_event_addr
;
564 tdb
->td_ta_set_event_p
= &td_ta_set_event
;
565 tdb
->td_ta_event_getmsg_p
= &td_ta_event_getmsg
;
566 tdb
->td_thr_tls_get_addr_p
= &td_thr_tls_get_addr
;
574 try_thread_db_load_1 (void *handle
)
577 struct thread_db
*tdb
;
578 struct process_info
*proc
= current_process ();
580 if (proc
->private->thread_db
!= NULL
)
581 fatal ("unexpected: proc->private->thread_db != NULL");
583 tdb
= xcalloc (1, sizeof (*tdb
));
584 proc
->private->thread_db
= tdb
;
586 tdb
->handle
= handle
;
588 /* Initialize pointers to the dynamic library functions we will use.
589 Essential functions first. */
591 #define CHK(required, a) \
597 fprintf (stderr, "dlsym: %s\n", dlerror ()); \
601 proc->private->thread_db = NULL; \
608 CHK (1, tdb
->td_ta_new_p
= dlsym (handle
, "td_ta_new"));
610 /* Attempt to open a connection to the thread library. */
611 err
= tdb
->td_ta_new_p (&tdb
->proc_handle
, &tdb
->thread_agent
);
615 fprintf (stderr
, "td_ta_new(): %s\n", thread_db_err_str (err
));
617 proc
->private->thread_db
= NULL
;
621 CHK (1, tdb
->td_ta_map_lwp2thr_p
= dlsym (handle
, "td_ta_map_lwp2thr"));
622 CHK (1, tdb
->td_thr_get_info_p
= dlsym (handle
, "td_thr_get_info"));
623 CHK (1, tdb
->td_ta_thr_iter_p
= dlsym (handle
, "td_ta_thr_iter"));
624 CHK (1, tdb
->td_symbol_list_p
= dlsym (handle
, "td_symbol_list"));
626 /* This is required only when thread_db_use_events is on. */
627 CHK (thread_db_use_events
,
628 tdb
->td_thr_event_enable_p
= dlsym (handle
, "td_thr_event_enable"));
630 /* These are not essential. */
631 CHK (0, tdb
->td_ta_event_addr_p
= dlsym (handle
, "td_ta_event_addr"));
632 CHK (0, tdb
->td_ta_set_event_p
= dlsym (handle
, "td_ta_set_event"));
633 CHK (0, tdb
->td_ta_event_getmsg_p
= dlsym (handle
, "td_ta_event_getmsg"));
634 CHK (0, tdb
->td_thr_tls_get_addr_p
= dlsym (handle
, "td_thr_tls_get_addr"));
643 /* Lookup a library in which given symbol resides.
644 Note: this is looking in the GDBSERVER process, not in the inferior.
645 Returns library name, or NULL. */
648 dladdr_to_soname (const void *addr
)
652 if (dladdr (addr
, &info
) != 0)
653 return info
.dli_fname
;
660 try_thread_db_load (const char *library
)
665 fprintf (stderr
, "Trying host libthread_db library: %s.\n",
667 handle
= dlopen (library
, RTLD_NOW
);
671 fprintf (stderr
, "dlopen failed: %s.\n", dlerror ());
676 if (debug_threads
&& strchr (library
, '/') == NULL
)
680 td_init
= dlsym (handle
, "td_init");
683 const char *const libpath
= dladdr_to_soname (td_init
);
686 fprintf (stderr
, "Host %s resolved to: %s.\n",
692 if (try_thread_db_load_1 (handle
))
695 /* This library "refused" to work on current inferior. */
700 /* Handle $sdir in libthread-db-search-path.
701 Look for libthread_db in the system dirs, or wherever a plain
702 dlopen(file_without_path) will look.
703 The result is true for success. */
706 try_thread_db_load_from_sdir (void)
708 return try_thread_db_load (LIBTHREAD_DB_SO
);
711 /* Try to load libthread_db from directory DIR of length DIR_LEN.
712 The result is true for success. */
715 try_thread_db_load_from_dir (const char *dir
, size_t dir_len
)
719 if (dir_len
+ 1 + strlen (LIBTHREAD_DB_SO
) + 1 > sizeof (path
))
721 char *cp
= xmalloc (dir_len
+ 1);
723 memcpy (cp
, dir
, dir_len
);
725 warning (_("libthread-db-search-path component too long,"
726 " ignored: %s."), cp
);
731 memcpy (path
, dir
, dir_len
);
733 strcpy (path
+ dir_len
+ 1, LIBTHREAD_DB_SO
);
734 return try_thread_db_load (path
);
737 /* Search libthread_db_search_path for libthread_db which "agrees"
738 to work on current inferior.
739 The result is true for success. */
742 thread_db_load_search (void)
744 const char *search_path
;
747 if (libthread_db_search_path
== NULL
)
748 libthread_db_search_path
= xstrdup (LIBTHREAD_DB_SEARCH_PATH
);
750 search_path
= libthread_db_search_path
;
753 const char *end
= strchr (search_path
, ':');
754 const char *this_dir
= search_path
;
759 this_dir_len
= end
- search_path
;
760 search_path
+= this_dir_len
+ 1;
764 this_dir_len
= strlen (this_dir
);
765 search_path
+= this_dir_len
;
768 if (this_dir_len
== sizeof ("$pdir") - 1
769 && strncmp (this_dir
, "$pdir", this_dir_len
) == 0)
771 /* We don't maintain a list of loaded libraries so we don't know
772 where libpthread lives. We *could* fetch the info, but we don't
773 do that yet. Ignore it. */
775 else if (this_dir_len
== sizeof ("$sdir") - 1
776 && strncmp (this_dir
, "$sdir", this_dir_len
) == 0)
778 if (try_thread_db_load_from_sdir ())
786 if (try_thread_db_load_from_dir (this_dir
, this_dir_len
))
795 fprintf (stderr
, "thread_db_load_search returning %d\n", rc
);
799 #endif /* USE_LIBTHREAD_DB_DIRECTLY */
802 thread_db_init (int use_events
)
804 struct process_info
*proc
= current_process ();
806 /* FIXME drow/2004-10-16: This is the "overall process ID", which
807 GNU/Linux calls tgid, "thread group ID". When we support
808 attaching to threads, the original thread may not be the correct
809 thread. We would have to get the process ID from /proc for NPTL.
810 For LinuxThreads we could do something similar: follow the chain
811 of parent processes until we find the highest one we're attached
812 to, and use its tgid.
814 This isn't the only place in gdbserver that assumes that the first
815 process in the list is the thread group leader. */
817 thread_db_use_events
= use_events
;
819 if (thread_db_load_search ())
821 if (use_events
&& thread_db_enable_reporting () == 0)
823 /* Keep trying; maybe event reporting will work later. */
824 thread_db_mourn (proc
);
827 thread_db_find_new_threads ();
828 thread_db_look_up_symbols ();
836 any_thread_of (struct inferior_list_entry
*entry
, void *args
)
840 if (ptid_get_pid (entry
->id
) == *pid_p
)
847 switch_to_process (struct process_info
*proc
)
849 int pid
= pid_of (proc
);
852 (struct thread_info
*) find_inferior (&all_threads
,
853 any_thread_of
, &pid
);
856 /* Disconnect from libthread_db and free resources. */
859 disable_thread_event_reporting (struct process_info
*proc
)
861 struct thread_db
*thread_db
= proc
->private->thread_db
;
864 td_err_e (*td_ta_clear_event_p
) (const td_thragent_t
*ta
,
865 td_thr_events_t
*event
);
867 #ifndef USE_LIBTHREAD_DB_DIRECTLY
868 td_ta_clear_event_p
= dlsym (thread_db
->handle
, "td_ta_clear_event");
870 td_ta_clear_event_p
= &td_ta_clear_event
;
873 if (td_ta_clear_event_p
!= NULL
)
875 struct thread_info
*saved_inferior
= current_inferior
;
876 td_thr_events_t events
;
878 switch_to_process (proc
);
880 /* Set the process wide mask saying we aren't interested
881 in any events anymore. */
882 td_event_fillset (&events
);
883 (*td_ta_clear_event_p
) (thread_db
->thread_agent
, &events
);
885 current_inferior
= saved_inferior
;
891 remove_thread_event_breakpoints (struct process_info
*proc
)
893 struct thread_db
*thread_db
= proc
->private->thread_db
;
895 if (thread_db
->td_create_bp
!= NULL
)
897 struct thread_info
*saved_inferior
= current_inferior
;
899 switch_to_process (proc
);
901 delete_breakpoint (thread_db
->td_create_bp
);
902 thread_db
->td_create_bp
= NULL
;
904 current_inferior
= saved_inferior
;
909 thread_db_detach (struct process_info
*proc
)
911 struct thread_db
*thread_db
= proc
->private->thread_db
;
915 disable_thread_event_reporting (proc
);
916 remove_thread_event_breakpoints (proc
);
920 /* Disconnect from libthread_db and free resources. */
923 thread_db_mourn (struct process_info
*proc
)
925 struct thread_db
*thread_db
= proc
->private->thread_db
;
928 td_err_e (*td_ta_delete_p
) (td_thragent_t
*);
930 #ifndef USE_LIBTHREAD_DB_DIRECTLY
931 td_ta_delete_p
= dlsym (thread_db
->handle
, "td_ta_delete");
933 td_ta_delete_p
= &td_ta_delete
;
936 if (td_ta_delete_p
!= NULL
)
937 (*td_ta_delete_p
) (thread_db
->thread_agent
);
939 #ifndef USE_LIBTHREAD_DB_DIRECTLY
940 dlclose (thread_db
->handle
);
941 #endif /* USE_LIBTHREAD_DB_DIRECTLY */
944 proc
->private->thread_db
= NULL
;
948 /* Handle "set libthread-db-search-path" monitor command and return 1.
949 For any other command, return 0. */
952 thread_db_handle_monitor_command (char *mon
)
954 const char *cmd
= "set libthread-db-search-path";
955 size_t cmd_len
= strlen (cmd
);
957 if (strncmp (mon
, cmd
, cmd_len
) == 0
958 && (mon
[cmd_len
] == '\0'
959 || mon
[cmd_len
] == ' '))
961 const char *cp
= mon
+ cmd_len
;
963 if (libthread_db_search_path
!= NULL
)
964 free (libthread_db_search_path
);
966 /* Skip leading space (if any). */
967 while (isspace (*cp
))
971 cp
= LIBTHREAD_DB_SEARCH_PATH
;
972 libthread_db_search_path
= xstrdup (cp
);
974 monitor_output ("libthread-db-search-path set to `");
975 monitor_output (libthread_db_search_path
);
976 monitor_output ("'\n");
980 /* Tell server.c to perform default processing. */