OSDN Git Service

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