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