2007-10-23 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
[deliverable/binutils-gdb.git] / gdb / gdbserver / thread-db.c
CommitLineData
0d62e5e8 1/* Thread management interface, for the remote server for GDB.
6aba47ca 2 Copyright (C) 2002, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
0d62e5e8
DJ
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
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
0d62e5e8
DJ
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
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0d62e5e8
DJ
20
21#include "server.h"
22
23#include "linux-low.h"
24
25extern int debug_threads;
26
27#ifdef HAVE_THREAD_DB_H
28#include <thread_db.h>
29#endif
30
0050a760 31#include "gdb_proc_service.h"
0d62e5e8 32
186947f7
DJ
33#include <stdint.h>
34
0d62e5e8
DJ
35/* Structure that identifies the child process for the
36 <proc_service.h> interface. */
37static struct ps_prochandle proc_handle;
38
39/* Connection to the libthread_db library. */
40static td_thragent_t *thread_agent;
41
ae13219e 42static int find_first_thread (void);
0d62e5e8
DJ
43static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data);
44
45static char *
46thread_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";
3db0444b
DJ
94#ifdef HAVE_TD_VERSION
95 case TD_VERSION:
96 return "version mismatch between libthread_db and libpthread";
97#endif
0d62e5e8
DJ
98 default:
99 snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
100 return buf;
101 }
102}
103
104#if 0
105static char *
106thread_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
131static void
132thread_db_create_event (CORE_ADDR where)
133{
134 td_event_msg_t msg;
135 td_err_e err;
4105de34 136 struct process_info *process;
0d62e5e8
DJ
137
138 if (debug_threads)
139 fprintf (stderr, "Thread creation event.\n");
140
0d62e5e8
DJ
141 /* FIXME: This assumes we don't get another event.
142 In the LinuxThreads implementation, this is safe,
143 because all events come from the manager thread
144 (except for its own creation, of course). */
145 err = td_ta_event_getmsg (thread_agent, &msg);
146 if (err != TD_OK)
147 fprintf (stderr, "thread getmsg err: %s\n",
148 thread_db_err_str (err));
149
4105de34
DJ
150 /* If we do not know about the main thread yet, this would be a good time to
151 find it. We need to do this to pick up the main thread before any newly
152 created threads. */
ae13219e 153 process = get_thread_process (current_inferior);
4105de34 154 if (process->thread_known == 0)
ae13219e 155 find_first_thread ();
4105de34 156
0d62e5e8
DJ
157 /* msg.event == TD_EVENT_CREATE */
158
159 find_new_threads_callback (msg.th_p, NULL);
160}
161
162#if 0
163static void
164thread_db_death_event (CORE_ADDR where)
165{
166 if (debug_threads)
167 fprintf (stderr, "Thread death event.\n");
168}
169#endif
170
171static int
172thread_db_enable_reporting ()
173{
174 td_thr_events_t events;
175 td_notify_t notify;
176 td_err_e err;
177
178 /* Set the process wide mask saying which events we're interested in. */
179 td_event_emptyset (&events);
180 td_event_addset (&events, TD_CREATE);
181
182#if 0
183 /* This is reported to be broken in glibc 2.1.3. A different approach
184 will be necessary to support that. */
185 td_event_addset (&events, TD_DEATH);
186#endif
187
188 err = td_ta_set_event (thread_agent, &events);
189 if (err != TD_OK)
190 {
191 warning ("Unable to set global thread event mask: %s",
192 thread_db_err_str (err));
193 return 0;
194 }
195
196 /* Get address for thread creation breakpoint. */
197 err = td_ta_event_addr (thread_agent, TD_CREATE, &notify);
198 if (err != TD_OK)
199 {
200 warning ("Unable to get location for thread creation breakpoint: %s",
201 thread_db_err_str (err));
202 return 0;
203 }
204 set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr,
205 thread_db_create_event);
206
207#if 0
208 /* Don't concern ourselves with reported thread deaths, only
209 with actual thread deaths (via wait). */
210
211 /* Get address for thread death breakpoint. */
212 err = td_ta_event_addr (thread_agent, TD_DEATH, &notify);
213 if (err != TD_OK)
214 {
215 warning ("Unable to get location for thread death breakpoint: %s",
216 thread_db_err_str (err));
217 return;
218 }
219 set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr,
220 thread_db_death_event);
221#endif
222
223 return 1;
224}
225
ae13219e
DJ
226static int
227find_first_thread (void)
0d62e5e8 228{
ae13219e
DJ
229 td_thrhandle_t th;
230 td_thrinfo_t ti;
0d62e5e8
DJ
231 td_err_e err;
232 struct thread_info *inferior;
233 struct process_info *process;
234
ae13219e
DJ
235 inferior = (struct thread_info *) all_threads.head;
236 process = get_thread_process (inferior);
237 if (process->thread_known)
238 return 1;
239
240 /* Get information about the one thread we know we have. */
241 err = td_ta_map_lwp2thr (thread_agent, process->lwpid, &th);
242 if (err != TD_OK)
243 error ("Cannot get first thread handle: %s", thread_db_err_str (err));
244
245 err = td_thr_get_info (&th, &ti);
246 if (err != TD_OK)
247 error ("Cannot get first thread info: %s", thread_db_err_str (err));
248
249 if (debug_threads)
250 fprintf (stderr, "Found first thread %ld (LWP %d)\n",
251 ti.ti_tid, ti.ti_lid);
252
253 if (process->lwpid != ti.ti_lid)
254 fatal ("PID mismatch! Expected %ld, got %ld",
255 (long) process->lwpid, (long) ti.ti_lid);
256
257 /* If the new thread ID is zero, a final thread ID will be available
258 later. Do not enable thread debugging yet. */
259 if (ti.ti_tid == 0)
0d62e5e8 260 {
ae13219e
DJ
261 err = td_thr_event_enable (&th, 1);
262 if (err != TD_OK)
263 error ("Cannot enable thread event reporting for %d: %s",
264 ti.ti_lid, thread_db_err_str (err));
265 return 0;
0d62e5e8 266 }
ae13219e
DJ
267
268 /* Switch to indexing the threads list by TID. */
269 change_inferior_id (&all_threads, ti.ti_tid);
270
271 new_thread_notify (ti.ti_tid);
272
273 process->tid = ti.ti_tid;
274 process->lwpid = ti.ti_lid;
275 process->thread_known = 1;
276 process->th = th;
277
278 err = td_thr_event_enable (&th, 1);
279 if (err != TD_OK)
280 error ("Cannot enable thread event reporting for %d: %s",
281 ti.ti_lid, thread_db_err_str (err));
282
283 return 1;
284}
285
286static void
287maybe_attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
288{
289 td_err_e err;
290 struct thread_info *inferior;
291 struct process_info *process;
292
0d62e5e8
DJ
293 inferior = (struct thread_info *) find_inferior_id (&all_threads,
294 ti_p->ti_tid);
295 if (inferior != NULL)
296 return;
297
298 if (debug_threads)
299 fprintf (stderr, "Attaching to thread %ld (LWP %d)\n",
300 ti_p->ti_tid, ti_p->ti_lid);
301 linux_attach_lwp (ti_p->ti_lid, ti_p->ti_tid);
302 inferior = (struct thread_info *) find_inferior_id (&all_threads,
303 ti_p->ti_tid);
304 if (inferior == NULL)
305 {
306 warning ("Could not attach to thread %ld (LWP %d)\n",
307 ti_p->ti_tid, ti_p->ti_lid);
308 return;
309 }
310
311 process = inferior_target_data (inferior);
312
0d62e5e8
DJ
313 new_thread_notify (ti_p->ti_tid);
314
315 process->tid = ti_p->ti_tid;
316 process->lwpid = ti_p->ti_lid;
317
318 process->thread_known = 1;
dae5f5cf 319 process->th = *th_p;
0d62e5e8
DJ
320 err = td_thr_event_enable (th_p, 1);
321 if (err != TD_OK)
322 error ("Cannot enable thread event reporting for %d: %s",
323 ti_p->ti_lid, thread_db_err_str (err));
324}
325
326static int
327find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
328{
329 td_thrinfo_t ti;
330 td_err_e err;
331
332 err = td_thr_get_info (th_p, &ti);
333 if (err != TD_OK)
334 error ("Cannot get thread info: %s", thread_db_err_str (err));
335
336 /* Check for zombies. */
337 if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
338 return 0;
339
340 maybe_attach_thread (th_p, &ti);
341
342 return 0;
343}
344
345static void
346thread_db_find_new_threads (void)
347{
348 td_err_e err;
349
ae13219e
DJ
350 /* This function is only called when we first initialize thread_db.
351 First locate the initial thread. If it is not ready for
352 debugging yet, then stop. */
353 if (find_first_thread () == 0)
354 return;
355
0d62e5e8
DJ
356 /* Iterate over all user-space threads to discover new threads. */
357 err = td_ta_thr_iter (thread_agent, find_new_threads_callback, NULL,
358 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
359 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
360 if (err != TD_OK)
361 error ("Cannot find new threads: %s", thread_db_err_str (err));
362}
363
fd500816
DJ
364/* Cache all future symbols that thread_db might request. We can not
365 request symbols at arbitrary states in the remote protocol, only
366 when the client tells us that new symbols are available. So when
367 we load the thread library, make sure to check the entire list. */
368
369static void
370thread_db_look_up_symbols (void)
371{
372 const char **sym_list = td_symbol_list ();
373 CORE_ADDR unused;
374
375 for (sym_list = td_symbol_list (); *sym_list; sym_list++)
376 look_up_one_symbol (*sym_list, &unused);
377}
378
dae5f5cf
DJ
379int
380thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
381 CORE_ADDR load_module, CORE_ADDR *address)
382{
383#if HAVE_TD_THR_TLS_GET_ADDR
384 psaddr_t addr;
385 td_err_e err;
386 struct process_info *process;
387
388 process = get_thread_process (thread);
4105de34 389 if (!process->thread_known)
ae13219e 390 find_first_thread ();
dae5f5cf
DJ
391 if (!process->thread_known)
392 return TD_NOTHR;
393
186947f7
DJ
394 /* Note the cast through uintptr_t: this interface only works if
395 a target address fits in a psaddr_t, which is a host pointer.
396 So a 32-bit debugger can not access 64-bit TLS through this. */
397 err = td_thr_tls_get_addr (&process->th, (psaddr_t) (uintptr_t) load_module,
398 offset, &addr);
dae5f5cf
DJ
399 if (err == TD_OK)
400 {
186947f7 401 *address = (CORE_ADDR) (uintptr_t) addr;
dae5f5cf
DJ
402 return 0;
403 }
404 else
405 return err;
406#else
407 return -1;
408#endif
409}
410
0d62e5e8
DJ
411int
412thread_db_init ()
413{
414 int err;
415
fd500816
DJ
416 /* FIXME drow/2004-10-16: This is the "overall process ID", which
417 GNU/Linux calls tgid, "thread group ID". When we support
418 attaching to threads, the original thread may not be the correct
419 thread. We would have to get the process ID from /proc for NPTL.
420 For LinuxThreads we could do something similar: follow the chain
421 of parent processes until we find the highest one we're attached
422 to, and use its tgid.
423
424 This isn't the only place in gdbserver that assumes that the first
425 process in the list is the thread group leader. */
0d62e5e8
DJ
426 proc_handle.pid = ((struct inferior_list_entry *)current_inferior)->id;
427
ea025f5f
DJ
428 /* Allow new symbol lookups. */
429 all_symbols_looked_up = 0;
430
0d62e5e8
DJ
431 err = td_ta_new (&proc_handle, &thread_agent);
432 switch (err)
433 {
434 case TD_NOLIBTHREAD:
435 /* No thread library was detected. */
436 return 0;
437
438 case TD_OK:
439 /* The thread library was detected. */
440
441 if (thread_db_enable_reporting () == 0)
442 return 0;
443 thread_db_find_new_threads ();
fd500816 444 thread_db_look_up_symbols ();
ea025f5f 445 all_symbols_looked_up = 1;
0d62e5e8
DJ
446 return 1;
447
448 default:
3db0444b
DJ
449 warning ("error initializing thread_db library: %s",
450 thread_db_err_str (err));
0d62e5e8
DJ
451 }
452
453 return 0;
454}
This page took 0.404199 seconds and 4 git commands to generate.