This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / gdb / gdbserver / thread-db.c
1 /* Thread management interface, for the remote server for GDB.
2    Copyright (C) 2002, 2004, 2005, 2006
3    Free Software Foundation, Inc.
4
5    Contributed by MontaVista Software.
6
7    This file is part of GDB.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street, Fifth Floor,
22    Boston, MA 02110-1301, USA.  */
23
24 #include "server.h"
25
26 #include "linux-low.h"
27
28 extern int debug_threads;
29
30 #ifdef HAVE_THREAD_DB_H
31 #include <thread_db.h>
32 #endif
33
34 #include "gdb_proc_service.h"
35
36 /* Structure that identifies the child process for the
37    <proc_service.h> interface.  */
38 static struct ps_prochandle proc_handle;
39
40 /* Connection to the libthread_db library.  */
41 static td_thragent_t *thread_agent;
42
43 static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data);
44
45 static char *
46 thread_db_err_str (td_err_e err)
47 {
48   static char buf[64];
49
50   switch (err)
51     {
52     case TD_OK:
53       return "generic 'call succeeded'";
54     case TD_ERR:
55       return "generic error";
56     case TD_NOTHR:
57       return "no thread to satisfy query";
58     case TD_NOSV:
59       return "no sync handle to satisfy query";
60     case TD_NOLWP:
61       return "no LWP to satisfy query";
62     case TD_BADPH:
63       return "invalid process handle";
64     case TD_BADTH:
65       return "invalid thread handle";
66     case TD_BADSH:
67       return "invalid synchronization handle";
68     case TD_BADTA:
69       return "invalid thread agent";
70     case TD_BADKEY:
71       return "invalid key";
72     case TD_NOMSG:
73       return "no event message for getmsg";
74     case TD_NOFPREGS:
75       return "FPU register set not available";
76     case TD_NOLIBTHREAD:
77       return "application not linked with libthread";
78     case TD_NOEVENT:
79       return "requested event is not supported";
80     case TD_NOCAPAB:
81       return "capability not available";
82     case TD_DBERR:
83       return "debugger service failed";
84     case TD_NOAPLIC:
85       return "operation not applicable to";
86     case TD_NOTSD:
87       return "no thread-specific data for this thread";
88     case TD_MALLOC:
89       return "malloc failed";
90     case TD_PARTIALREG:
91       return "only part of register set was written/read";
92     case TD_NOXREGS:
93       return "X register set not available for this thread";
94 #ifdef HAVE_TD_VERSION
95     case TD_VERSION:
96       return "version mismatch between libthread_db and libpthread";
97 #endif
98     default:
99       snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
100       return buf;
101     }
102 }
103
104 #if 0
105 static char *
106 thread_db_state_str (td_thr_state_e state)
107 {
108   static char buf[64];
109
110   switch (state)
111     {
112     case TD_THR_STOPPED:
113       return "stopped by debugger";
114     case TD_THR_RUN:
115       return "runnable";
116     case TD_THR_ACTIVE:
117       return "active";
118     case TD_THR_ZOMBIE:
119       return "zombie";
120     case TD_THR_SLEEP:
121       return "sleeping";
122     case TD_THR_STOPPED_ASLEEP:
123       return "stopped by debugger AND blocked";
124     default:
125       snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
126       return buf;
127     }
128 }
129 #endif
130
131 static void
132 thread_db_create_event (CORE_ADDR where)
133 {
134   td_event_msg_t msg;
135   td_err_e err;
136   struct inferior_linux_data *tdata;
137
138   if (debug_threads)
139     fprintf (stderr, "Thread creation event.\n");
140
141   tdata = inferior_target_data (current_inferior);
142
143   /* FIXME: This assumes we don't get another event.
144      In the LinuxThreads implementation, this is safe,
145      because all events come from the manager thread
146      (except for its own creation, of course).  */
147   err = td_ta_event_getmsg (thread_agent, &msg);
148   if (err != TD_OK)
149     fprintf (stderr, "thread getmsg err: %s\n",
150              thread_db_err_str (err));
151
152   /* msg.event == TD_EVENT_CREATE */
153
154   find_new_threads_callback (msg.th_p, NULL);
155 }
156
157 #if 0
158 static void
159 thread_db_death_event (CORE_ADDR where)
160 {
161   if (debug_threads)
162     fprintf (stderr, "Thread death event.\n");
163 }
164 #endif
165
166 static int
167 thread_db_enable_reporting ()
168 {
169   td_thr_events_t events;
170   td_notify_t notify;
171   td_err_e err;
172
173   /* Set the process wide mask saying which events we're interested in.  */
174   td_event_emptyset (&events);
175   td_event_addset (&events, TD_CREATE);
176
177 #if 0
178   /* This is reported to be broken in glibc 2.1.3.  A different approach
179      will be necessary to support that.  */
180   td_event_addset (&events, TD_DEATH);
181 #endif
182
183   err = td_ta_set_event (thread_agent, &events);
184   if (err != TD_OK)
185     {
186       warning ("Unable to set global thread event mask: %s",
187                thread_db_err_str (err));
188       return 0;
189     }
190
191   /* Get address for thread creation breakpoint.  */
192   err = td_ta_event_addr (thread_agent, TD_CREATE, &notify);
193   if (err != TD_OK)
194     {
195       warning ("Unable to get location for thread creation breakpoint: %s",
196                thread_db_err_str (err));
197       return 0;
198     }
199   set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr,
200                      thread_db_create_event);
201
202 #if 0
203   /* Don't concern ourselves with reported thread deaths, only
204      with actual thread deaths (via wait).  */
205
206   /* Get address for thread death breakpoint.  */
207   err = td_ta_event_addr (thread_agent, TD_DEATH, &notify);
208   if (err != TD_OK)
209     {
210       warning ("Unable to get location for thread death breakpoint: %s",
211                thread_db_err_str (err));
212       return;
213     }
214   set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr,
215                      thread_db_death_event);
216 #endif
217
218   return 1;
219 }
220
221 static void
222 maybe_attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
223 {
224   td_err_e err;
225   struct thread_info *inferior;
226   struct process_info *process;
227
228   /* If we are attaching to our first thread, things are a little
229      different.  */
230   if (all_threads.head == all_threads.tail)
231     {
232       inferior = (struct thread_info *) all_threads.head;
233       process = get_thread_process (inferior);
234       if (process->thread_known == 0)
235         {
236           /* Switch to indexing the threads list by TID.  */
237           change_inferior_id (&all_threads, ti_p->ti_tid);
238           goto found;
239         }
240     }
241   
242   inferior = (struct thread_info *) find_inferior_id (&all_threads,
243                                                       ti_p->ti_tid);
244   if (inferior != NULL)
245     return;
246
247   if (debug_threads)
248     fprintf (stderr, "Attaching to thread %ld (LWP %d)\n",
249              ti_p->ti_tid, ti_p->ti_lid);
250   linux_attach_lwp (ti_p->ti_lid, ti_p->ti_tid);
251   inferior = (struct thread_info *) find_inferior_id (&all_threads,
252                                                       ti_p->ti_tid);
253   if (inferior == NULL)
254     {
255       warning ("Could not attach to thread %ld (LWP %d)\n",
256                ti_p->ti_tid, ti_p->ti_lid);
257       return;
258     }
259
260   process = inferior_target_data (inferior);
261
262 found:
263   new_thread_notify (ti_p->ti_tid);
264
265   process->tid = ti_p->ti_tid;
266   process->lwpid = ti_p->ti_lid;
267
268   process->thread_known = 1;
269   err = td_thr_event_enable (th_p, 1);
270   if (err != TD_OK)
271     error ("Cannot enable thread event reporting for %d: %s",
272            ti_p->ti_lid, thread_db_err_str (err));
273 }
274
275 static int
276 find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
277 {
278   td_thrinfo_t ti;
279   td_err_e err;
280
281   err = td_thr_get_info (th_p, &ti);
282   if (err != TD_OK)
283     error ("Cannot get thread info: %s", thread_db_err_str (err));
284
285   /* Check for zombies.  */
286   if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
287     return 0;
288
289   maybe_attach_thread (th_p, &ti);
290
291   return 0;
292 }
293
294 static void
295 thread_db_find_new_threads (void)
296 {
297   td_err_e err;
298
299   /* Iterate over all user-space threads to discover new threads.  */
300   err = td_ta_thr_iter (thread_agent, find_new_threads_callback, NULL,
301                         TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
302                         TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
303   if (err != TD_OK)
304     error ("Cannot find new threads: %s", thread_db_err_str (err));
305 }
306
307 /* Cache all future symbols that thread_db might request.  We can not
308    request symbols at arbitrary states in the remote protocol, only
309    when the client tells us that new symbols are available.  So when
310    we load the thread library, make sure to check the entire list.  */
311
312 static void
313 thread_db_look_up_symbols (void)
314 {
315   const char **sym_list = td_symbol_list ();
316   CORE_ADDR unused;
317
318   for (sym_list = td_symbol_list (); *sym_list; sym_list++)
319     look_up_one_symbol (*sym_list, &unused);
320 }
321
322 int
323 thread_db_init ()
324 {
325   int err;
326
327   /* FIXME drow/2004-10-16: This is the "overall process ID", which
328      GNU/Linux calls tgid, "thread group ID".  When we support
329      attaching to threads, the original thread may not be the correct
330      thread.  We would have to get the process ID from /proc for NPTL.
331      For LinuxThreads we could do something similar: follow the chain
332      of parent processes until we find the highest one we're attached
333      to, and use its tgid.
334
335      This isn't the only place in gdbserver that assumes that the first
336      process in the list is the thread group leader.  */
337   proc_handle.pid = ((struct inferior_list_entry *)current_inferior)->id;
338
339   err = td_ta_new (&proc_handle, &thread_agent);
340   switch (err)
341     {
342     case TD_NOLIBTHREAD:
343       /* No thread library was detected.  */
344       return 0;
345
346     case TD_OK:
347       /* The thread library was detected.  */
348
349       if (thread_db_enable_reporting () == 0)
350         return 0;
351       thread_db_find_new_threads ();
352       thread_db_look_up_symbols ();
353       return 1;
354
355     default:
356       warning ("error initializing thread_db library: %s",
357                thread_db_err_str (err));
358     }
359
360   return 0;
361 }