1b725ae77Skettenis /* Thread management interface, for the remote server for GDB.
2b725ae77Skettenis Copyright 2002
3b725ae77Skettenis Free Software Foundation, Inc.
4b725ae77Skettenis
5b725ae77Skettenis Contributed by MontaVista Software.
6b725ae77Skettenis
7b725ae77Skettenis This file is part of GDB.
8b725ae77Skettenis
9b725ae77Skettenis This program is free software; you can redistribute it and/or modify
10b725ae77Skettenis it under the terms of the GNU General Public License as published by
11b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
12b725ae77Skettenis (at your option) any later version.
13b725ae77Skettenis
14b725ae77Skettenis This program is distributed in the hope that it will be useful,
15b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
16b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17b725ae77Skettenis GNU General Public License for more details.
18b725ae77Skettenis
19b725ae77Skettenis You should have received a copy of the GNU General Public License
20b725ae77Skettenis along with this program; if not, write to the Free Software
21b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
22b725ae77Skettenis Boston, MA 02111-1307, USA. */
23b725ae77Skettenis
24b725ae77Skettenis #include "server.h"
25b725ae77Skettenis
26b725ae77Skettenis #include "linux-low.h"
27b725ae77Skettenis
28b725ae77Skettenis extern int debug_threads;
29b725ae77Skettenis
30b725ae77Skettenis #ifdef HAVE_THREAD_DB_H
31b725ae77Skettenis #include <thread_db.h>
32b725ae77Skettenis #endif
33b725ae77Skettenis
34b725ae77Skettenis /* Correct for all GNU/Linux targets (for quite some time). */
35b725ae77Skettenis #define GDB_GREGSET_T elf_gregset_t
36b725ae77Skettenis #define GDB_FPREGSET_T elf_fpregset_t
37b725ae77Skettenis
38b725ae77Skettenis #ifndef HAVE_ELF_FPREGSET_T
39b725ae77Skettenis /* Make sure we have said types. Not all platforms bring in <linux/elf.h>
40b725ae77Skettenis via <sys/procfs.h>. */
41b725ae77Skettenis #ifdef HAVE_LINUX_ELF_H
42b725ae77Skettenis #include <linux/elf.h>
43b725ae77Skettenis #endif
44b725ae77Skettenis #endif
45b725ae77Skettenis
46b725ae77Skettenis #include "../gdb_proc_service.h"
47b725ae77Skettenis
48b725ae77Skettenis /* Structure that identifies the child process for the
49b725ae77Skettenis <proc_service.h> interface. */
50b725ae77Skettenis static struct ps_prochandle proc_handle;
51b725ae77Skettenis
52b725ae77Skettenis /* Connection to the libthread_db library. */
53b725ae77Skettenis static td_thragent_t *thread_agent;
54b725ae77Skettenis
55b725ae77Skettenis static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data);
56b725ae77Skettenis
57b725ae77Skettenis static char *
thread_db_err_str(td_err_e err)58b725ae77Skettenis thread_db_err_str (td_err_e err)
59b725ae77Skettenis {
60b725ae77Skettenis static char buf[64];
61b725ae77Skettenis
62b725ae77Skettenis switch (err)
63b725ae77Skettenis {
64b725ae77Skettenis case TD_OK:
65b725ae77Skettenis return "generic 'call succeeded'";
66b725ae77Skettenis case TD_ERR:
67b725ae77Skettenis return "generic error";
68b725ae77Skettenis case TD_NOTHR:
69b725ae77Skettenis return "no thread to satisfy query";
70b725ae77Skettenis case TD_NOSV:
71b725ae77Skettenis return "no sync handle to satisfy query";
72b725ae77Skettenis case TD_NOLWP:
73b725ae77Skettenis return "no LWP to satisfy query";
74b725ae77Skettenis case TD_BADPH:
75b725ae77Skettenis return "invalid process handle";
76b725ae77Skettenis case TD_BADTH:
77b725ae77Skettenis return "invalid thread handle";
78b725ae77Skettenis case TD_BADSH:
79b725ae77Skettenis return "invalid synchronization handle";
80b725ae77Skettenis case TD_BADTA:
81b725ae77Skettenis return "invalid thread agent";
82b725ae77Skettenis case TD_BADKEY:
83b725ae77Skettenis return "invalid key";
84b725ae77Skettenis case TD_NOMSG:
85b725ae77Skettenis return "no event message for getmsg";
86b725ae77Skettenis case TD_NOFPREGS:
87b725ae77Skettenis return "FPU register set not available";
88b725ae77Skettenis case TD_NOLIBTHREAD:
89b725ae77Skettenis return "application not linked with libthread";
90b725ae77Skettenis case TD_NOEVENT:
91b725ae77Skettenis return "requested event is not supported";
92b725ae77Skettenis case TD_NOCAPAB:
93b725ae77Skettenis return "capability not available";
94b725ae77Skettenis case TD_DBERR:
95b725ae77Skettenis return "debugger service failed";
96b725ae77Skettenis case TD_NOAPLIC:
97b725ae77Skettenis return "operation not applicable to";
98b725ae77Skettenis case TD_NOTSD:
99b725ae77Skettenis return "no thread-specific data for this thread";
100b725ae77Skettenis case TD_MALLOC:
101b725ae77Skettenis return "malloc failed";
102b725ae77Skettenis case TD_PARTIALREG:
103b725ae77Skettenis return "only part of register set was written/read";
104b725ae77Skettenis case TD_NOXREGS:
105b725ae77Skettenis return "X register set not available for this thread";
106b725ae77Skettenis default:
107b725ae77Skettenis snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
108b725ae77Skettenis return buf;
109b725ae77Skettenis }
110b725ae77Skettenis }
111b725ae77Skettenis
112b725ae77Skettenis #if 0
113b725ae77Skettenis static char *
114b725ae77Skettenis thread_db_state_str (td_thr_state_e state)
115b725ae77Skettenis {
116b725ae77Skettenis static char buf[64];
117b725ae77Skettenis
118b725ae77Skettenis switch (state)
119b725ae77Skettenis {
120b725ae77Skettenis case TD_THR_STOPPED:
121b725ae77Skettenis return "stopped by debugger";
122b725ae77Skettenis case TD_THR_RUN:
123b725ae77Skettenis return "runnable";
124b725ae77Skettenis case TD_THR_ACTIVE:
125b725ae77Skettenis return "active";
126b725ae77Skettenis case TD_THR_ZOMBIE:
127b725ae77Skettenis return "zombie";
128b725ae77Skettenis case TD_THR_SLEEP:
129b725ae77Skettenis return "sleeping";
130b725ae77Skettenis case TD_THR_STOPPED_ASLEEP:
131b725ae77Skettenis return "stopped by debugger AND blocked";
132b725ae77Skettenis default:
133b725ae77Skettenis snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
134b725ae77Skettenis return buf;
135b725ae77Skettenis }
136b725ae77Skettenis }
137b725ae77Skettenis #endif
138b725ae77Skettenis
139b725ae77Skettenis static void
thread_db_create_event(CORE_ADDR where)140b725ae77Skettenis thread_db_create_event (CORE_ADDR where)
141b725ae77Skettenis {
142b725ae77Skettenis td_event_msg_t msg;
143b725ae77Skettenis td_err_e err;
144b725ae77Skettenis struct inferior_linux_data *tdata;
145b725ae77Skettenis
146b725ae77Skettenis if (debug_threads)
147b725ae77Skettenis fprintf (stderr, "Thread creation event.\n");
148b725ae77Skettenis
149b725ae77Skettenis tdata = inferior_target_data (current_inferior);
150b725ae77Skettenis
151b725ae77Skettenis /* FIXME: This assumes we don't get another event.
152b725ae77Skettenis In the LinuxThreads implementation, this is safe,
153b725ae77Skettenis because all events come from the manager thread
154b725ae77Skettenis (except for its own creation, of course). */
155b725ae77Skettenis err = td_ta_event_getmsg (thread_agent, &msg);
156b725ae77Skettenis if (err != TD_OK)
157b725ae77Skettenis fprintf (stderr, "thread getmsg err: %s\n",
158b725ae77Skettenis thread_db_err_str (err));
159b725ae77Skettenis
160b725ae77Skettenis /* msg.event == TD_EVENT_CREATE */
161b725ae77Skettenis
162b725ae77Skettenis find_new_threads_callback (msg.th_p, NULL);
163b725ae77Skettenis }
164b725ae77Skettenis
165b725ae77Skettenis #if 0
166b725ae77Skettenis static void
167b725ae77Skettenis thread_db_death_event (CORE_ADDR where)
168b725ae77Skettenis {
169b725ae77Skettenis if (debug_threads)
170b725ae77Skettenis fprintf (stderr, "Thread death event.\n");
171b725ae77Skettenis }
172b725ae77Skettenis #endif
173b725ae77Skettenis
174b725ae77Skettenis static int
thread_db_enable_reporting()175b725ae77Skettenis thread_db_enable_reporting ()
176b725ae77Skettenis {
177b725ae77Skettenis td_thr_events_t events;
178b725ae77Skettenis td_notify_t notify;
179b725ae77Skettenis td_err_e err;
180b725ae77Skettenis
181b725ae77Skettenis /* Set the process wide mask saying which events we're interested in. */
182b725ae77Skettenis td_event_emptyset (&events);
183b725ae77Skettenis td_event_addset (&events, TD_CREATE);
184b725ae77Skettenis
185b725ae77Skettenis #if 0
186b725ae77Skettenis /* This is reported to be broken in glibc 2.1.3. A different approach
187b725ae77Skettenis will be necessary to support that. */
188b725ae77Skettenis td_event_addset (&events, TD_DEATH);
189b725ae77Skettenis #endif
190b725ae77Skettenis
191b725ae77Skettenis err = td_ta_set_event (thread_agent, &events);
192b725ae77Skettenis if (err != TD_OK)
193b725ae77Skettenis {
194b725ae77Skettenis warning ("Unable to set global thread event mask: %s",
195b725ae77Skettenis thread_db_err_str (err));
196b725ae77Skettenis return 0;
197b725ae77Skettenis }
198b725ae77Skettenis
199b725ae77Skettenis /* Get address for thread creation breakpoint. */
200b725ae77Skettenis err = td_ta_event_addr (thread_agent, TD_CREATE, ¬ify);
201b725ae77Skettenis if (err != TD_OK)
202b725ae77Skettenis {
203b725ae77Skettenis warning ("Unable to get location for thread creation breakpoint: %s",
204b725ae77Skettenis thread_db_err_str (err));
205b725ae77Skettenis return 0;
206b725ae77Skettenis }
207b725ae77Skettenis set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr,
208b725ae77Skettenis thread_db_create_event);
209b725ae77Skettenis
210b725ae77Skettenis #if 0
211b725ae77Skettenis /* Don't concern ourselves with reported thread deaths, only
212b725ae77Skettenis with actual thread deaths (via wait). */
213b725ae77Skettenis
214b725ae77Skettenis /* Get address for thread death breakpoint. */
215b725ae77Skettenis err = td_ta_event_addr (thread_agent, TD_DEATH, ¬ify);
216b725ae77Skettenis if (err != TD_OK)
217b725ae77Skettenis {
218b725ae77Skettenis warning ("Unable to get location for thread death breakpoint: %s",
219b725ae77Skettenis thread_db_err_str (err));
220b725ae77Skettenis return;
221b725ae77Skettenis }
222b725ae77Skettenis set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr,
223b725ae77Skettenis thread_db_death_event);
224b725ae77Skettenis #endif
225b725ae77Skettenis
226b725ae77Skettenis return 1;
227b725ae77Skettenis }
228b725ae77Skettenis
229b725ae77Skettenis static void
maybe_attach_thread(const td_thrhandle_t * th_p,td_thrinfo_t * ti_p)230b725ae77Skettenis maybe_attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
231b725ae77Skettenis {
232b725ae77Skettenis td_err_e err;
233b725ae77Skettenis struct thread_info *inferior;
234b725ae77Skettenis struct process_info *process;
235b725ae77Skettenis
236b725ae77Skettenis /* If we are attaching to our first thread, things are a little
237b725ae77Skettenis different. */
238b725ae77Skettenis if (all_threads.head == all_threads.tail)
239b725ae77Skettenis {
240b725ae77Skettenis inferior = (struct thread_info *) all_threads.head;
241b725ae77Skettenis process = get_thread_process (inferior);
242b725ae77Skettenis if (process->thread_known == 0)
243b725ae77Skettenis {
244b725ae77Skettenis /* Switch to indexing the threads list by TID. */
245b725ae77Skettenis change_inferior_id (&all_threads, ti_p->ti_tid);
246b725ae77Skettenis goto found;
247b725ae77Skettenis }
248b725ae77Skettenis }
249b725ae77Skettenis
250b725ae77Skettenis inferior = (struct thread_info *) find_inferior_id (&all_threads,
251b725ae77Skettenis ti_p->ti_tid);
252b725ae77Skettenis if (inferior != NULL)
253b725ae77Skettenis return;
254b725ae77Skettenis
255b725ae77Skettenis if (debug_threads)
256b725ae77Skettenis fprintf (stderr, "Attaching to thread %ld (LWP %d)\n",
257b725ae77Skettenis ti_p->ti_tid, ti_p->ti_lid);
258b725ae77Skettenis linux_attach_lwp (ti_p->ti_lid, ti_p->ti_tid);
259b725ae77Skettenis inferior = (struct thread_info *) find_inferior_id (&all_threads,
260b725ae77Skettenis ti_p->ti_tid);
261b725ae77Skettenis if (inferior == NULL)
262b725ae77Skettenis {
263b725ae77Skettenis warning ("Could not attach to thread %ld (LWP %d)\n",
264b725ae77Skettenis ti_p->ti_tid, ti_p->ti_lid);
265b725ae77Skettenis return;
266b725ae77Skettenis }
267b725ae77Skettenis
268b725ae77Skettenis process = inferior_target_data (inferior);
269b725ae77Skettenis
270b725ae77Skettenis found:
271b725ae77Skettenis new_thread_notify (ti_p->ti_tid);
272b725ae77Skettenis
273b725ae77Skettenis process->tid = ti_p->ti_tid;
274b725ae77Skettenis process->lwpid = ti_p->ti_lid;
275b725ae77Skettenis
276b725ae77Skettenis process->thread_known = 1;
277b725ae77Skettenis err = td_thr_event_enable (th_p, 1);
278b725ae77Skettenis if (err != TD_OK)
279b725ae77Skettenis error ("Cannot enable thread event reporting for %d: %s",
280b725ae77Skettenis ti_p->ti_lid, thread_db_err_str (err));
281b725ae77Skettenis }
282b725ae77Skettenis
283b725ae77Skettenis static int
find_new_threads_callback(const td_thrhandle_t * th_p,void * data)284b725ae77Skettenis find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
285b725ae77Skettenis {
286b725ae77Skettenis td_thrinfo_t ti;
287b725ae77Skettenis td_err_e err;
288b725ae77Skettenis
289b725ae77Skettenis err = td_thr_get_info (th_p, &ti);
290b725ae77Skettenis if (err != TD_OK)
291b725ae77Skettenis error ("Cannot get thread info: %s", thread_db_err_str (err));
292b725ae77Skettenis
293b725ae77Skettenis /* Check for zombies. */
294b725ae77Skettenis if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
295b725ae77Skettenis return 0;
296b725ae77Skettenis
297b725ae77Skettenis maybe_attach_thread (th_p, &ti);
298b725ae77Skettenis
299b725ae77Skettenis return 0;
300b725ae77Skettenis }
301b725ae77Skettenis
302b725ae77Skettenis static void
thread_db_find_new_threads(void)303b725ae77Skettenis thread_db_find_new_threads (void)
304b725ae77Skettenis {
305b725ae77Skettenis td_err_e err;
306b725ae77Skettenis
307b725ae77Skettenis /* Iterate over all user-space threads to discover new threads. */
308b725ae77Skettenis err = td_ta_thr_iter (thread_agent, find_new_threads_callback, NULL,
309b725ae77Skettenis TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
310b725ae77Skettenis TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
311b725ae77Skettenis if (err != TD_OK)
312b725ae77Skettenis error ("Cannot find new threads: %s", thread_db_err_str (err));
313b725ae77Skettenis }
314b725ae77Skettenis
315*11efff7fSkettenis /* Cache all future symbols that thread_db might request. We can not
316*11efff7fSkettenis request symbols at arbitrary states in the remote protocol, only
317*11efff7fSkettenis when the client tells us that new symbols are available. So when
318*11efff7fSkettenis we load the thread library, make sure to check the entire list. */
319*11efff7fSkettenis
320*11efff7fSkettenis static void
thread_db_look_up_symbols(void)321*11efff7fSkettenis thread_db_look_up_symbols (void)
322*11efff7fSkettenis {
323*11efff7fSkettenis const char **sym_list = td_symbol_list ();
324*11efff7fSkettenis CORE_ADDR unused;
325*11efff7fSkettenis
326*11efff7fSkettenis for (sym_list = td_symbol_list (); *sym_list; sym_list++)
327*11efff7fSkettenis look_up_one_symbol (*sym_list, &unused);
328*11efff7fSkettenis }
329*11efff7fSkettenis
330b725ae77Skettenis int
thread_db_init()331b725ae77Skettenis thread_db_init ()
332b725ae77Skettenis {
333b725ae77Skettenis int err;
334b725ae77Skettenis
335*11efff7fSkettenis /* FIXME drow/2004-10-16: This is the "overall process ID", which
336*11efff7fSkettenis GNU/Linux calls tgid, "thread group ID". When we support
337*11efff7fSkettenis attaching to threads, the original thread may not be the correct
338*11efff7fSkettenis thread. We would have to get the process ID from /proc for NPTL.
339*11efff7fSkettenis For LinuxThreads we could do something similar: follow the chain
340*11efff7fSkettenis of parent processes until we find the highest one we're attached
341*11efff7fSkettenis to, and use its tgid.
342*11efff7fSkettenis
343*11efff7fSkettenis This isn't the only place in gdbserver that assumes that the first
344*11efff7fSkettenis process in the list is the thread group leader. */
345b725ae77Skettenis proc_handle.pid = ((struct inferior_list_entry *)current_inferior)->id;
346b725ae77Skettenis
347b725ae77Skettenis err = td_ta_new (&proc_handle, &thread_agent);
348b725ae77Skettenis switch (err)
349b725ae77Skettenis {
350b725ae77Skettenis case TD_NOLIBTHREAD:
351b725ae77Skettenis /* No thread library was detected. */
352b725ae77Skettenis return 0;
353b725ae77Skettenis
354b725ae77Skettenis case TD_OK:
355b725ae77Skettenis /* The thread library was detected. */
356b725ae77Skettenis
357b725ae77Skettenis if (thread_db_enable_reporting () == 0)
358b725ae77Skettenis return 0;
359b725ae77Skettenis thread_db_find_new_threads ();
360*11efff7fSkettenis thread_db_look_up_symbols ();
361b725ae77Skettenis return 1;
362b725ae77Skettenis
363b725ae77Skettenis default:
364b725ae77Skettenis warning ("error initializing thread_db library.");
365b725ae77Skettenis }
366b725ae77Skettenis
367b725ae77Skettenis return 0;
368b725ae77Skettenis }
369