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