OSDN Git Service

76900014eea8c1884b028b362ed551078438d9cf
[pf3gnuchains/pf3gnuchains3x.git] / gdb / gdbserver / thread-db.c
1 /* Thread management interface, for the remote server for GDB.
2    Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008
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 3 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, see <http://www.gnu.org/licenses/>.  */
21
22 #include "server.h"
23
24 #include "linux-low.h"
25
26 extern int debug_threads;
27
28 static int thread_db_use_events;
29
30 #ifdef HAVE_THREAD_DB_H
31 #include <thread_db.h>
32 #endif
33
34 #include "gdb_proc_service.h"
35
36 #include <stdint.h>
37
38 /* Structure that identifies the child process for the
39    <proc_service.h> interface.  */
40 static struct ps_prochandle proc_handle;
41
42 /* Connection to the libthread_db library.  */
43 static td_thragent_t *thread_agent;
44
45 static int find_one_thread (int);
46 static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data);
47
48 static char *
49 thread_db_err_str (td_err_e err)
50 {
51   static char buf[64];
52
53   switch (err)
54     {
55     case TD_OK:
56       return "generic 'call succeeded'";
57     case TD_ERR:
58       return "generic error";
59     case TD_NOTHR:
60       return "no thread to satisfy query";
61     case TD_NOSV:
62       return "no sync handle to satisfy query";
63     case TD_NOLWP:
64       return "no LWP to satisfy query";
65     case TD_BADPH:
66       return "invalid process handle";
67     case TD_BADTH:
68       return "invalid thread handle";
69     case TD_BADSH:
70       return "invalid synchronization handle";
71     case TD_BADTA:
72       return "invalid thread agent";
73     case TD_BADKEY:
74       return "invalid key";
75     case TD_NOMSG:
76       return "no event message for getmsg";
77     case TD_NOFPREGS:
78       return "FPU register set not available";
79     case TD_NOLIBTHREAD:
80       return "application not linked with libthread";
81     case TD_NOEVENT:
82       return "requested event is not supported";
83     case TD_NOCAPAB:
84       return "capability not available";
85     case TD_DBERR:
86       return "debugger service failed";
87     case TD_NOAPLIC:
88       return "operation not applicable to";
89     case TD_NOTSD:
90       return "no thread-specific data for this thread";
91     case TD_MALLOC:
92       return "malloc failed";
93     case TD_PARTIALREG:
94       return "only part of register set was written/read";
95     case TD_NOXREGS:
96       return "X register set not available for this thread";
97 #ifdef HAVE_TD_VERSION
98     case TD_VERSION:
99       return "version mismatch between libthread_db and libpthread";
100 #endif
101     default:
102       snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
103       return buf;
104     }
105 }
106
107 #if 0
108 static char *
109 thread_db_state_str (td_thr_state_e state)
110 {
111   static char buf[64];
112
113   switch (state)
114     {
115     case TD_THR_STOPPED:
116       return "stopped by debugger";
117     case TD_THR_RUN:
118       return "runnable";
119     case TD_THR_ACTIVE:
120       return "active";
121     case TD_THR_ZOMBIE:
122       return "zombie";
123     case TD_THR_SLEEP:
124       return "sleeping";
125     case TD_THR_STOPPED_ASLEEP:
126       return "stopped by debugger AND blocked";
127     default:
128       snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
129       return buf;
130     }
131 }
132 #endif
133
134 static int
135 thread_db_create_event (CORE_ADDR where)
136 {
137   td_event_msg_t msg;
138   td_err_e err;
139   struct process_info *process;
140
141   if (debug_threads)
142     fprintf (stderr, "Thread creation event.\n");
143
144   /* FIXME: This assumes we don't get another event.
145      In the LinuxThreads implementation, this is safe,
146      because all events come from the manager thread
147      (except for its own creation, of course).  */
148   err = td_ta_event_getmsg (thread_agent, &msg);
149   if (err != TD_OK)
150     fprintf (stderr, "thread getmsg err: %s\n",
151              thread_db_err_str (err));
152
153   /* If we do not know about the main thread yet, this would be a good time to
154      find it.  We need to do this to pick up the main thread before any newly
155      created threads.  */
156   process = get_thread_process (current_inferior);
157   if (process->thread_known == 0)
158     find_one_thread (process->lwpid);
159
160   /* msg.event == TD_EVENT_CREATE */
161
162   find_new_threads_callback (msg.th_p, NULL);
163
164   return 0;
165 }
166
167 #if 0
168 static int
169 thread_db_death_event (CORE_ADDR where)
170 {
171   if (debug_threads)
172     fprintf (stderr, "Thread death event.\n");
173
174   return 0;
175 }
176 #endif
177
178 static int
179 thread_db_enable_reporting ()
180 {
181   td_thr_events_t events;
182   td_notify_t notify;
183   td_err_e err;
184
185   /* Set the process wide mask saying which events we're interested in.  */
186   td_event_emptyset (&events);
187   td_event_addset (&events, TD_CREATE);
188
189 #if 0
190   /* This is reported to be broken in glibc 2.1.3.  A different approach
191      will be necessary to support that.  */
192   td_event_addset (&events, TD_DEATH);
193 #endif
194
195   err = td_ta_set_event (thread_agent, &events);
196   if (err != TD_OK)
197     {
198       warning ("Unable to set global thread event mask: %s",
199                thread_db_err_str (err));
200       return 0;
201     }
202
203   /* Get address for thread creation breakpoint.  */
204   err = td_ta_event_addr (thread_agent, TD_CREATE, &notify);
205   if (err != TD_OK)
206     {
207       warning ("Unable to get location for thread creation breakpoint: %s",
208                thread_db_err_str (err));
209       return 0;
210     }
211   set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr,
212                      thread_db_create_event);
213
214 #if 0
215   /* Don't concern ourselves with reported thread deaths, only
216      with actual thread deaths (via wait).  */
217
218   /* Get address for thread death breakpoint.  */
219   err = td_ta_event_addr (thread_agent, TD_DEATH, &notify);
220   if (err != TD_OK)
221     {
222       warning ("Unable to get location for thread death breakpoint: %s",
223                thread_db_err_str (err));
224       return;
225     }
226   set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr,
227                      thread_db_death_event);
228 #endif
229
230   return 1;
231 }
232
233 static int
234 find_one_thread (int lwpid)
235 {
236   td_thrhandle_t th;
237   td_thrinfo_t ti;
238   td_err_e err;
239   struct thread_info *inferior;
240   struct process_info *process;
241
242   inferior = (struct thread_info *) find_inferior_id (&all_threads, lwpid);
243   process = get_thread_process (inferior);
244   if (process->thread_known)
245     return 1;
246
247   /* Get information about this thread.  */
248   err = td_ta_map_lwp2thr (thread_agent, process->lwpid, &th);
249   if (err != TD_OK)
250     error ("Cannot get thread handle for LWP %d: %s",
251            lwpid, thread_db_err_str (err));
252
253   err = td_thr_get_info (&th, &ti);
254   if (err != TD_OK)
255     error ("Cannot get thread info for LWP %d: %s",
256            lwpid, thread_db_err_str (err));
257
258   if (debug_threads)
259     fprintf (stderr, "Found thread %ld (LWP %d)\n",
260              ti.ti_tid, ti.ti_lid);
261
262   if (process->lwpid != ti.ti_lid)
263     {
264       warning ("PID mismatch!  Expected %ld, got %ld",
265                (long) process->lwpid, (long) ti.ti_lid);
266       return 0;
267     }
268
269   if (thread_db_use_events)
270     {
271       err = td_thr_event_enable (&th, 1);
272       if (err != TD_OK)
273         error ("Cannot enable thread event reporting for %d: %s",
274                ti.ti_lid, thread_db_err_str (err));
275     }
276
277   /* If the new thread ID is zero, a final thread ID will be available
278      later.  Do not enable thread debugging yet.  */
279   if (ti.ti_tid == 0)
280     return 0;
281
282   process->thread_known = 1;
283   process->tid = ti.ti_tid;
284   process->th = th;
285
286   return 1;
287 }
288
289 static void
290 maybe_attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
291 {
292   td_err_e err;
293   struct thread_info *inferior;
294   struct process_info *process;
295
296   inferior = (struct thread_info *) find_inferior_id (&all_threads,
297                                                       ti_p->ti_lid);
298   if (inferior != NULL)
299     return;
300
301   if (debug_threads)
302     fprintf (stderr, "Attaching to thread %ld (LWP %d)\n",
303              ti_p->ti_tid, ti_p->ti_lid);
304   linux_attach_lwp (ti_p->ti_lid);
305   inferior = (struct thread_info *) find_inferior_id (&all_threads,
306                                                       ti_p->ti_lid);
307   if (inferior == NULL)
308     {
309       warning ("Could not attach to thread %ld (LWP %d)\n",
310                ti_p->ti_tid, ti_p->ti_lid);
311       return;
312     }
313
314   process = inferior_target_data (inferior);
315
316   process->tid = ti_p->ti_tid;
317   process->thread_known = 1;
318   process->th = *th_p;
319
320   if (thread_db_use_events)
321     {
322       err = td_thr_event_enable (th_p, 1);
323       if (err != TD_OK)
324         error ("Cannot enable thread event reporting for %d: %s",
325                ti_p->ti_lid, thread_db_err_str (err));
326     }
327 }
328
329 static int
330 find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
331 {
332   td_thrinfo_t ti;
333   td_err_e err;
334
335   err = td_thr_get_info (th_p, &ti);
336   if (err != TD_OK)
337     error ("Cannot get thread info: %s", thread_db_err_str (err));
338
339   /* Check for zombies.  */
340   if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
341     return 0;
342
343   maybe_attach_thread (th_p, &ti);
344
345   return 0;
346 }
347
348 static void
349 thread_db_find_new_threads (void)
350 {
351   td_err_e err;
352
353   /* This function is only called when we first initialize thread_db.
354      First locate the initial thread.  If it is not ready for
355      debugging yet, then stop.  */
356   if (find_one_thread (all_threads.head->id) == 0)
357     return;
358
359   /* Iterate over all user-space threads to discover new threads.  */
360   err = td_ta_thr_iter (thread_agent, find_new_threads_callback, NULL,
361                         TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
362                         TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
363   if (err != TD_OK)
364     error ("Cannot find new threads: %s", thread_db_err_str (err));
365 }
366
367 /* Cache all future symbols that thread_db might request.  We can not
368    request symbols at arbitrary states in the remote protocol, only
369    when the client tells us that new symbols are available.  So when
370    we load the thread library, make sure to check the entire list.  */
371
372 static void
373 thread_db_look_up_symbols (void)
374 {
375   const char **sym_list = td_symbol_list ();
376   CORE_ADDR unused;
377
378   for (sym_list = td_symbol_list (); *sym_list; sym_list++)
379     look_up_one_symbol (*sym_list, &unused);
380 }
381
382 int
383 thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
384                            CORE_ADDR load_module, CORE_ADDR *address)
385 {
386 #if HAVE_TD_THR_TLS_GET_ADDR
387   psaddr_t addr;
388   td_err_e err;
389   struct process_info *process;
390
391   process = get_thread_process (thread);
392   if (!process->thread_known)
393     find_one_thread (process->lwpid);
394   if (!process->thread_known)
395     return TD_NOTHR;
396
397   /* Note the cast through uintptr_t: this interface only works if
398      a target address fits in a psaddr_t, which is a host pointer.
399      So a 32-bit debugger can not access 64-bit TLS through this.  */
400   err = td_thr_tls_get_addr (&process->th, (psaddr_t) (uintptr_t) load_module,
401                              offset, &addr);
402   if (err == TD_OK)
403     {
404       *address = (CORE_ADDR) (uintptr_t) addr;
405       return 0;
406     }
407   else
408     return err;
409 #else
410   return -1;
411 #endif
412 }
413
414 int
415 thread_db_init (int use_events)
416 {
417   int err;
418
419   /* FIXME drow/2004-10-16: This is the "overall process ID", which
420      GNU/Linux calls tgid, "thread group ID".  When we support
421      attaching to threads, the original thread may not be the correct
422      thread.  We would have to get the process ID from /proc for NPTL.
423      For LinuxThreads we could do something similar: follow the chain
424      of parent processes until we find the highest one we're attached
425      to, and use its tgid.
426
427      This isn't the only place in gdbserver that assumes that the first
428      process in the list is the thread group leader.  */
429   proc_handle.pid = ((struct inferior_list_entry *)current_inferior)->id;
430
431   /* Allow new symbol lookups.  */
432   all_symbols_looked_up = 0;
433
434   thread_db_use_events = use_events;
435
436   err = td_ta_new (&proc_handle, &thread_agent);
437   switch (err)
438     {
439     case TD_NOLIBTHREAD:
440       /* No thread library was detected.  */
441       return 0;
442
443     case TD_OK:
444       /* The thread library was detected.  */
445
446       if (use_events && thread_db_enable_reporting () == 0)
447         return 0;
448       thread_db_find_new_threads ();
449       thread_db_look_up_symbols ();
450       all_symbols_looked_up = 1;
451       return 1;
452
453     default:
454       warning ("error initializing thread_db library: %s",
455                thread_db_err_str (err));
456     }
457
458   return 0;
459 }