Add a target_ops parameter to the to_kill method in struct target_ops.
[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
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
54363045 48static const char *
0d62e5e8
DJ
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
DJ
282 process->thread_known = 1;
283 process->th = th;
284
ae13219e
DJ
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 295 inferior = (struct thread_info *) find_inferior_id (&all_threads,
24a09b5f 296 ti_p->ti_lid);
0d62e5e8
DJ
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);
24a09b5f 303 linux_attach_lwp (ti_p->ti_lid);
0d62e5e8 304 inferior = (struct thread_info *) find_inferior_id (&all_threads,
24a09b5f 305 ti_p->ti_lid);
0d62e5e8
DJ
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 315 process->thread_known = 1;
dae5f5cf 316 process->th = *th_p;
24a09b5f
DJ
317
318 if (thread_db_use_events)
319 {
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 }
0d62e5e8
DJ
325}
326
327static int
328find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
329{
330 td_thrinfo_t ti;
331 td_err_e err;
332
333 err = td_thr_get_info (th_p, &ti);
334 if (err != TD_OK)
335 error ("Cannot get thread info: %s", thread_db_err_str (err));
336
337 /* Check for zombies. */
338 if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
339 return 0;
340
341 maybe_attach_thread (th_p, &ti);
342
343 return 0;
344}
345
346static void
347thread_db_find_new_threads (void)
348{
349 td_err_e err;
350
ae13219e
DJ
351 /* This function is only called when we first initialize thread_db.
352 First locate the initial thread. If it is not ready for
353 debugging yet, then stop. */
24a09b5f 354 if (find_one_thread (all_threads.head->id) == 0)
ae13219e
DJ
355 return;
356
0d62e5e8
DJ
357 /* Iterate over all user-space threads to discover new threads. */
358 err = td_ta_thr_iter (thread_agent, find_new_threads_callback, NULL,
359 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
360 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
361 if (err != TD_OK)
362 error ("Cannot find new threads: %s", thread_db_err_str (err));
363}
364
fd500816
DJ
365/* Cache all future symbols that thread_db might request. We can not
366 request symbols at arbitrary states in the remote protocol, only
367 when the client tells us that new symbols are available. So when
368 we load the thread library, make sure to check the entire list. */
369
370static void
371thread_db_look_up_symbols (void)
372{
373 const char **sym_list = td_symbol_list ();
374 CORE_ADDR unused;
375
376 for (sym_list = td_symbol_list (); *sym_list; sym_list++)
377 look_up_one_symbol (*sym_list, &unused);
378}
379
dae5f5cf
DJ
380int
381thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
382 CORE_ADDR load_module, CORE_ADDR *address)
383{
384#if HAVE_TD_THR_TLS_GET_ADDR
385 psaddr_t addr;
386 td_err_e err;
387 struct process_info *process;
388
389 process = get_thread_process (thread);
4105de34 390 if (!process->thread_known)
24a09b5f 391 find_one_thread (process->lwpid);
dae5f5cf
DJ
392 if (!process->thread_known)
393 return TD_NOTHR;
394
186947f7
DJ
395 /* Note the cast through uintptr_t: this interface only works if
396 a target address fits in a psaddr_t, which is a host pointer.
397 So a 32-bit debugger can not access 64-bit TLS through this. */
398 err = td_thr_tls_get_addr (&process->th, (psaddr_t) (uintptr_t) load_module,
399 offset, &addr);
dae5f5cf
DJ
400 if (err == TD_OK)
401 {
186947f7 402 *address = (CORE_ADDR) (uintptr_t) addr;
dae5f5cf
DJ
403 return 0;
404 }
405 else
406 return err;
407#else
408 return -1;
409#endif
410}
411
0d62e5e8 412int
24a09b5f 413thread_db_init (int use_events)
0d62e5e8
DJ
414{
415 int err;
416
fd500816
DJ
417 /* FIXME drow/2004-10-16: This is the "overall process ID", which
418 GNU/Linux calls tgid, "thread group ID". When we support
419 attaching to threads, the original thread may not be the correct
420 thread. We would have to get the process ID from /proc for NPTL.
421 For LinuxThreads we could do something similar: follow the chain
422 of parent processes until we find the highest one we're attached
423 to, and use its tgid.
424
425 This isn't the only place in gdbserver that assumes that the first
426 process in the list is the thread group leader. */
0d62e5e8
DJ
427 proc_handle.pid = ((struct inferior_list_entry *)current_inferior)->id;
428
ea025f5f
DJ
429 /* Allow new symbol lookups. */
430 all_symbols_looked_up = 0;
431
24a09b5f
DJ
432 thread_db_use_events = use_events;
433
0d62e5e8
DJ
434 err = td_ta_new (&proc_handle, &thread_agent);
435 switch (err)
436 {
437 case TD_NOLIBTHREAD:
438 /* No thread library was detected. */
439 return 0;
440
441 case TD_OK:
442 /* The thread library was detected. */
443
24a09b5f 444 if (use_events && thread_db_enable_reporting () == 0)
0d62e5e8
DJ
445 return 0;
446 thread_db_find_new_threads ();
fd500816 447 thread_db_look_up_symbols ();
ea025f5f 448 all_symbols_looked_up = 1;
0d62e5e8
DJ
449 return 1;
450
451 default:
3db0444b
DJ
452 warning ("error initializing thread_db library: %s",
453 thread_db_err_str (err));
0d62e5e8
DJ
454 }
455
456 return 0;
457}
This page took 0.490295 seconds and 4 git commands to generate.