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