xref: /openbsd-src/gnu/usr.bin/binutils/gdb/thread-db.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* libthread_db assisted debugging support, generic parts.
2b725ae77Skettenis 
3*11efff7fSkettenis    Copyright 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
4b725ae77Skettenis 
5b725ae77Skettenis    This file is part of GDB.
6b725ae77Skettenis 
7b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis    it under the terms of the GNU General Public License as published by
9b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis    (at your option) any later version.
11b725ae77Skettenis 
12b725ae77Skettenis    This program is distributed in the hope that it will be useful,
13b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15b725ae77Skettenis    GNU General Public License for more details.
16b725ae77Skettenis 
17b725ae77Skettenis    You should have received a copy of the GNU General Public License
18b725ae77Skettenis    along with this program; if not, write to the Free Software
19b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
21b725ae77Skettenis 
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis 
24b725ae77Skettenis #include "gdb_assert.h"
25b725ae77Skettenis #include <dlfcn.h>
26b725ae77Skettenis #include "gdb_proc_service.h"
27b725ae77Skettenis #include "gdb_thread_db.h"
28b725ae77Skettenis 
29b725ae77Skettenis #include "bfd.h"
30b725ae77Skettenis #include "gdbthread.h"
31b725ae77Skettenis #include "inferior.h"
32b725ae77Skettenis #include "symfile.h"
33b725ae77Skettenis #include "objfiles.h"
34b725ae77Skettenis #include "target.h"
35b725ae77Skettenis #include "regcache.h"
36b725ae77Skettenis #include "solib-svr4.h"
37b725ae77Skettenis 
38*11efff7fSkettenis #ifdef HAVE_GNU_LIBC_VERSION_H
39*11efff7fSkettenis #include <gnu/libc-version.h>
40*11efff7fSkettenis #endif
41*11efff7fSkettenis 
42b725ae77Skettenis #ifndef LIBTHREAD_DB_SO
43b725ae77Skettenis #define LIBTHREAD_DB_SO "libthread_db.so.1"
44b725ae77Skettenis #endif
45b725ae77Skettenis 
46b725ae77Skettenis /* If we're running on GNU/Linux, we must explicitly attach to any new
47b725ae77Skettenis    threads.  */
48b725ae77Skettenis 
49b725ae77Skettenis /* FIXME: There is certainly some room for improvements:
50b725ae77Skettenis    - Cache LWP ids.
51b725ae77Skettenis    - Bypass libthread_db when fetching or storing registers for
52b725ae77Skettenis    threads bound to a LWP.  */
53b725ae77Skettenis 
54b725ae77Skettenis /* This module's target vector.  */
55b725ae77Skettenis static struct target_ops thread_db_ops;
56b725ae77Skettenis 
57b725ae77Skettenis /* The target vector that we call for things this module can't handle.  */
58b725ae77Skettenis static struct target_ops *target_beneath;
59b725ae77Skettenis 
60b725ae77Skettenis /* Pointer to the next function on the objfile event chain.  */
61b725ae77Skettenis static void (*target_new_objfile_chain) (struct objfile * objfile);
62b725ae77Skettenis 
63b725ae77Skettenis /* Non-zero if we're using this module's target vector.  */
64b725ae77Skettenis static int using_thread_db;
65b725ae77Skettenis 
66b725ae77Skettenis /* Non-zero if we have determined the signals used by the threads
67b725ae77Skettenis    library.  */
68b725ae77Skettenis static int thread_signals;
69b725ae77Skettenis static sigset_t thread_stop_set;
70b725ae77Skettenis static sigset_t thread_print_set;
71b725ae77Skettenis 
72b725ae77Skettenis /* Structure that identifies the child process for the
73b725ae77Skettenis    <proc_service.h> interface.  */
74b725ae77Skettenis static struct ps_prochandle proc_handle;
75b725ae77Skettenis 
76b725ae77Skettenis /* Connection to the libthread_db library.  */
77b725ae77Skettenis static td_thragent_t *thread_agent;
78b725ae77Skettenis 
79b725ae77Skettenis /* Pointers to the libthread_db functions.  */
80b725ae77Skettenis 
81b725ae77Skettenis static td_err_e (*td_init_p) (void);
82b725ae77Skettenis 
83b725ae77Skettenis static td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
84b725ae77Skettenis 				td_thragent_t **ta);
85b725ae77Skettenis static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
86b725ae77Skettenis 				       td_thrhandle_t *__th);
87b725ae77Skettenis static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
88b725ae77Skettenis 					lwpid_t lwpid, td_thrhandle_t *th);
89b725ae77Skettenis static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
90b725ae77Skettenis 				     td_thr_iter_f *callback, void *cbdata_p,
91b725ae77Skettenis 				     td_thr_state_e state, int ti_pri,
92b725ae77Skettenis 				     sigset_t *ti_sigmask_p,
93b725ae77Skettenis 				     unsigned int ti_user_flags);
94b725ae77Skettenis static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
95b725ae77Skettenis 				       td_event_e event, td_notify_t *ptr);
96b725ae77Skettenis static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
97b725ae77Skettenis 				      td_thr_events_t *event);
98b725ae77Skettenis static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
99b725ae77Skettenis 					 td_event_msg_t *msg);
100b725ae77Skettenis 
101b725ae77Skettenis static td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
102b725ae77Skettenis static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
103b725ae77Skettenis 				      td_thrinfo_t *infop);
104b725ae77Skettenis static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
105b725ae77Skettenis 				       gdb_prfpregset_t *regset);
106b725ae77Skettenis static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
107b725ae77Skettenis 				      prgregset_t gregs);
108b725ae77Skettenis static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
109b725ae77Skettenis 				       const gdb_prfpregset_t *fpregs);
110b725ae77Skettenis static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
111b725ae77Skettenis 				      prgregset_t gregs);
112b725ae77Skettenis static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
113b725ae77Skettenis 					  int event);
114b725ae77Skettenis 
115b725ae77Skettenis static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
116b725ae77Skettenis 					  void *map_address,
117b725ae77Skettenis 					  size_t offset, void **address);
118b725ae77Skettenis 
119b725ae77Skettenis /* Location of the thread creation event breakpoint.  The code at this
120b725ae77Skettenis    location in the child process will be called by the pthread library
121b725ae77Skettenis    whenever a new thread is created.  By setting a special breakpoint
122b725ae77Skettenis    at this location, GDB can detect when a new thread is created.  We
123b725ae77Skettenis    obtain this location via the td_ta_event_addr call.  */
124b725ae77Skettenis static CORE_ADDR td_create_bp_addr;
125b725ae77Skettenis 
126b725ae77Skettenis /* Location of the thread death event breakpoint.  */
127b725ae77Skettenis static CORE_ADDR td_death_bp_addr;
128b725ae77Skettenis 
129b725ae77Skettenis /* Prototypes for local functions.  */
130b725ae77Skettenis static void thread_db_find_new_threads (void);
131b725ae77Skettenis static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
132b725ae77Skettenis 			   const td_thrinfo_t *ti_p, int verbose);
133*11efff7fSkettenis static void detach_thread (ptid_t ptid, int verbose);
134b725ae77Skettenis 
135b725ae77Skettenis 
136b725ae77Skettenis /* Building process ids.  */
137b725ae77Skettenis 
138b725ae77Skettenis #define GET_PID(ptid)		ptid_get_pid (ptid)
139b725ae77Skettenis #define GET_LWP(ptid)		ptid_get_lwp (ptid)
140b725ae77Skettenis #define GET_THREAD(ptid)	ptid_get_tid (ptid)
141b725ae77Skettenis 
142b725ae77Skettenis #define is_lwp(ptid)		(GET_LWP (ptid) != 0)
143b725ae77Skettenis #define is_thread(ptid)		(GET_THREAD (ptid) != 0)
144b725ae77Skettenis 
145b725ae77Skettenis #define BUILD_LWP(lwp, pid)	ptid_build (pid, lwp, 0)
146b725ae77Skettenis #define BUILD_THREAD(tid, pid)	ptid_build (pid, 0, tid)
147b725ae77Skettenis 
148b725ae77Skettenis 
149b725ae77Skettenis /* Use "struct private_thread_info" to cache thread state.  This is
150b725ae77Skettenis    a substantial optimization.  */
151b725ae77Skettenis 
152b725ae77Skettenis struct private_thread_info
153b725ae77Skettenis {
154*11efff7fSkettenis   /* Flag set when we see a TD_DEATH event for this thread.  */
155*11efff7fSkettenis   unsigned int dying:1;
156*11efff7fSkettenis 
157b725ae77Skettenis   /* Cached thread state.  */
158b725ae77Skettenis   unsigned int th_valid:1;
159b725ae77Skettenis   unsigned int ti_valid:1;
160b725ae77Skettenis 
161b725ae77Skettenis   td_thrhandle_t th;
162b725ae77Skettenis   td_thrinfo_t ti;
163b725ae77Skettenis };
164b725ae77Skettenis 
165b725ae77Skettenis 
166b725ae77Skettenis static char *
thread_db_err_str(td_err_e err)167b725ae77Skettenis thread_db_err_str (td_err_e err)
168b725ae77Skettenis {
169b725ae77Skettenis   static char buf[64];
170b725ae77Skettenis 
171b725ae77Skettenis   switch (err)
172b725ae77Skettenis     {
173b725ae77Skettenis     case TD_OK:
174b725ae77Skettenis       return "generic 'call succeeded'";
175b725ae77Skettenis     case TD_ERR:
176b725ae77Skettenis       return "generic error";
177b725ae77Skettenis     case TD_NOTHR:
178b725ae77Skettenis       return "no thread to satisfy query";
179b725ae77Skettenis     case TD_NOSV:
180b725ae77Skettenis       return "no sync handle to satisfy query";
181b725ae77Skettenis     case TD_NOLWP:
182b725ae77Skettenis       return "no LWP to satisfy query";
183b725ae77Skettenis     case TD_BADPH:
184b725ae77Skettenis       return "invalid process handle";
185b725ae77Skettenis     case TD_BADTH:
186b725ae77Skettenis       return "invalid thread handle";
187b725ae77Skettenis     case TD_BADSH:
188b725ae77Skettenis       return "invalid synchronization handle";
189b725ae77Skettenis     case TD_BADTA:
190b725ae77Skettenis       return "invalid thread agent";
191b725ae77Skettenis     case TD_BADKEY:
192b725ae77Skettenis       return "invalid key";
193b725ae77Skettenis     case TD_NOMSG:
194b725ae77Skettenis       return "no event message for getmsg";
195b725ae77Skettenis     case TD_NOFPREGS:
196b725ae77Skettenis       return "FPU register set not available";
197b725ae77Skettenis     case TD_NOLIBTHREAD:
198b725ae77Skettenis       return "application not linked with libthread";
199b725ae77Skettenis     case TD_NOEVENT:
200b725ae77Skettenis       return "requested event is not supported";
201b725ae77Skettenis     case TD_NOCAPAB:
202b725ae77Skettenis       return "capability not available";
203b725ae77Skettenis     case TD_DBERR:
204b725ae77Skettenis       return "debugger service failed";
205b725ae77Skettenis     case TD_NOAPLIC:
206b725ae77Skettenis       return "operation not applicable to";
207b725ae77Skettenis     case TD_NOTSD:
208b725ae77Skettenis       return "no thread-specific data for this thread";
209b725ae77Skettenis     case TD_MALLOC:
210b725ae77Skettenis       return "malloc failed";
211b725ae77Skettenis     case TD_PARTIALREG:
212b725ae77Skettenis       return "only part of register set was written/read";
213b725ae77Skettenis     case TD_NOXREGS:
214b725ae77Skettenis       return "X register set not available for this thread";
215b725ae77Skettenis     default:
216b725ae77Skettenis       snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
217b725ae77Skettenis       return buf;
218b725ae77Skettenis     }
219b725ae77Skettenis }
220b725ae77Skettenis 
221b725ae77Skettenis static char *
thread_db_state_str(td_thr_state_e state)222b725ae77Skettenis thread_db_state_str (td_thr_state_e state)
223b725ae77Skettenis {
224b725ae77Skettenis   static char buf[64];
225b725ae77Skettenis 
226b725ae77Skettenis   switch (state)
227b725ae77Skettenis     {
228b725ae77Skettenis     case TD_THR_STOPPED:
229b725ae77Skettenis       return "stopped by debugger";
230b725ae77Skettenis     case TD_THR_RUN:
231b725ae77Skettenis       return "runnable";
232b725ae77Skettenis     case TD_THR_ACTIVE:
233b725ae77Skettenis       return "active";
234b725ae77Skettenis     case TD_THR_ZOMBIE:
235b725ae77Skettenis       return "zombie";
236b725ae77Skettenis     case TD_THR_SLEEP:
237b725ae77Skettenis       return "sleeping";
238b725ae77Skettenis     case TD_THR_STOPPED_ASLEEP:
239b725ae77Skettenis       return "stopped by debugger AND blocked";
240b725ae77Skettenis     default:
241b725ae77Skettenis       snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
242b725ae77Skettenis       return buf;
243b725ae77Skettenis     }
244b725ae77Skettenis }
245b725ae77Skettenis 
246b725ae77Skettenis /* A callback function for td_ta_thr_iter, which we use to map all
247b725ae77Skettenis    threads to LWPs.
248b725ae77Skettenis 
249b725ae77Skettenis    THP is a handle to the current thread; if INFOP is not NULL, the
250b725ae77Skettenis    struct thread_info associated with this thread is returned in
251*11efff7fSkettenis    *INFOP.
252*11efff7fSkettenis 
253*11efff7fSkettenis    If the thread is a zombie, TD_THR_ZOMBIE is returned.  Otherwise,
254*11efff7fSkettenis    zero is returned to indicate success.  */
255b725ae77Skettenis 
256b725ae77Skettenis static int
thread_get_info_callback(const td_thrhandle_t * thp,void * infop)257b725ae77Skettenis thread_get_info_callback (const td_thrhandle_t *thp, void *infop)
258b725ae77Skettenis {
259b725ae77Skettenis   td_thrinfo_t ti;
260b725ae77Skettenis   td_err_e err;
261b725ae77Skettenis   struct thread_info *thread_info;
262b725ae77Skettenis   ptid_t thread_ptid;
263b725ae77Skettenis 
264b725ae77Skettenis   err = td_thr_get_info_p (thp, &ti);
265b725ae77Skettenis   if (err != TD_OK)
266b725ae77Skettenis     error ("thread_get_info_callback: cannot get thread info: %s",
267b725ae77Skettenis 	   thread_db_err_str (err));
268b725ae77Skettenis 
269b725ae77Skettenis   /* Fill the cache.  */
270b725ae77Skettenis   thread_ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid));
271b725ae77Skettenis   thread_info = find_thread_pid (thread_ptid);
272b725ae77Skettenis 
273*11efff7fSkettenis   /* In the case of a zombie thread, don't continue.  We don't want to
274*11efff7fSkettenis      attach to it thinking it is a new thread.  */
275*11efff7fSkettenis   if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
276*11efff7fSkettenis     {
277*11efff7fSkettenis       if (infop != NULL)
278*11efff7fSkettenis         *(struct thread_info **) infop = thread_info;
279*11efff7fSkettenis       if (thread_info != NULL)
280*11efff7fSkettenis 	{
281*11efff7fSkettenis 	  memcpy (&thread_info->private->th, thp, sizeof (*thp));
282*11efff7fSkettenis 	  thread_info->private->th_valid = 1;
283*11efff7fSkettenis 	  memcpy (&thread_info->private->ti, &ti, sizeof (ti));
284*11efff7fSkettenis 	  thread_info->private->ti_valid = 1;
285*11efff7fSkettenis 	}
286*11efff7fSkettenis       return TD_THR_ZOMBIE;
287*11efff7fSkettenis     }
288*11efff7fSkettenis 
289b725ae77Skettenis   if (thread_info == NULL)
290b725ae77Skettenis     {
291b725ae77Skettenis       /* New thread.  Attach to it now (why wait?).  */
292b725ae77Skettenis       attach_thread (thread_ptid, thp, &ti, 1);
293b725ae77Skettenis       thread_info = find_thread_pid (thread_ptid);
294b725ae77Skettenis       gdb_assert (thread_info != NULL);
295b725ae77Skettenis     }
296b725ae77Skettenis 
297b725ae77Skettenis   memcpy (&thread_info->private->th, thp, sizeof (*thp));
298b725ae77Skettenis   thread_info->private->th_valid = 1;
299b725ae77Skettenis   memcpy (&thread_info->private->ti, &ti, sizeof (ti));
300b725ae77Skettenis   thread_info->private->ti_valid = 1;
301b725ae77Skettenis 
302b725ae77Skettenis   if (infop != NULL)
303b725ae77Skettenis     *(struct thread_info **) infop = thread_info;
304b725ae77Skettenis 
305b725ae77Skettenis   return 0;
306b725ae77Skettenis }
307b725ae77Skettenis 
308b725ae77Skettenis /* Accessor functions for the thread_db information, with caching.  */
309b725ae77Skettenis 
310b725ae77Skettenis static void
thread_db_map_id2thr(struct thread_info * thread_info,int fatal)311b725ae77Skettenis thread_db_map_id2thr (struct thread_info *thread_info, int fatal)
312b725ae77Skettenis {
313b725ae77Skettenis   td_err_e err;
314b725ae77Skettenis 
315b725ae77Skettenis   if (thread_info->private->th_valid)
316b725ae77Skettenis     return;
317b725ae77Skettenis 
318b725ae77Skettenis   err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (thread_info->ptid),
319b725ae77Skettenis 			    &thread_info->private->th);
320b725ae77Skettenis   if (err != TD_OK)
321b725ae77Skettenis     {
322b725ae77Skettenis       if (fatal)
323b725ae77Skettenis 	error ("Cannot find thread %ld: %s",
324b725ae77Skettenis 	       (long) GET_THREAD (thread_info->ptid),
325b725ae77Skettenis 	       thread_db_err_str (err));
326b725ae77Skettenis     }
327b725ae77Skettenis   else
328b725ae77Skettenis     thread_info->private->th_valid = 1;
329b725ae77Skettenis }
330b725ae77Skettenis 
331b725ae77Skettenis static td_thrinfo_t *
thread_db_get_info(struct thread_info * thread_info)332b725ae77Skettenis thread_db_get_info (struct thread_info *thread_info)
333b725ae77Skettenis {
334b725ae77Skettenis   td_err_e err;
335b725ae77Skettenis 
336b725ae77Skettenis   if (thread_info->private->ti_valid)
337b725ae77Skettenis     return &thread_info->private->ti;
338b725ae77Skettenis 
339b725ae77Skettenis   if (!thread_info->private->th_valid)
340b725ae77Skettenis     thread_db_map_id2thr (thread_info, 1);
341b725ae77Skettenis 
342b725ae77Skettenis   err =
343b725ae77Skettenis     td_thr_get_info_p (&thread_info->private->th, &thread_info->private->ti);
344b725ae77Skettenis   if (err != TD_OK)
345b725ae77Skettenis     error ("thread_db_get_info: cannot get thread info: %s",
346b725ae77Skettenis 	   thread_db_err_str (err));
347b725ae77Skettenis 
348b725ae77Skettenis   thread_info->private->ti_valid = 1;
349b725ae77Skettenis   return &thread_info->private->ti;
350b725ae77Skettenis }
351b725ae77Skettenis 
352b725ae77Skettenis /* Convert between user-level thread ids and LWP ids.  */
353b725ae77Skettenis 
354b725ae77Skettenis static ptid_t
thread_from_lwp(ptid_t ptid)355b725ae77Skettenis thread_from_lwp (ptid_t ptid)
356b725ae77Skettenis {
357b725ae77Skettenis   td_thrhandle_t th;
358b725ae77Skettenis   td_err_e err;
359b725ae77Skettenis   struct thread_info *thread_info;
360b725ae77Skettenis   ptid_t thread_ptid;
361b725ae77Skettenis 
362b725ae77Skettenis   if (GET_LWP (ptid) == 0)
363b725ae77Skettenis     ptid = BUILD_LWP (GET_PID (ptid), GET_PID (ptid));
364b725ae77Skettenis 
365b725ae77Skettenis   gdb_assert (is_lwp (ptid));
366b725ae77Skettenis 
367b725ae77Skettenis   err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
368b725ae77Skettenis   if (err != TD_OK)
369b725ae77Skettenis     error ("Cannot find user-level thread for LWP %ld: %s",
370b725ae77Skettenis 	   GET_LWP (ptid), thread_db_err_str (err));
371b725ae77Skettenis 
372b725ae77Skettenis   thread_info = NULL;
373*11efff7fSkettenis 
374*11efff7fSkettenis   /* Fetch the thread info.  If we get back TD_THR_ZOMBIE, then the
375*11efff7fSkettenis      event thread has already died.  If another gdb interface has called
376*11efff7fSkettenis      thread_alive() previously, the thread won't be found on the thread list
377*11efff7fSkettenis      anymore.  In that case, we don't want to process this ptid anymore
378*11efff7fSkettenis      to avoid the possibility of later treating it as a newly
379*11efff7fSkettenis      discovered thread id that we should add to the list.  Thus,
380*11efff7fSkettenis      we return a -1 ptid which is also how the thread list marks a
381*11efff7fSkettenis      dead thread.  */
382*11efff7fSkettenis   if (thread_get_info_callback (&th, &thread_info) == TD_THR_ZOMBIE
383*11efff7fSkettenis       && thread_info == NULL)
384*11efff7fSkettenis     return pid_to_ptid (-1);
385*11efff7fSkettenis 
386b725ae77Skettenis   gdb_assert (thread_info && thread_info->private->ti_valid);
387b725ae77Skettenis 
388b725ae77Skettenis   return BUILD_THREAD (thread_info->private->ti.ti_tid, GET_PID (ptid));
389b725ae77Skettenis }
390b725ae77Skettenis 
391b725ae77Skettenis static ptid_t
lwp_from_thread(ptid_t ptid)392b725ae77Skettenis lwp_from_thread (ptid_t ptid)
393b725ae77Skettenis {
394b725ae77Skettenis   struct thread_info *thread_info;
395b725ae77Skettenis   ptid_t thread_ptid;
396b725ae77Skettenis 
397b725ae77Skettenis   if (!is_thread (ptid))
398b725ae77Skettenis     return ptid;
399b725ae77Skettenis 
400b725ae77Skettenis   thread_info = find_thread_pid (ptid);
401b725ae77Skettenis   thread_db_get_info (thread_info);
402b725ae77Skettenis 
403b725ae77Skettenis   return BUILD_LWP (thread_info->private->ti.ti_lid, GET_PID (ptid));
404b725ae77Skettenis }
405b725ae77Skettenis 
406b725ae77Skettenis 
407b725ae77Skettenis void
thread_db_init(struct target_ops * target)408b725ae77Skettenis thread_db_init (struct target_ops *target)
409b725ae77Skettenis {
410b725ae77Skettenis   target_beneath = target;
411b725ae77Skettenis }
412b725ae77Skettenis 
413b725ae77Skettenis static void *
verbose_dlsym(void * handle,const char * name)414b725ae77Skettenis verbose_dlsym (void *handle, const char *name)
415b725ae77Skettenis {
416b725ae77Skettenis   void *sym = dlsym (handle, name);
417b725ae77Skettenis   if (sym == NULL)
418b725ae77Skettenis     warning ("Symbol \"%s\" not found in libthread_db: %s", name, dlerror ());
419b725ae77Skettenis   return sym;
420b725ae77Skettenis }
421b725ae77Skettenis 
422b725ae77Skettenis static int
thread_db_load(void)423b725ae77Skettenis thread_db_load (void)
424b725ae77Skettenis {
425b725ae77Skettenis   void *handle;
426b725ae77Skettenis   td_err_e err;
427b725ae77Skettenis 
428b725ae77Skettenis   handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
429b725ae77Skettenis   if (handle == NULL)
430b725ae77Skettenis     {
431b725ae77Skettenis       fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
432b725ae77Skettenis 			LIBTHREAD_DB_SO, dlerror ());
433b725ae77Skettenis       fprintf_filtered (gdb_stderr,
434b725ae77Skettenis 			"GDB will not be able to debug pthreads.\n\n");
435b725ae77Skettenis       return 0;
436b725ae77Skettenis     }
437b725ae77Skettenis 
438b725ae77Skettenis   /* Initialize pointers to the dynamic library functions we will use.
439b725ae77Skettenis      Essential functions first.  */
440b725ae77Skettenis 
441b725ae77Skettenis   td_init_p = verbose_dlsym (handle, "td_init");
442b725ae77Skettenis   if (td_init_p == NULL)
443b725ae77Skettenis     return 0;
444b725ae77Skettenis 
445b725ae77Skettenis   td_ta_new_p = verbose_dlsym (handle, "td_ta_new");
446b725ae77Skettenis   if (td_ta_new_p == NULL)
447b725ae77Skettenis     return 0;
448b725ae77Skettenis 
449b725ae77Skettenis   td_ta_map_id2thr_p = verbose_dlsym (handle, "td_ta_map_id2thr");
450b725ae77Skettenis   if (td_ta_map_id2thr_p == NULL)
451b725ae77Skettenis     return 0;
452b725ae77Skettenis 
453b725ae77Skettenis   td_ta_map_lwp2thr_p = verbose_dlsym (handle, "td_ta_map_lwp2thr");
454b725ae77Skettenis   if (td_ta_map_lwp2thr_p == NULL)
455b725ae77Skettenis     return 0;
456b725ae77Skettenis 
457b725ae77Skettenis   td_ta_thr_iter_p = verbose_dlsym (handle, "td_ta_thr_iter");
458b725ae77Skettenis   if (td_ta_thr_iter_p == NULL)
459b725ae77Skettenis     return 0;
460b725ae77Skettenis 
461b725ae77Skettenis   td_thr_validate_p = verbose_dlsym (handle, "td_thr_validate");
462b725ae77Skettenis   if (td_thr_validate_p == NULL)
463b725ae77Skettenis     return 0;
464b725ae77Skettenis 
465b725ae77Skettenis   td_thr_get_info_p = verbose_dlsym (handle, "td_thr_get_info");
466b725ae77Skettenis   if (td_thr_get_info_p == NULL)
467b725ae77Skettenis     return 0;
468b725ae77Skettenis 
469b725ae77Skettenis   td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs");
470b725ae77Skettenis   if (td_thr_getfpregs_p == NULL)
471b725ae77Skettenis     return 0;
472b725ae77Skettenis 
473b725ae77Skettenis   td_thr_getgregs_p = verbose_dlsym (handle, "td_thr_getgregs");
474b725ae77Skettenis   if (td_thr_getgregs_p == NULL)
475b725ae77Skettenis     return 0;
476b725ae77Skettenis 
477b725ae77Skettenis   td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs");
478b725ae77Skettenis   if (td_thr_setfpregs_p == NULL)
479b725ae77Skettenis     return 0;
480b725ae77Skettenis 
481b725ae77Skettenis   td_thr_setgregs_p = verbose_dlsym (handle, "td_thr_setgregs");
482b725ae77Skettenis   if (td_thr_setgregs_p == NULL)
483b725ae77Skettenis     return 0;
484b725ae77Skettenis 
485b725ae77Skettenis   /* Initialize the library.  */
486b725ae77Skettenis   err = td_init_p ();
487b725ae77Skettenis   if (err != TD_OK)
488b725ae77Skettenis     {
489b725ae77Skettenis       warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
490b725ae77Skettenis       return 0;
491b725ae77Skettenis     }
492b725ae77Skettenis 
493b725ae77Skettenis   /* These are not essential.  */
494b725ae77Skettenis   td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
495b725ae77Skettenis   td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
496b725ae77Skettenis   td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
497b725ae77Skettenis   td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
498b725ae77Skettenis   td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
499b725ae77Skettenis 
500b725ae77Skettenis   return 1;
501b725ae77Skettenis }
502b725ae77Skettenis 
503b725ae77Skettenis static td_err_e
enable_thread_event(td_thragent_t * thread_agent,int event,CORE_ADDR * bp)504b725ae77Skettenis enable_thread_event (td_thragent_t *thread_agent, int event, CORE_ADDR *bp)
505b725ae77Skettenis {
506b725ae77Skettenis   td_notify_t notify;
507b725ae77Skettenis   td_err_e err;
508b725ae77Skettenis 
509b725ae77Skettenis   /* Get the breakpoint address for thread EVENT.  */
510b725ae77Skettenis   err = td_ta_event_addr_p (thread_agent, event, &notify);
511b725ae77Skettenis   if (err != TD_OK)
512b725ae77Skettenis     return err;
513b725ae77Skettenis 
514b725ae77Skettenis   /* Set up the breakpoint.  */
515b725ae77Skettenis   (*bp) = gdbarch_convert_from_func_ptr_addr (current_gdbarch,
516b725ae77Skettenis 					      (CORE_ADDR) notify.u.bptaddr,
517b725ae77Skettenis 					      &current_target);
518b725ae77Skettenis   create_thread_event_breakpoint ((*bp));
519b725ae77Skettenis 
520b725ae77Skettenis   return TD_OK;
521b725ae77Skettenis }
522b725ae77Skettenis 
523b725ae77Skettenis static void
enable_thread_event_reporting(void)524b725ae77Skettenis enable_thread_event_reporting (void)
525b725ae77Skettenis {
526b725ae77Skettenis   td_thr_events_t events;
527b725ae77Skettenis   td_notify_t notify;
528b725ae77Skettenis   td_err_e err;
529*11efff7fSkettenis #ifdef HAVE_GNU_LIBC_VERSION_H
530*11efff7fSkettenis   const char *libc_version;
531*11efff7fSkettenis   int libc_major, libc_minor;
532*11efff7fSkettenis #endif
533b725ae77Skettenis 
534b725ae77Skettenis   /* We cannot use the thread event reporting facility if these
535b725ae77Skettenis      functions aren't available.  */
536b725ae77Skettenis   if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
537b725ae77Skettenis       || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
538b725ae77Skettenis     return;
539b725ae77Skettenis 
540b725ae77Skettenis   /* Set the process wide mask saying which events we're interested in.  */
541b725ae77Skettenis   td_event_emptyset (&events);
542b725ae77Skettenis   td_event_addset (&events, TD_CREATE);
543*11efff7fSkettenis 
544*11efff7fSkettenis #ifdef HAVE_GNU_LIBC_VERSION_H
545b725ae77Skettenis   /* FIXME: kettenis/2000-04-23: The event reporting facility is
546b725ae77Skettenis      broken for TD_DEATH events in glibc 2.1.3, so don't enable it for
547b725ae77Skettenis      now.  */
548*11efff7fSkettenis   libc_version = gnu_get_libc_version ();
549*11efff7fSkettenis   if (sscanf (libc_version, "%d.%d", &libc_major, &libc_minor) == 2
550*11efff7fSkettenis       && (libc_major > 2 || (libc_major == 2 && libc_minor > 1)))
551b725ae77Skettenis #endif
552*11efff7fSkettenis     td_event_addset (&events, TD_DEATH);
553b725ae77Skettenis 
554b725ae77Skettenis   err = td_ta_set_event_p (thread_agent, &events);
555b725ae77Skettenis   if (err != TD_OK)
556b725ae77Skettenis     {
557b725ae77Skettenis       warning ("Unable to set global thread event mask: %s",
558b725ae77Skettenis 	       thread_db_err_str (err));
559b725ae77Skettenis       return;
560b725ae77Skettenis     }
561b725ae77Skettenis 
562b725ae77Skettenis   /* Delete previous thread event breakpoints, if any.  */
563b725ae77Skettenis   remove_thread_event_breakpoints ();
564b725ae77Skettenis   td_create_bp_addr = 0;
565b725ae77Skettenis   td_death_bp_addr = 0;
566b725ae77Skettenis 
567b725ae77Skettenis   /* Set up the thread creation event.  */
568b725ae77Skettenis   err = enable_thread_event (thread_agent, TD_CREATE, &td_create_bp_addr);
569b725ae77Skettenis   if (err != TD_OK)
570b725ae77Skettenis     {
571b725ae77Skettenis       warning ("Unable to get location for thread creation breakpoint: %s",
572b725ae77Skettenis 	       thread_db_err_str (err));
573b725ae77Skettenis       return;
574b725ae77Skettenis     }
575b725ae77Skettenis 
576b725ae77Skettenis   /* Set up the thread death event.  */
577b725ae77Skettenis   err = enable_thread_event (thread_agent, TD_DEATH, &td_death_bp_addr);
578b725ae77Skettenis   if (err != TD_OK)
579b725ae77Skettenis     {
580b725ae77Skettenis       warning ("Unable to get location for thread death breakpoint: %s",
581b725ae77Skettenis 	       thread_db_err_str (err));
582b725ae77Skettenis       return;
583b725ae77Skettenis     }
584b725ae77Skettenis }
585b725ae77Skettenis 
586b725ae77Skettenis static void
disable_thread_event_reporting(void)587b725ae77Skettenis disable_thread_event_reporting (void)
588b725ae77Skettenis {
589b725ae77Skettenis   td_thr_events_t events;
590b725ae77Skettenis 
591b725ae77Skettenis   /* Set the process wide mask saying we aren't interested in any
592b725ae77Skettenis      events anymore.  */
593b725ae77Skettenis   td_event_emptyset (&events);
594b725ae77Skettenis   td_ta_set_event_p (thread_agent, &events);
595b725ae77Skettenis 
596b725ae77Skettenis   /* Delete thread event breakpoints, if any.  */
597b725ae77Skettenis   remove_thread_event_breakpoints ();
598b725ae77Skettenis   td_create_bp_addr = 0;
599b725ae77Skettenis   td_death_bp_addr = 0;
600b725ae77Skettenis }
601b725ae77Skettenis 
602b725ae77Skettenis static void
check_thread_signals(void)603b725ae77Skettenis check_thread_signals (void)
604b725ae77Skettenis {
605b725ae77Skettenis #ifdef GET_THREAD_SIGNALS
606b725ae77Skettenis   if (!thread_signals)
607b725ae77Skettenis     {
608b725ae77Skettenis       sigset_t mask;
609b725ae77Skettenis       int i;
610b725ae77Skettenis 
611b725ae77Skettenis       GET_THREAD_SIGNALS (&mask);
612b725ae77Skettenis       sigemptyset (&thread_stop_set);
613b725ae77Skettenis       sigemptyset (&thread_print_set);
614b725ae77Skettenis 
615b725ae77Skettenis       for (i = 1; i < NSIG; i++)
616b725ae77Skettenis 	{
617b725ae77Skettenis 	  if (sigismember (&mask, i))
618b725ae77Skettenis 	    {
619b725ae77Skettenis 	      if (signal_stop_update (target_signal_from_host (i), 0))
620b725ae77Skettenis 		sigaddset (&thread_stop_set, i);
621b725ae77Skettenis 	      if (signal_print_update (target_signal_from_host (i), 0))
622b725ae77Skettenis 		sigaddset (&thread_print_set, i);
623b725ae77Skettenis 	      thread_signals = 1;
624b725ae77Skettenis 	    }
625b725ae77Skettenis 	}
626b725ae77Skettenis     }
627b725ae77Skettenis #endif
628b725ae77Skettenis }
629b725ae77Skettenis 
630b725ae77Skettenis static void
thread_db_new_objfile(struct objfile * objfile)631b725ae77Skettenis thread_db_new_objfile (struct objfile *objfile)
632b725ae77Skettenis {
633b725ae77Skettenis   td_err_e err;
634b725ae77Skettenis 
635b725ae77Skettenis   /* First time through, report that libthread_db was successfuly
636b725ae77Skettenis      loaded.  Can't print this in in thread_db_load as, at that stage,
637b725ae77Skettenis      the interpreter and it's console haven't started.  The real
638b725ae77Skettenis      problem here is that libthread_db is loaded too early - it should
639b725ae77Skettenis      only be loaded when there is a program to debug.  */
640b725ae77Skettenis   {
641b725ae77Skettenis     static int dejavu;
642b725ae77Skettenis     if (!dejavu)
643b725ae77Skettenis       {
644b725ae77Skettenis 	Dl_info info;
645b725ae77Skettenis 	const char *library = NULL;
646b725ae77Skettenis 	/* Try dladdr.  */
647b725ae77Skettenis 	if (dladdr ((*td_ta_new_p), &info) != 0)
648b725ae77Skettenis 	  library = info.dli_fname;
649b725ae77Skettenis 	/* Try dlinfo?  */
650b725ae77Skettenis 	if (library == NULL)
651b725ae77Skettenis 	  /* Paranoid - don't let a NULL path slip through.  */
652b725ae77Skettenis 	  library = LIBTHREAD_DB_SO;
653b725ae77Skettenis 	printf_unfiltered ("Using host libthread_db library \"%s\".\n",
654b725ae77Skettenis 			   library);
655b725ae77Skettenis 	dejavu = 1;
656b725ae77Skettenis       }
657b725ae77Skettenis   }
658b725ae77Skettenis 
659b725ae77Skettenis   /* Don't attempt to use thread_db on targets which can not run
660b725ae77Skettenis      (core files).  */
661b725ae77Skettenis   if (objfile == NULL || !target_has_execution)
662b725ae77Skettenis     {
663b725ae77Skettenis       /* All symbols have been discarded.  If the thread_db target is
664b725ae77Skettenis          active, deactivate it now.  */
665b725ae77Skettenis       if (using_thread_db)
666b725ae77Skettenis 	{
667b725ae77Skettenis 	  gdb_assert (proc_handle.pid == 0);
668b725ae77Skettenis 	  unpush_target (&thread_db_ops);
669b725ae77Skettenis 	  using_thread_db = 0;
670b725ae77Skettenis 	}
671b725ae77Skettenis 
672b725ae77Skettenis       goto quit;
673b725ae77Skettenis     }
674b725ae77Skettenis 
675b725ae77Skettenis   if (using_thread_db)
676b725ae77Skettenis     /* Nothing to do.  The thread library was already detected and the
677b725ae77Skettenis        target vector was already activated.  */
678b725ae77Skettenis     goto quit;
679b725ae77Skettenis 
680b725ae77Skettenis   /* Initialize the structure that identifies the child process.  Note
681b725ae77Skettenis      that at this point there is no guarantee that we actually have a
682b725ae77Skettenis      child process.  */
683b725ae77Skettenis   proc_handle.pid = GET_PID (inferior_ptid);
684b725ae77Skettenis 
685b725ae77Skettenis   /* Now attempt to open a connection to the thread library.  */
686b725ae77Skettenis   err = td_ta_new_p (&proc_handle, &thread_agent);
687b725ae77Skettenis   switch (err)
688b725ae77Skettenis     {
689b725ae77Skettenis     case TD_NOLIBTHREAD:
690b725ae77Skettenis       /* No thread library was detected.  */
691b725ae77Skettenis       break;
692b725ae77Skettenis 
693b725ae77Skettenis     case TD_OK:
694b725ae77Skettenis       printf_unfiltered ("[Thread debugging using libthread_db enabled]\n");
695b725ae77Skettenis 
696b725ae77Skettenis       /* The thread library was detected.  Activate the thread_db target.  */
697b725ae77Skettenis       push_target (&thread_db_ops);
698b725ae77Skettenis       using_thread_db = 1;
699b725ae77Skettenis 
700b725ae77Skettenis       enable_thread_event_reporting ();
701b725ae77Skettenis       thread_db_find_new_threads ();
702b725ae77Skettenis       break;
703b725ae77Skettenis 
704b725ae77Skettenis     default:
705b725ae77Skettenis       warning ("Cannot initialize thread debugging library: %s",
706b725ae77Skettenis 	       thread_db_err_str (err));
707b725ae77Skettenis       break;
708b725ae77Skettenis     }
709b725ae77Skettenis 
710b725ae77Skettenis quit:
711b725ae77Skettenis   if (target_new_objfile_chain)
712b725ae77Skettenis     target_new_objfile_chain (objfile);
713b725ae77Skettenis }
714b725ae77Skettenis 
715*11efff7fSkettenis /* Attach to a new thread.  This function is called when we receive a
716*11efff7fSkettenis    TD_CREATE event or when we iterate over all threads and find one
717*11efff7fSkettenis    that wasn't already in our list.  */
718*11efff7fSkettenis 
719b725ae77Skettenis static void
attach_thread(ptid_t ptid,const td_thrhandle_t * th_p,const td_thrinfo_t * ti_p,int verbose)720b725ae77Skettenis attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
721b725ae77Skettenis 	       const td_thrinfo_t *ti_p, int verbose)
722b725ae77Skettenis {
723b725ae77Skettenis   struct thread_info *tp;
724b725ae77Skettenis   td_err_e err;
725b725ae77Skettenis 
726*11efff7fSkettenis   /* If we're being called after a TD_CREATE event, we may already
727*11efff7fSkettenis      know about this thread.  There are two ways this can happen.  We
728*11efff7fSkettenis      may have iterated over all threads between the thread creation
729*11efff7fSkettenis      and the TD_CREATE event, for instance when the user has issued
730*11efff7fSkettenis      the `info threads' command before the SIGTRAP for hitting the
731*11efff7fSkettenis      thread creation breakpoint was reported.  Alternatively, the
732*11efff7fSkettenis      thread may have exited and a new one been created with the same
733*11efff7fSkettenis      thread ID.  In the first case we don't need to do anything; in
734*11efff7fSkettenis      the second case we should discard information about the dead
735*11efff7fSkettenis      thread and attach to the new one.  */
736*11efff7fSkettenis   if (in_thread_list (ptid))
737*11efff7fSkettenis     {
738*11efff7fSkettenis       tp = find_thread_pid (ptid);
739*11efff7fSkettenis       gdb_assert (tp != NULL);
740*11efff7fSkettenis 
741*11efff7fSkettenis       if (!tp->private->dying)
742*11efff7fSkettenis         return;
743*11efff7fSkettenis 
744*11efff7fSkettenis       delete_thread (ptid);
745*11efff7fSkettenis     }
746*11efff7fSkettenis 
747b725ae77Skettenis   check_thread_signals ();
748b725ae77Skettenis 
749b725ae77Skettenis   /* Add the thread to GDB's thread list.  */
750b725ae77Skettenis   tp = add_thread (ptid);
751b725ae77Skettenis   tp->private = xmalloc (sizeof (struct private_thread_info));
752b725ae77Skettenis   memset (tp->private, 0, sizeof (struct private_thread_info));
753b725ae77Skettenis 
754b725ae77Skettenis   if (verbose)
755b725ae77Skettenis     printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid));
756b725ae77Skettenis 
757b725ae77Skettenis   if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE)
758b725ae77Skettenis     return;			/* A zombie thread -- do not attach.  */
759b725ae77Skettenis 
760b725ae77Skettenis   /* Under GNU/Linux, we have to attach to each and every thread.  */
761b725ae77Skettenis #ifdef ATTACH_LWP
762b725ae77Skettenis   ATTACH_LWP (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)), 0);
763b725ae77Skettenis #endif
764b725ae77Skettenis 
765b725ae77Skettenis   /* Enable thread event reporting for this thread.  */
766b725ae77Skettenis   err = td_thr_event_enable_p (th_p, 1);
767b725ae77Skettenis   if (err != TD_OK)
768b725ae77Skettenis     error ("Cannot enable thread event reporting for %s: %s",
769b725ae77Skettenis 	   target_pid_to_str (ptid), thread_db_err_str (err));
770b725ae77Skettenis }
771b725ae77Skettenis 
772b725ae77Skettenis static void
thread_db_attach(char * args,int from_tty)773b725ae77Skettenis thread_db_attach (char *args, int from_tty)
774b725ae77Skettenis {
775b725ae77Skettenis   target_beneath->to_attach (args, from_tty);
776b725ae77Skettenis 
777b725ae77Skettenis   /* Destroy thread info; it's no longer valid.  */
778b725ae77Skettenis   init_thread_list ();
779b725ae77Skettenis 
780b725ae77Skettenis   /* The child process is now the actual multi-threaded
781b725ae77Skettenis      program.  Snatch its process ID...  */
782b725ae77Skettenis   proc_handle.pid = GET_PID (inferior_ptid);
783b725ae77Skettenis 
784b725ae77Skettenis   /* ...and perform the remaining initialization steps.  */
785b725ae77Skettenis   enable_thread_event_reporting ();
786b725ae77Skettenis   thread_db_find_new_threads ();
787b725ae77Skettenis }
788b725ae77Skettenis 
789b725ae77Skettenis static void
detach_thread(ptid_t ptid,int verbose)790b725ae77Skettenis detach_thread (ptid_t ptid, int verbose)
791b725ae77Skettenis {
792*11efff7fSkettenis   struct thread_info *thread_info;
793*11efff7fSkettenis 
794b725ae77Skettenis   if (verbose)
795b725ae77Skettenis     printf_unfiltered ("[%s exited]\n", target_pid_to_str (ptid));
796*11efff7fSkettenis 
797*11efff7fSkettenis   /* Don't delete the thread now, because it still reports as active
798*11efff7fSkettenis      until it has executed a few instructions after the event
799*11efff7fSkettenis      breakpoint - if we deleted it now, "info threads" would cause us
800*11efff7fSkettenis      to re-attach to it.  Just mark it as having had a TD_DEATH
801*11efff7fSkettenis      event.  This means that we won't delete it from our thread list
802*11efff7fSkettenis      until we notice that it's dead (via prune_threads), or until
803*11efff7fSkettenis      something re-uses its thread ID.  */
804*11efff7fSkettenis   thread_info = find_thread_pid (ptid);
805*11efff7fSkettenis   gdb_assert (thread_info != NULL);
806*11efff7fSkettenis   thread_info->private->dying = 1;
807b725ae77Skettenis }
808b725ae77Skettenis 
809b725ae77Skettenis static void
thread_db_detach(char * args,int from_tty)810b725ae77Skettenis thread_db_detach (char *args, int from_tty)
811b725ae77Skettenis {
812b725ae77Skettenis   disable_thread_event_reporting ();
813b725ae77Skettenis 
814b725ae77Skettenis   /* There's no need to save & restore inferior_ptid here, since the
815b725ae77Skettenis      inferior is supposed to be survive this function call.  */
816b725ae77Skettenis   inferior_ptid = lwp_from_thread (inferior_ptid);
817b725ae77Skettenis 
818b725ae77Skettenis   /* Forget about the child's process ID.  We shouldn't need it
819b725ae77Skettenis      anymore.  */
820b725ae77Skettenis   proc_handle.pid = 0;
821b725ae77Skettenis 
822b725ae77Skettenis   target_beneath->to_detach (args, from_tty);
823b725ae77Skettenis }
824b725ae77Skettenis 
825b725ae77Skettenis static int
clear_lwpid_callback(struct thread_info * thread,void * dummy)826b725ae77Skettenis clear_lwpid_callback (struct thread_info *thread, void *dummy)
827b725ae77Skettenis {
828b725ae77Skettenis   /* If we know that our thread implementation is 1-to-1, we could save
829b725ae77Skettenis      a certain amount of information; it's not clear how much, so we
830b725ae77Skettenis      are always conservative.  */
831b725ae77Skettenis 
832b725ae77Skettenis   thread->private->th_valid = 0;
833b725ae77Skettenis   thread->private->ti_valid = 0;
834b725ae77Skettenis 
835b725ae77Skettenis   return 0;
836b725ae77Skettenis }
837b725ae77Skettenis 
838b725ae77Skettenis static void
thread_db_resume(ptid_t ptid,int step,enum target_signal signo)839b725ae77Skettenis thread_db_resume (ptid_t ptid, int step, enum target_signal signo)
840b725ae77Skettenis {
841b725ae77Skettenis   struct cleanup *old_chain = save_inferior_ptid ();
842b725ae77Skettenis 
843b725ae77Skettenis   if (GET_PID (ptid) == -1)
844b725ae77Skettenis     inferior_ptid = lwp_from_thread (inferior_ptid);
845b725ae77Skettenis   else if (is_thread (ptid))
846b725ae77Skettenis     ptid = lwp_from_thread (ptid);
847b725ae77Skettenis 
848b725ae77Skettenis   /* Clear cached data which may not be valid after the resume.  */
849b725ae77Skettenis   iterate_over_threads (clear_lwpid_callback, NULL);
850b725ae77Skettenis 
851b725ae77Skettenis   target_beneath->to_resume (ptid, step, signo);
852b725ae77Skettenis 
853b725ae77Skettenis   do_cleanups (old_chain);
854b725ae77Skettenis }
855b725ae77Skettenis 
856b725ae77Skettenis /* Check if PID is currently stopped at the location of a thread event
857b725ae77Skettenis    breakpoint location.  If it is, read the event message and act upon
858b725ae77Skettenis    the event.  */
859b725ae77Skettenis 
860b725ae77Skettenis static void
check_event(ptid_t ptid)861b725ae77Skettenis check_event (ptid_t ptid)
862b725ae77Skettenis {
863b725ae77Skettenis   td_event_msg_t msg;
864b725ae77Skettenis   td_thrinfo_t ti;
865b725ae77Skettenis   td_err_e err;
866b725ae77Skettenis   CORE_ADDR stop_pc;
867b725ae77Skettenis   int loop = 0;
868b725ae77Skettenis 
869b725ae77Skettenis   /* Bail out early if we're not at a thread event breakpoint.  */
870b725ae77Skettenis   stop_pc = read_pc_pid (ptid) - DECR_PC_AFTER_BREAK;
871b725ae77Skettenis   if (stop_pc != td_create_bp_addr && stop_pc != td_death_bp_addr)
872b725ae77Skettenis     return;
873b725ae77Skettenis 
874b725ae77Skettenis   /* If we are at a create breakpoint, we do not know what new lwp
875b725ae77Skettenis      was created and cannot specifically locate the event message for it.
876b725ae77Skettenis      We have to call td_ta_event_getmsg() to get
877b725ae77Skettenis      the latest message.  Since we have no way of correlating whether
878b725ae77Skettenis      the event message we get back corresponds to our breakpoint, we must
879b725ae77Skettenis      loop and read all event messages, processing them appropriately.
880b725ae77Skettenis      This guarantees we will process the correct message before continuing
881b725ae77Skettenis      from the breakpoint.
882b725ae77Skettenis 
883b725ae77Skettenis      Currently, death events are not enabled.  If they are enabled,
884b725ae77Skettenis      the death event can use the td_thr_event_getmsg() interface to
885b725ae77Skettenis      get the message specifically for that lwp and avoid looping
886b725ae77Skettenis      below.  */
887b725ae77Skettenis 
888b725ae77Skettenis   loop = 1;
889b725ae77Skettenis 
890b725ae77Skettenis   do
891b725ae77Skettenis     {
892b725ae77Skettenis       err = td_ta_event_getmsg_p (thread_agent, &msg);
893b725ae77Skettenis       if (err != TD_OK)
894b725ae77Skettenis 	{
895b725ae77Skettenis 	  if (err == TD_NOMSG)
896b725ae77Skettenis 	    return;
897b725ae77Skettenis 
898b725ae77Skettenis 	  error ("Cannot get thread event message: %s",
899b725ae77Skettenis 		 thread_db_err_str (err));
900b725ae77Skettenis 	}
901b725ae77Skettenis 
902b725ae77Skettenis       err = td_thr_get_info_p (msg.th_p, &ti);
903b725ae77Skettenis       if (err != TD_OK)
904b725ae77Skettenis 	error ("Cannot get thread info: %s", thread_db_err_str (err));
905b725ae77Skettenis 
906b725ae77Skettenis       ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid));
907b725ae77Skettenis 
908b725ae77Skettenis       switch (msg.event)
909b725ae77Skettenis 	{
910b725ae77Skettenis 	case TD_CREATE:
911*11efff7fSkettenis 	  /* Call attach_thread whether or not we already know about a
912*11efff7fSkettenis 	     thread with this thread ID.  */
913b725ae77Skettenis 	  attach_thread (ptid, msg.th_p, &ti, 1);
914b725ae77Skettenis 
915b725ae77Skettenis 	  break;
916b725ae77Skettenis 
917b725ae77Skettenis 	case TD_DEATH:
918b725ae77Skettenis 
919b725ae77Skettenis 	  if (!in_thread_list (ptid))
920b725ae77Skettenis 	    error ("Spurious thread death event.");
921b725ae77Skettenis 
922b725ae77Skettenis 	  detach_thread (ptid, 1);
923b725ae77Skettenis 
924b725ae77Skettenis 	  break;
925b725ae77Skettenis 
926b725ae77Skettenis 	default:
927b725ae77Skettenis 	  error ("Spurious thread event.");
928b725ae77Skettenis 	}
929b725ae77Skettenis     }
930b725ae77Skettenis   while (loop);
931b725ae77Skettenis }
932b725ae77Skettenis 
933b725ae77Skettenis static ptid_t
thread_db_wait(ptid_t ptid,struct target_waitstatus * ourstatus)934b725ae77Skettenis thread_db_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
935b725ae77Skettenis {
936b725ae77Skettenis   extern ptid_t trap_ptid;
937b725ae77Skettenis 
938b725ae77Skettenis   if (GET_PID (ptid) != -1 && is_thread (ptid))
939b725ae77Skettenis     ptid = lwp_from_thread (ptid);
940b725ae77Skettenis 
941b725ae77Skettenis   ptid = target_beneath->to_wait (ptid, ourstatus);
942b725ae77Skettenis 
943b725ae77Skettenis   if (proc_handle.pid == 0)
944b725ae77Skettenis     /* The current child process isn't the actual multi-threaded
945b725ae77Skettenis        program yet, so don't try to do any special thread-specific
946b725ae77Skettenis        post-processing and bail out early.  */
947b725ae77Skettenis     return ptid;
948b725ae77Skettenis 
949b725ae77Skettenis   if (ourstatus->kind == TARGET_WAITKIND_EXITED)
950b725ae77Skettenis     return pid_to_ptid (-1);
951b725ae77Skettenis 
952b725ae77Skettenis   if (ourstatus->kind == TARGET_WAITKIND_STOPPED
953b725ae77Skettenis       && ourstatus->value.sig == TARGET_SIGNAL_TRAP)
954b725ae77Skettenis     /* Check for a thread event.  */
955b725ae77Skettenis     check_event (ptid);
956b725ae77Skettenis 
957b725ae77Skettenis   if (!ptid_equal (trap_ptid, null_ptid))
958b725ae77Skettenis     trap_ptid = thread_from_lwp (trap_ptid);
959b725ae77Skettenis 
960*11efff7fSkettenis   /* Change the ptid back into the higher level PID + TID format.
961*11efff7fSkettenis      If the thread is dead and no longer on the thread list, we will
962*11efff7fSkettenis      get back a dead ptid.  This can occur if the thread death event
963*11efff7fSkettenis      gets postponed by other simultaneous events.  In such a case,
964*11efff7fSkettenis      we want to just ignore the event and continue on.  */
965*11efff7fSkettenis   ptid = thread_from_lwp (ptid);
966*11efff7fSkettenis   if (GET_PID (ptid) == -1)
967*11efff7fSkettenis     ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
968*11efff7fSkettenis 
969*11efff7fSkettenis   return ptid;
970b725ae77Skettenis }
971b725ae77Skettenis 
972b725ae77Skettenis static int
thread_db_xfer_memory(CORE_ADDR memaddr,char * myaddr,int len,int write,struct mem_attrib * attrib,struct target_ops * target)973b725ae77Skettenis thread_db_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
974b725ae77Skettenis 		       struct mem_attrib *attrib, struct target_ops *target)
975b725ae77Skettenis {
976b725ae77Skettenis   struct cleanup *old_chain = save_inferior_ptid ();
977b725ae77Skettenis   int xfer;
978b725ae77Skettenis 
979b725ae77Skettenis   if (is_thread (inferior_ptid))
980b725ae77Skettenis     {
981b725ae77Skettenis       /* FIXME: This seems to be necessary to make sure breakpoints
982b725ae77Skettenis          are removed.  */
983b725ae77Skettenis       if (!target_thread_alive (inferior_ptid))
984b725ae77Skettenis 	inferior_ptid = pid_to_ptid (GET_PID (inferior_ptid));
985b725ae77Skettenis       else
986b725ae77Skettenis 	inferior_ptid = lwp_from_thread (inferior_ptid);
987b725ae77Skettenis     }
988b725ae77Skettenis 
989b725ae77Skettenis   xfer =
990*11efff7fSkettenis     target_beneath->deprecated_xfer_memory (memaddr, myaddr, len, write,
991*11efff7fSkettenis 					    attrib, target);
992b725ae77Skettenis 
993b725ae77Skettenis   do_cleanups (old_chain);
994b725ae77Skettenis   return xfer;
995b725ae77Skettenis }
996b725ae77Skettenis 
997b725ae77Skettenis static void
thread_db_fetch_registers(int regno)998b725ae77Skettenis thread_db_fetch_registers (int regno)
999b725ae77Skettenis {
1000b725ae77Skettenis   struct thread_info *thread_info;
1001b725ae77Skettenis   prgregset_t gregset;
1002b725ae77Skettenis   gdb_prfpregset_t fpregset;
1003b725ae77Skettenis   td_err_e err;
1004b725ae77Skettenis 
1005b725ae77Skettenis   if (!is_thread (inferior_ptid))
1006b725ae77Skettenis     {
1007b725ae77Skettenis       /* Pass the request to the target beneath us.  */
1008b725ae77Skettenis       target_beneath->to_fetch_registers (regno);
1009b725ae77Skettenis       return;
1010b725ae77Skettenis     }
1011b725ae77Skettenis 
1012b725ae77Skettenis   thread_info = find_thread_pid (inferior_ptid);
1013b725ae77Skettenis   thread_db_map_id2thr (thread_info, 1);
1014b725ae77Skettenis 
1015b725ae77Skettenis   err = td_thr_getgregs_p (&thread_info->private->th, gregset);
1016b725ae77Skettenis   if (err != TD_OK)
1017b725ae77Skettenis     error ("Cannot fetch general-purpose registers for thread %ld: %s",
1018b725ae77Skettenis 	   (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
1019b725ae77Skettenis 
1020b725ae77Skettenis   err = td_thr_getfpregs_p (&thread_info->private->th, &fpregset);
1021b725ae77Skettenis   if (err != TD_OK)
1022b725ae77Skettenis     error ("Cannot get floating-point registers for thread %ld: %s",
1023b725ae77Skettenis 	   (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
1024b725ae77Skettenis 
1025b725ae77Skettenis   /* Note that we must call supply_gregset after calling the thread_db
1026b725ae77Skettenis      routines because the thread_db routines call ps_lgetgregs and
1027b725ae77Skettenis      friends which clobber GDB's register cache.  */
1028b725ae77Skettenis   supply_gregset ((gdb_gregset_t *) gregset);
1029b725ae77Skettenis   supply_fpregset (&fpregset);
1030b725ae77Skettenis }
1031b725ae77Skettenis 
1032b725ae77Skettenis static void
thread_db_store_registers(int regno)1033b725ae77Skettenis thread_db_store_registers (int regno)
1034b725ae77Skettenis {
1035b725ae77Skettenis   prgregset_t gregset;
1036b725ae77Skettenis   gdb_prfpregset_t fpregset;
1037b725ae77Skettenis   td_err_e err;
1038b725ae77Skettenis   struct thread_info *thread_info;
1039b725ae77Skettenis 
1040b725ae77Skettenis   if (!is_thread (inferior_ptid))
1041b725ae77Skettenis     {
1042b725ae77Skettenis       /* Pass the request to the target beneath us.  */
1043b725ae77Skettenis       target_beneath->to_store_registers (regno);
1044b725ae77Skettenis       return;
1045b725ae77Skettenis     }
1046b725ae77Skettenis 
1047b725ae77Skettenis   thread_info = find_thread_pid (inferior_ptid);
1048b725ae77Skettenis   thread_db_map_id2thr (thread_info, 1);
1049b725ae77Skettenis 
1050b725ae77Skettenis   if (regno != -1)
1051b725ae77Skettenis     {
1052b725ae77Skettenis       char raw[MAX_REGISTER_SIZE];
1053b725ae77Skettenis 
1054b725ae77Skettenis       deprecated_read_register_gen (regno, raw);
1055b725ae77Skettenis       thread_db_fetch_registers (-1);
1056*11efff7fSkettenis       regcache_raw_supply (current_regcache, regno, raw);
1057b725ae77Skettenis     }
1058b725ae77Skettenis 
1059b725ae77Skettenis   fill_gregset ((gdb_gregset_t *) gregset, -1);
1060b725ae77Skettenis   fill_fpregset (&fpregset, -1);
1061b725ae77Skettenis 
1062b725ae77Skettenis   err = td_thr_setgregs_p (&thread_info->private->th, gregset);
1063b725ae77Skettenis   if (err != TD_OK)
1064b725ae77Skettenis     error ("Cannot store general-purpose registers for thread %ld: %s",
1065b725ae77Skettenis 	   (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
1066b725ae77Skettenis   err = td_thr_setfpregs_p (&thread_info->private->th, &fpregset);
1067b725ae77Skettenis   if (err != TD_OK)
1068b725ae77Skettenis     error ("Cannot store floating-point registers  for thread %ld: %s",
1069b725ae77Skettenis 	   (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
1070b725ae77Skettenis }
1071b725ae77Skettenis 
1072b725ae77Skettenis static void
thread_db_kill(void)1073b725ae77Skettenis thread_db_kill (void)
1074b725ae77Skettenis {
1075b725ae77Skettenis   /* There's no need to save & restore inferior_ptid here, since the
1076b725ae77Skettenis      inferior isn't supposed to survive this function call.  */
1077b725ae77Skettenis   inferior_ptid = lwp_from_thread (inferior_ptid);
1078b725ae77Skettenis   target_beneath->to_kill ();
1079b725ae77Skettenis }
1080b725ae77Skettenis 
1081b725ae77Skettenis static void
thread_db_create_inferior(char * exec_file,char * allargs,char ** env,int from_tty)1082*11efff7fSkettenis thread_db_create_inferior (char *exec_file, char *allargs, char **env,
1083*11efff7fSkettenis 			   int from_tty)
1084b725ae77Skettenis {
1085b725ae77Skettenis   unpush_target (&thread_db_ops);
1086b725ae77Skettenis   using_thread_db = 0;
1087*11efff7fSkettenis   target_beneath->to_create_inferior (exec_file, allargs, env, from_tty);
1088b725ae77Skettenis }
1089b725ae77Skettenis 
1090b725ae77Skettenis static void
thread_db_post_startup_inferior(ptid_t ptid)1091b725ae77Skettenis thread_db_post_startup_inferior (ptid_t ptid)
1092b725ae77Skettenis {
1093b725ae77Skettenis   if (proc_handle.pid == 0)
1094b725ae77Skettenis     {
1095b725ae77Skettenis       /* The child process is now the actual multi-threaded
1096b725ae77Skettenis          program.  Snatch its process ID...  */
1097b725ae77Skettenis       proc_handle.pid = GET_PID (ptid);
1098b725ae77Skettenis 
1099b725ae77Skettenis       /* ...and perform the remaining initialization steps.  */
1100b725ae77Skettenis       enable_thread_event_reporting ();
1101b725ae77Skettenis       thread_db_find_new_threads ();
1102b725ae77Skettenis     }
1103b725ae77Skettenis }
1104b725ae77Skettenis 
1105b725ae77Skettenis static void
thread_db_mourn_inferior(void)1106b725ae77Skettenis thread_db_mourn_inferior (void)
1107b725ae77Skettenis {
1108b725ae77Skettenis   remove_thread_event_breakpoints ();
1109b725ae77Skettenis 
1110b725ae77Skettenis   /* Forget about the child's process ID.  We shouldn't need it
1111b725ae77Skettenis      anymore.  */
1112b725ae77Skettenis   proc_handle.pid = 0;
1113b725ae77Skettenis 
1114b725ae77Skettenis   target_beneath->to_mourn_inferior ();
1115b725ae77Skettenis 
1116*11efff7fSkettenis   /* Detach thread_db target ops.  */
1117b725ae77Skettenis   unpush_target (&thread_db_ops);
1118b725ae77Skettenis   using_thread_db = 0;
1119b725ae77Skettenis }
1120b725ae77Skettenis 
1121b725ae77Skettenis static int
thread_db_thread_alive(ptid_t ptid)1122b725ae77Skettenis thread_db_thread_alive (ptid_t ptid)
1123b725ae77Skettenis {
1124b725ae77Skettenis   td_thrhandle_t th;
1125b725ae77Skettenis   td_err_e err;
1126b725ae77Skettenis 
1127b725ae77Skettenis   if (is_thread (ptid))
1128b725ae77Skettenis     {
1129b725ae77Skettenis       struct thread_info *thread_info;
1130b725ae77Skettenis       thread_info = find_thread_pid (ptid);
1131b725ae77Skettenis 
1132b725ae77Skettenis       thread_db_map_id2thr (thread_info, 0);
1133b725ae77Skettenis       if (!thread_info->private->th_valid)
1134b725ae77Skettenis 	return 0;
1135b725ae77Skettenis 
1136b725ae77Skettenis       err = td_thr_validate_p (&thread_info->private->th);
1137b725ae77Skettenis       if (err != TD_OK)
1138b725ae77Skettenis 	return 0;
1139b725ae77Skettenis 
1140b725ae77Skettenis       if (!thread_info->private->ti_valid)
1141b725ae77Skettenis 	{
1142b725ae77Skettenis 	  err =
1143b725ae77Skettenis 	    td_thr_get_info_p (&thread_info->private->th,
1144b725ae77Skettenis 			       &thread_info->private->ti);
1145b725ae77Skettenis 	  if (err != TD_OK)
1146b725ae77Skettenis 	    return 0;
1147b725ae77Skettenis 	  thread_info->private->ti_valid = 1;
1148b725ae77Skettenis 	}
1149b725ae77Skettenis 
1150b725ae77Skettenis       if (thread_info->private->ti.ti_state == TD_THR_UNKNOWN
1151b725ae77Skettenis 	  || thread_info->private->ti.ti_state == TD_THR_ZOMBIE)
1152b725ae77Skettenis 	return 0;		/* A zombie thread.  */
1153b725ae77Skettenis 
1154b725ae77Skettenis       return 1;
1155b725ae77Skettenis     }
1156b725ae77Skettenis 
1157b725ae77Skettenis   if (target_beneath->to_thread_alive)
1158b725ae77Skettenis     return target_beneath->to_thread_alive (ptid);
1159b725ae77Skettenis 
1160b725ae77Skettenis   return 0;
1161b725ae77Skettenis }
1162b725ae77Skettenis 
1163b725ae77Skettenis static int
find_new_threads_callback(const td_thrhandle_t * th_p,void * data)1164b725ae77Skettenis find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
1165b725ae77Skettenis {
1166b725ae77Skettenis   td_thrinfo_t ti;
1167b725ae77Skettenis   td_err_e err;
1168b725ae77Skettenis   ptid_t ptid;
1169b725ae77Skettenis 
1170b725ae77Skettenis   err = td_thr_get_info_p (th_p, &ti);
1171b725ae77Skettenis   if (err != TD_OK)
1172b725ae77Skettenis     error ("find_new_threads_callback: cannot get thread info: %s",
1173b725ae77Skettenis 	   thread_db_err_str (err));
1174b725ae77Skettenis 
1175b725ae77Skettenis   if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
1176b725ae77Skettenis     return 0;			/* A zombie -- ignore.  */
1177b725ae77Skettenis 
1178b725ae77Skettenis   ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid));
1179b725ae77Skettenis 
1180b725ae77Skettenis   if (!in_thread_list (ptid))
1181b725ae77Skettenis     attach_thread (ptid, th_p, &ti, 1);
1182b725ae77Skettenis 
1183b725ae77Skettenis   return 0;
1184b725ae77Skettenis }
1185b725ae77Skettenis 
1186b725ae77Skettenis static void
thread_db_find_new_threads(void)1187b725ae77Skettenis thread_db_find_new_threads (void)
1188b725ae77Skettenis {
1189b725ae77Skettenis   td_err_e err;
1190b725ae77Skettenis 
1191b725ae77Skettenis   /* Iterate over all user-space threads to discover new threads.  */
1192b725ae77Skettenis   err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
1193b725ae77Skettenis 			  TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1194b725ae77Skettenis 			  TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1195b725ae77Skettenis   if (err != TD_OK)
1196b725ae77Skettenis     error ("Cannot find new threads: %s", thread_db_err_str (err));
1197b725ae77Skettenis }
1198b725ae77Skettenis 
1199b725ae77Skettenis static char *
thread_db_pid_to_str(ptid_t ptid)1200b725ae77Skettenis thread_db_pid_to_str (ptid_t ptid)
1201b725ae77Skettenis {
1202b725ae77Skettenis   if (is_thread (ptid))
1203b725ae77Skettenis     {
1204b725ae77Skettenis       static char buf[64];
1205b725ae77Skettenis       td_thrinfo_t *ti_p;
1206b725ae77Skettenis       td_err_e err;
1207b725ae77Skettenis       struct thread_info *thread_info;
1208b725ae77Skettenis 
1209b725ae77Skettenis       thread_info = find_thread_pid (ptid);
1210b725ae77Skettenis       thread_db_map_id2thr (thread_info, 0);
1211b725ae77Skettenis       if (!thread_info->private->th_valid)
1212b725ae77Skettenis 	{
1213b725ae77Skettenis 	  snprintf (buf, sizeof (buf), "Thread %ld (Missing)",
1214b725ae77Skettenis 		    GET_THREAD (ptid));
1215b725ae77Skettenis 	  return buf;
1216b725ae77Skettenis 	}
1217b725ae77Skettenis 
1218b725ae77Skettenis       ti_p = thread_db_get_info (thread_info);
1219b725ae77Skettenis 
1220b725ae77Skettenis       if (ti_p->ti_state == TD_THR_ACTIVE && ti_p->ti_lid != 0)
1221b725ae77Skettenis 	{
1222b725ae77Skettenis 	  snprintf (buf, sizeof (buf), "Thread %ld (LWP %d)",
1223b725ae77Skettenis 		    (long) ti_p->ti_tid, ti_p->ti_lid);
1224b725ae77Skettenis 	}
1225b725ae77Skettenis       else
1226b725ae77Skettenis 	{
1227b725ae77Skettenis 	  snprintf (buf, sizeof (buf), "Thread %ld (%s)",
1228b725ae77Skettenis 		    (long) ti_p->ti_tid,
1229b725ae77Skettenis 		    thread_db_state_str (ti_p->ti_state));
1230b725ae77Skettenis 	}
1231b725ae77Skettenis 
1232b725ae77Skettenis       return buf;
1233b725ae77Skettenis     }
1234b725ae77Skettenis 
1235b725ae77Skettenis   if (target_beneath->to_pid_to_str (ptid))
1236b725ae77Skettenis     return target_beneath->to_pid_to_str (ptid);
1237b725ae77Skettenis 
1238b725ae77Skettenis   return normal_pid_to_str (ptid);
1239b725ae77Skettenis }
1240b725ae77Skettenis 
1241b725ae77Skettenis /* Get the address of the thread local variable in OBJFILE which is
1242b725ae77Skettenis    stored at OFFSET within the thread local storage for thread PTID.  */
1243b725ae77Skettenis 
1244b725ae77Skettenis static CORE_ADDR
thread_db_get_thread_local_address(ptid_t ptid,struct objfile * objfile,CORE_ADDR offset)1245b725ae77Skettenis thread_db_get_thread_local_address (ptid_t ptid, struct objfile *objfile,
1246b725ae77Skettenis 				    CORE_ADDR offset)
1247b725ae77Skettenis {
1248b725ae77Skettenis   if (is_thread (ptid))
1249b725ae77Skettenis     {
1250b725ae77Skettenis       int objfile_is_library = (objfile->flags & OBJF_SHARED);
1251b725ae77Skettenis       td_err_e err;
1252b725ae77Skettenis       void *address;
1253b725ae77Skettenis       CORE_ADDR lm;
1254b725ae77Skettenis       struct thread_info *thread_info;
1255b725ae77Skettenis 
1256b725ae77Skettenis       /* glibc doesn't provide the needed interface.  */
1257b725ae77Skettenis       if (!td_thr_tls_get_addr_p)
1258b725ae77Skettenis 	error ("Cannot find thread-local variables in this thread library.");
1259b725ae77Skettenis 
1260b725ae77Skettenis       /* Get the address of the link map for this objfile.  */
1261b725ae77Skettenis       lm = svr4_fetch_objfile_link_map (objfile);
1262b725ae77Skettenis 
1263b725ae77Skettenis       /* Whoops, we couldn't find one. Bail out.  */
1264b725ae77Skettenis       if (!lm)
1265b725ae77Skettenis 	{
1266b725ae77Skettenis 	  if (objfile_is_library)
1267b725ae77Skettenis 	    error ("Cannot find shared library `%s' link_map in dynamic"
1268b725ae77Skettenis 		   " linker's module list", objfile->name);
1269b725ae77Skettenis 	  else
1270b725ae77Skettenis 	    error ("Cannot find executable file `%s' link_map in dynamic"
1271b725ae77Skettenis 		   " linker's module list", objfile->name);
1272b725ae77Skettenis 	}
1273b725ae77Skettenis 
1274b725ae77Skettenis       /* Get info about the thread.  */
1275b725ae77Skettenis       thread_info = find_thread_pid (ptid);
1276b725ae77Skettenis       thread_db_map_id2thr (thread_info, 1);
1277b725ae77Skettenis 
1278b725ae77Skettenis       /* Finally, get the address of the variable.  */
1279b725ae77Skettenis       err = td_thr_tls_get_addr_p (&thread_info->private->th, (void *) lm,
1280b725ae77Skettenis 				   offset, &address);
1281b725ae77Skettenis 
1282b725ae77Skettenis #ifdef THREAD_DB_HAS_TD_NOTALLOC
1283b725ae77Skettenis       /* The memory hasn't been allocated, yet.  */
1284b725ae77Skettenis       if (err == TD_NOTALLOC)
1285b725ae77Skettenis 	{
1286b725ae77Skettenis 	  /* Now, if libthread_db provided the initialization image's
1287b725ae77Skettenis 	     address, we *could* try to build a non-lvalue value from
1288b725ae77Skettenis 	     the initialization image.  */
1289b725ae77Skettenis 	  if (objfile_is_library)
1290b725ae77Skettenis 	    error ("The inferior has not yet allocated storage for"
1291b725ae77Skettenis 		   " thread-local variables in\n"
1292b725ae77Skettenis 		   "the shared library `%s'\n"
1293b725ae77Skettenis 		   "for the thread %ld",
1294b725ae77Skettenis 		   objfile->name, (long) GET_THREAD (ptid));
1295b725ae77Skettenis 	  else
1296b725ae77Skettenis 	    error ("The inferior has not yet allocated storage for"
1297b725ae77Skettenis 		   " thread-local variables in\n"
1298b725ae77Skettenis 		   "the executable `%s'\n"
1299b725ae77Skettenis 		   "for the thread %ld",
1300b725ae77Skettenis 		   objfile->name, (long) GET_THREAD (ptid));
1301b725ae77Skettenis 	}
1302b725ae77Skettenis #endif
1303b725ae77Skettenis 
1304b725ae77Skettenis       /* Something else went wrong.  */
1305b725ae77Skettenis       if (err != TD_OK)
1306b725ae77Skettenis 	{
1307b725ae77Skettenis 	  if (objfile_is_library)
1308b725ae77Skettenis 	    error ("Cannot find thread-local storage for thread %ld, "
1309b725ae77Skettenis 		   "shared library %s:\n%s",
1310b725ae77Skettenis 		   (long) GET_THREAD (ptid),
1311b725ae77Skettenis 		   objfile->name, thread_db_err_str (err));
1312b725ae77Skettenis 	  else
1313b725ae77Skettenis 	    error ("Cannot find thread-local storage for thread %ld, "
1314b725ae77Skettenis 		   "executable file %s:\n%s",
1315b725ae77Skettenis 		   (long) GET_THREAD (ptid),
1316b725ae77Skettenis 		   objfile->name, thread_db_err_str (err));
1317b725ae77Skettenis 	}
1318b725ae77Skettenis 
1319b725ae77Skettenis       /* Cast assuming host == target.  Joy.  */
1320b725ae77Skettenis       return (CORE_ADDR) address;
1321b725ae77Skettenis     }
1322b725ae77Skettenis 
1323b725ae77Skettenis   if (target_beneath->to_get_thread_local_address)
1324b725ae77Skettenis     return target_beneath->to_get_thread_local_address (ptid, objfile,
1325b725ae77Skettenis 							offset);
1326b725ae77Skettenis 
1327b725ae77Skettenis   error ("Cannot find thread-local values on this target.");
1328b725ae77Skettenis }
1329b725ae77Skettenis 
1330b725ae77Skettenis static void
init_thread_db_ops(void)1331b725ae77Skettenis init_thread_db_ops (void)
1332b725ae77Skettenis {
1333b725ae77Skettenis   thread_db_ops.to_shortname = "multi-thread";
1334b725ae77Skettenis   thread_db_ops.to_longname = "multi-threaded child process.";
1335b725ae77Skettenis   thread_db_ops.to_doc = "Threads and pthreads support.";
1336b725ae77Skettenis   thread_db_ops.to_attach = thread_db_attach;
1337b725ae77Skettenis   thread_db_ops.to_detach = thread_db_detach;
1338b725ae77Skettenis   thread_db_ops.to_resume = thread_db_resume;
1339b725ae77Skettenis   thread_db_ops.to_wait = thread_db_wait;
1340b725ae77Skettenis   thread_db_ops.to_fetch_registers = thread_db_fetch_registers;
1341b725ae77Skettenis   thread_db_ops.to_store_registers = thread_db_store_registers;
1342*11efff7fSkettenis   thread_db_ops.deprecated_xfer_memory = thread_db_xfer_memory;
1343b725ae77Skettenis   thread_db_ops.to_kill = thread_db_kill;
1344b725ae77Skettenis   thread_db_ops.to_create_inferior = thread_db_create_inferior;
1345b725ae77Skettenis   thread_db_ops.to_post_startup_inferior = thread_db_post_startup_inferior;
1346b725ae77Skettenis   thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
1347b725ae77Skettenis   thread_db_ops.to_thread_alive = thread_db_thread_alive;
1348b725ae77Skettenis   thread_db_ops.to_find_new_threads = thread_db_find_new_threads;
1349b725ae77Skettenis   thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
1350b725ae77Skettenis   thread_db_ops.to_stratum = thread_stratum;
1351b725ae77Skettenis   thread_db_ops.to_has_thread_control = tc_schedlock;
1352b725ae77Skettenis   thread_db_ops.to_get_thread_local_address
1353b725ae77Skettenis     = thread_db_get_thread_local_address;
1354b725ae77Skettenis   thread_db_ops.to_magic = OPS_MAGIC;
1355b725ae77Skettenis }
1356b725ae77Skettenis 
1357b725ae77Skettenis void
_initialize_thread_db(void)1358b725ae77Skettenis _initialize_thread_db (void)
1359b725ae77Skettenis {
1360b725ae77Skettenis   /* Only initialize the module if we can load libthread_db.  */
1361b725ae77Skettenis   if (thread_db_load ())
1362b725ae77Skettenis     {
1363b725ae77Skettenis       init_thread_db_ops ();
1364b725ae77Skettenis       add_target (&thread_db_ops);
1365b725ae77Skettenis 
1366b725ae77Skettenis       /* Add ourselves to objfile event chain.  */
1367*11efff7fSkettenis       target_new_objfile_chain = deprecated_target_new_objfile_hook;
1368*11efff7fSkettenis       deprecated_target_new_objfile_hook = thread_db_new_objfile;
1369b725ae77Skettenis     }
1370b725ae77Skettenis }
1371