Updated copyright notices for most files.
[deliverable/binutils-gdb.git] / gdb / gdbserver / thread-db.c
CommitLineData
0d62e5e8 1/* Thread management interface, for the remote server for GDB.
9b254dd1
DJ
2 Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008
3 Free Software Foundation, Inc.
0d62e5e8
DJ
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
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
0d62e5e8
DJ
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
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0d62e5e8
DJ
21
22#include "server.h"
23
24#include "linux-low.h"
25
26extern int debug_threads;
27
24a09b5f
DJ
28static int thread_db_use_events;
29
0d62e5e8
DJ
30#ifdef HAVE_THREAD_DB_H
31#include <thread_db.h>
32#endif
33
0050a760 34#include "gdb_proc_service.h"
0d62e5e8 35
186947f7
DJ
36#include <stdint.h>
37
0d62e5e8
DJ
38/* Structure that identifies the child process for the
39 <proc_service.h> interface. */
40static struct ps_prochandle proc_handle;
41
42/* Connection to the libthread_db library. */
43static td_thragent_t *thread_agent;
44
24a09b5f 45static int find_one_thread (int);
0d62e5e8
DJ
46static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data);
47
48static char *
49thread_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";
3db0444b
DJ
97#ifdef HAVE_TD_VERSION
98 case TD_VERSION:
99 return "version mismatch between libthread_db and libpthread";
100#endif
0d62e5e8
DJ
101 default:
102 snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
103 return buf;
104 }
105}
106
107#if 0
108static char *
109thread_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
b65d95c5 134static int
0d62e5e8
DJ
135thread_db_create_event (CORE_ADDR where)
136{
137 td_event_msg_t msg;
138 td_err_e err;
4105de34 139 struct process_info *process;
0d62e5e8
DJ
140
141 if (debug_threads)
142 fprintf (stderr, "Thread creation event.\n");
143
0d62e5e8
DJ
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
4105de34
DJ
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. */
ae13219e 156 process = get_thread_process (current_inferior);
4105de34 157 if (process->thread_known == 0)
24a09b5f 158 find_one_thread (process->lwpid);
4105de34 159
0d62e5e8
DJ
160 /* msg.event == TD_EVENT_CREATE */
161
162 find_new_threads_callback (msg.th_p, NULL);
b65d95c5
DJ
163
164 return 0;
0d62e5e8
DJ
165}
166
167#if 0
b65d95c5 168static int
0d62e5e8
DJ
169thread_db_death_event (CORE_ADDR where)
170{
171 if (debug_threads)
172 fprintf (stderr, "Thread death event.\n");
b65d95c5
DJ
173
174 return 0;
0d62e5e8
DJ
175}
176#endif
177
178static int
179thread_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
ae13219e 233static int
24a09b5f 234find_one_thread (int lwpid)
0d62e5e8 235{
ae13219e
DJ
236 td_thrhandle_t th;
237 td_thrinfo_t ti;
0d62e5e8
DJ
238 td_err_e err;
239 struct thread_info *inferior;
240 struct process_info *process;
241
24a09b5f 242 inferior = (struct thread_info *) find_inferior_id (&all_threads, lwpid);
ae13219e
DJ
243 process = get_thread_process (inferior);
244 if (process->thread_known)
245 return 1;
246
24a09b5f 247 /* Get information about this thread. */
ae13219e
DJ
248 err = td_ta_map_lwp2thr (thread_agent, process->lwpid, &th);
249 if (err != TD_OK)
24a09b5f
DJ
250 error ("Cannot get thread handle for LWP %d: %s",
251 lwpid, thread_db_err_str (err));
ae13219e
DJ
252
253 err = td_thr_get_info (&th, &ti);
254 if (err != TD_OK)
24a09b5f
DJ
255 error ("Cannot get thread info for LWP %d: %s",
256 lwpid, thread_db_err_str (err));
ae13219e
DJ
257
258 if (debug_threads)
24a09b5f 259 fprintf (stderr, "Found thread %ld (LWP %d)\n",
ae13219e
DJ
260 ti.ti_tid, ti.ti_lid);
261
262 if (process->lwpid != ti.ti_lid)
24a09b5f
DJ
263 {
264 warning ("PID mismatch! Expected %ld, got %ld",
265 (long) process->lwpid, (long) ti.ti_lid);
266 return 0;
267 }
ae13219e 268
24a09b5f 269 if (thread_db_use_events)
0d62e5e8 270 {
ae13219e
DJ
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));
0d62e5e8 275 }
ae13219e 276
24a09b5f
DJ
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;
ae13219e 281
ae13219e 282 process->thread_known = 1;
24a09b5f 283 process->tid = ti.ti_tid;
ae13219e
DJ
284 process->th = th;
285
ae13219e
DJ
286 return 1;
287}
288
289static void
290maybe_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
0d62e5e8 296 inferior = (struct thread_info *) find_inferior_id (&all_threads,
24a09b5f 297 ti_p->ti_lid);
0d62e5e8
DJ
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);
24a09b5f 304 linux_attach_lwp (ti_p->ti_lid);
0d62e5e8 305 inferior = (struct thread_info *) find_inferior_id (&all_threads,
24a09b5f 306 ti_p->ti_lid);
0d62e5e8
DJ
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
0d62e5e8 316 process->tid = ti_p->ti_tid;
0d62e5e8 317 process->thread_known = 1;
dae5f5cf 318 process->th = *th_p;
24a09b5f
DJ
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 }
0d62e5e8
DJ
327}
328
329static int
330find_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
348static void
349thread_db_find_new_threads (void)
350{
351 td_err_e err;
352
ae13219e
DJ
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. */
24a09b5f 356 if (find_one_thread (all_threads.head->id) == 0)
ae13219e
DJ
357 return;
358
0d62e5e8
DJ
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
fd500816
DJ
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
372static void
373thread_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
dae5f5cf
DJ
382int
383thread_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);
4105de34 392 if (!process->thread_known)
24a09b5f 393 find_one_thread (process->lwpid);
dae5f5cf
DJ
394 if (!process->thread_known)
395 return TD_NOTHR;
396
186947f7
DJ
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);
dae5f5cf
DJ
402 if (err == TD_OK)
403 {
186947f7 404 *address = (CORE_ADDR) (uintptr_t) addr;
dae5f5cf
DJ
405 return 0;
406 }
407 else
408 return err;
409#else
410 return -1;
411#endif
412}
413
0d62e5e8 414int
24a09b5f 415thread_db_init (int use_events)
0d62e5e8
DJ
416{
417 int err;
418
fd500816
DJ
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. */
0d62e5e8
DJ
429 proc_handle.pid = ((struct inferior_list_entry *)current_inferior)->id;
430
ea025f5f
DJ
431 /* Allow new symbol lookups. */
432 all_symbols_looked_up = 0;
433
24a09b5f
DJ
434 thread_db_use_events = use_events;
435
0d62e5e8
DJ
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
24a09b5f 446 if (use_events && thread_db_enable_reporting () == 0)
0d62e5e8
DJ
447 return 0;
448 thread_db_find_new_threads ();
fd500816 449 thread_db_look_up_symbols ();
ea025f5f 450 all_symbols_looked_up = 1;
0d62e5e8
DJ
451 return 1;
452
453 default:
3db0444b
DJ
454 warning ("error initializing thread_db library: %s",
455 thread_db_err_str (err));
0d62e5e8
DJ
456 }
457
458 return 0;
459}
This page took 0.405227 seconds and 4 git commands to generate.