*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / gdbserver / thread-db.c
CommitLineData
0d62e5e8 1/* Thread management interface, for the remote server for GDB.
0fb0cc75 2 Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009
9b254dd1 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
95954743 38static int find_one_thread (ptid_t);
0d62e5e8
DJ
39static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data);
40
54363045 41static const char *
0d62e5e8
DJ
42thread_db_err_str (td_err_e err)
43{
44 static char buf[64];
45
46 switch (err)
47 {
48 case TD_OK:
49 return "generic 'call succeeded'";
50 case TD_ERR:
51 return "generic error";
52 case TD_NOTHR:
53 return "no thread to satisfy query";
54 case TD_NOSV:
55 return "no sync handle to satisfy query";
56 case TD_NOLWP:
57 return "no LWP to satisfy query";
58 case TD_BADPH:
59 return "invalid process handle";
60 case TD_BADTH:
61 return "invalid thread handle";
62 case TD_BADSH:
63 return "invalid synchronization handle";
64 case TD_BADTA:
65 return "invalid thread agent";
66 case TD_BADKEY:
67 return "invalid key";
68 case TD_NOMSG:
69 return "no event message for getmsg";
70 case TD_NOFPREGS:
71 return "FPU register set not available";
72 case TD_NOLIBTHREAD:
73 return "application not linked with libthread";
74 case TD_NOEVENT:
75 return "requested event is not supported";
76 case TD_NOCAPAB:
77 return "capability not available";
78 case TD_DBERR:
79 return "debugger service failed";
80 case TD_NOAPLIC:
81 return "operation not applicable to";
82 case TD_NOTSD:
83 return "no thread-specific data for this thread";
84 case TD_MALLOC:
85 return "malloc failed";
86 case TD_PARTIALREG:
87 return "only part of register set was written/read";
88 case TD_NOXREGS:
89 return "X register set not available for this thread";
3db0444b
DJ
90#ifdef HAVE_TD_VERSION
91 case TD_VERSION:
92 return "version mismatch between libthread_db and libpthread";
93#endif
0d62e5e8
DJ
94 default:
95 snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
96 return buf;
97 }
98}
99
100#if 0
101static char *
102thread_db_state_str (td_thr_state_e state)
103{
104 static char buf[64];
105
106 switch (state)
107 {
108 case TD_THR_STOPPED:
109 return "stopped by debugger";
110 case TD_THR_RUN:
111 return "runnable";
112 case TD_THR_ACTIVE:
113 return "active";
114 case TD_THR_ZOMBIE:
115 return "zombie";
116 case TD_THR_SLEEP:
117 return "sleeping";
118 case TD_THR_STOPPED_ASLEEP:
119 return "stopped by debugger AND blocked";
120 default:
121 snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
122 return buf;
123 }
124}
125#endif
126
b65d95c5 127static int
0d62e5e8
DJ
128thread_db_create_event (CORE_ADDR where)
129{
130 td_event_msg_t msg;
131 td_err_e err;
54a0b537 132 struct lwp_info *lwp;
95954743 133 struct process_info_private *proc = current_process()->private;
0d62e5e8
DJ
134
135 if (debug_threads)
136 fprintf (stderr, "Thread creation event.\n");
137
0d62e5e8
DJ
138 /* FIXME: This assumes we don't get another event.
139 In the LinuxThreads implementation, this is safe,
140 because all events come from the manager thread
141 (except for its own creation, of course). */
95954743 142 err = td_ta_event_getmsg (proc->thread_agent, &msg);
0d62e5e8
DJ
143 if (err != TD_OK)
144 fprintf (stderr, "thread getmsg err: %s\n",
145 thread_db_err_str (err));
146
4105de34
DJ
147 /* If we do not know about the main thread yet, this would be a good time to
148 find it. We need to do this to pick up the main thread before any newly
149 created threads. */
54a0b537
PA
150 lwp = get_thread_lwp (current_inferior);
151 if (lwp->thread_known == 0)
95954743 152 find_one_thread (lwp->head.id);
4105de34 153
0d62e5e8
DJ
154 /* msg.event == TD_EVENT_CREATE */
155
156 find_new_threads_callback (msg.th_p, NULL);
b65d95c5
DJ
157
158 return 0;
0d62e5e8
DJ
159}
160
161#if 0
b65d95c5 162static int
0d62e5e8
DJ
163thread_db_death_event (CORE_ADDR where)
164{
165 if (debug_threads)
166 fprintf (stderr, "Thread death event.\n");
b65d95c5
DJ
167
168 return 0;
0d62e5e8
DJ
169}
170#endif
171
172static int
173thread_db_enable_reporting ()
174{
175 td_thr_events_t events;
176 td_notify_t notify;
177 td_err_e err;
95954743 178 struct process_info_private *proc = current_process()->private;
0d62e5e8
DJ
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
95954743 190 err = td_ta_set_event (proc->thread_agent, &events);
0d62e5e8
DJ
191 if (err != TD_OK)
192 {
193 warning ("Unable to set global thread event mask: %s",
1b3f6016 194 thread_db_err_str (err));
0d62e5e8
DJ
195 return 0;
196 }
197
198 /* Get address for thread creation breakpoint. */
95954743 199 err = td_ta_event_addr (proc->thread_agent, TD_CREATE, &notify);
0d62e5e8
DJ
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. */
95954743 214 err = td_ta_event_addr (proc->thread_agent, TD_DEATH, &notify);
0d62e5e8
DJ
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 228static int
95954743 229find_one_thread (ptid_t ptid)
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;
54a0b537 235 struct lwp_info *lwp;
7fe519cb 236 struct process_info_private *proc;
95954743 237 int lwpid = ptid_get_lwp (ptid);
0d62e5e8 238
95954743 239 inferior = (struct thread_info *) find_inferior_id (&all_threads, ptid);
54a0b537
PA
240 lwp = get_thread_lwp (inferior);
241 if (lwp->thread_known)
ae13219e
DJ
242 return 1;
243
24a09b5f 244 /* Get information about this thread. */
7fe519cb 245 proc = get_thread_process (inferior)->private;
95954743 246 err = td_ta_map_lwp2thr (proc->thread_agent, lwpid, &th);
ae13219e 247 if (err != TD_OK)
24a09b5f
DJ
248 error ("Cannot get thread handle for LWP %d: %s",
249 lwpid, thread_db_err_str (err));
ae13219e
DJ
250
251 err = td_thr_get_info (&th, &ti);
252 if (err != TD_OK)
24a09b5f
DJ
253 error ("Cannot get thread info for LWP %d: %s",
254 lwpid, thread_db_err_str (err));
ae13219e
DJ
255
256 if (debug_threads)
24a09b5f 257 fprintf (stderr, "Found thread %ld (LWP %d)\n",
ae13219e
DJ
258 ti.ti_tid, ti.ti_lid);
259
95954743 260 if (lwpid != ti.ti_lid)
24a09b5f
DJ
261 {
262 warning ("PID mismatch! Expected %ld, got %ld",
95954743 263 (long) lwpid, (long) ti.ti_lid);
24a09b5f
DJ
264 return 0;
265 }
ae13219e 266
24a09b5f 267 if (thread_db_use_events)
0d62e5e8 268 {
ae13219e
DJ
269 err = td_thr_event_enable (&th, 1);
270 if (err != TD_OK)
271 error ("Cannot enable thread event reporting for %d: %s",
272 ti.ti_lid, thread_db_err_str (err));
0d62e5e8 273 }
ae13219e 274
24a09b5f
DJ
275 /* If the new thread ID is zero, a final thread ID will be available
276 later. Do not enable thread debugging yet. */
277 if (ti.ti_tid == 0)
278 return 0;
ae13219e 279
54a0b537
PA
280 lwp->thread_known = 1;
281 lwp->th = th;
ae13219e 282
ae13219e
DJ
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;
54a0b537 290 struct lwp_info *lwp;
ae13219e 291
95954743
PA
292 lwp = find_lwp_pid (pid_to_ptid (ti_p->ti_lid));
293 if (lwp != NULL)
0d62e5e8
DJ
294 return;
295
296 if (debug_threads)
297 fprintf (stderr, "Attaching to thread %ld (LWP %d)\n",
298 ti_p->ti_tid, ti_p->ti_lid);
24a09b5f 299 linux_attach_lwp (ti_p->ti_lid);
95954743
PA
300 lwp = find_lwp_pid (pid_to_ptid (ti_p->ti_lid));
301 if (lwp == NULL)
0d62e5e8
DJ
302 {
303 warning ("Could not attach to thread %ld (LWP %d)\n",
304 ti_p->ti_tid, ti_p->ti_lid);
305 return;
306 }
307
54a0b537
PA
308 lwp->thread_known = 1;
309 lwp->th = *th_p;
24a09b5f
DJ
310
311 if (thread_db_use_events)
312 {
313 err = td_thr_event_enable (th_p, 1);
314 if (err != TD_OK)
315 error ("Cannot enable thread event reporting for %d: %s",
316 ti_p->ti_lid, thread_db_err_str (err));
317 }
0d62e5e8
DJ
318}
319
320static int
321find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
322{
323 td_thrinfo_t ti;
324 td_err_e err;
325
326 err = td_thr_get_info (th_p, &ti);
327 if (err != TD_OK)
328 error ("Cannot get thread info: %s", thread_db_err_str (err));
329
330 /* Check for zombies. */
331 if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
332 return 0;
333
334 maybe_attach_thread (th_p, &ti);
335
336 return 0;
337}
338
339static void
340thread_db_find_new_threads (void)
341{
342 td_err_e err;
95954743
PA
343 ptid_t ptid = ((struct inferior_list_entry *) current_inferior)->id;
344 struct process_info_private *proc = current_process()->private;
0d62e5e8 345
ae13219e
DJ
346 /* This function is only called when we first initialize thread_db.
347 First locate the initial thread. If it is not ready for
348 debugging yet, then stop. */
95954743 349 if (find_one_thread (ptid) == 0)
ae13219e
DJ
350 return;
351
0d62e5e8 352 /* Iterate over all user-space threads to discover new threads. */
95954743
PA
353 err = td_ta_thr_iter (proc->thread_agent,
354 find_new_threads_callback, NULL,
0d62e5e8
DJ
355 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
356 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
357 if (err != TD_OK)
358 error ("Cannot find new threads: %s", thread_db_err_str (err));
359}
360
fd500816
DJ
361/* Cache all future symbols that thread_db might request. We can not
362 request symbols at arbitrary states in the remote protocol, only
363 when the client tells us that new symbols are available. So when
364 we load the thread library, make sure to check the entire list. */
365
366static void
367thread_db_look_up_symbols (void)
368{
369 const char **sym_list = td_symbol_list ();
370 CORE_ADDR unused;
371
372 for (sym_list = td_symbol_list (); *sym_list; sym_list++)
373 look_up_one_symbol (*sym_list, &unused);
374}
375
dae5f5cf
DJ
376int
377thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
378 CORE_ADDR load_module, CORE_ADDR *address)
379{
380#if HAVE_TD_THR_TLS_GET_ADDR
381 psaddr_t addr;
382 td_err_e err;
54a0b537 383 struct lwp_info *lwp;
95954743 384 struct thread_info *saved_inferior;
dae5f5cf 385
7fe519cb
UW
386 /* If the thread layer is not (yet) initialized, fail. */
387 if (!get_thread_process (thread)->all_symbols_looked_up)
388 return TD_ERR;
389
54a0b537
PA
390 lwp = get_thread_lwp (thread);
391 if (!lwp->thread_known)
95954743 392 find_one_thread (lwp->head.id);
54a0b537 393 if (!lwp->thread_known)
dae5f5cf
DJ
394 return TD_NOTHR;
395
95954743
PA
396 saved_inferior = current_inferior;
397 current_inferior = thread;
186947f7
DJ
398 /* Note the cast through uintptr_t: this interface only works if
399 a target address fits in a psaddr_t, which is a host pointer.
400 So a 32-bit debugger can not access 64-bit TLS through this. */
54a0b537 401 err = td_thr_tls_get_addr (&lwp->th, (psaddr_t) (uintptr_t) load_module,
186947f7 402 offset, &addr);
95954743 403 current_inferior = saved_inferior;
dae5f5cf
DJ
404 if (err == TD_OK)
405 {
186947f7 406 *address = (CORE_ADDR) (uintptr_t) addr;
dae5f5cf
DJ
407 return 0;
408 }
409 else
410 return err;
411#else
412 return -1;
413#endif
414}
415
0d62e5e8 416int
24a09b5f 417thread_db_init (int use_events)
0d62e5e8
DJ
418{
419 int err;
95954743
PA
420 struct process_info *proc = current_process ();
421 struct process_info_private *priv = proc->private;
0d62e5e8 422
fd500816
DJ
423 /* FIXME drow/2004-10-16: This is the "overall process ID", which
424 GNU/Linux calls tgid, "thread group ID". When we support
425 attaching to threads, the original thread may not be the correct
426 thread. We would have to get the process ID from /proc for NPTL.
427 For LinuxThreads we could do something similar: follow the chain
428 of parent processes until we find the highest one we're attached
429 to, and use its tgid.
430
431 This isn't the only place in gdbserver that assumes that the first
432 process in the list is the thread group leader. */
ea025f5f 433
24a09b5f
DJ
434 thread_db_use_events = use_events;
435
95954743 436 err = td_ta_new (&priv->proc_handle, &priv->thread_agent);
0d62e5e8
DJ
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 ();
95954743 450 proc->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.692244 seconds and 4 git commands to generate.