* lin-lwp.c, thread-db.c, defs.h, cris-tdep.c: Replace ``Linux''
[deliverable/binutils-gdb.git] / gdb / thread-db.c
CommitLineData
fb0e1ba7 1/* libthread_db assisted debugging support, generic parts.
4e052eda 2 Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
fb0e1ba7
MK
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21#include "defs.h"
22
23#include "gdb_assert.h"
24#include <dlfcn.h>
25#include "gdb_proc_service.h"
26#include "gdb_thread_db.h"
27
bda9cb72 28#include "bfd.h"
fb0e1ba7
MK
29#include "gdbthread.h"
30#include "inferior.h"
bda9cb72
MK
31#include "symfile.h"
32#include "objfiles.h"
fb0e1ba7 33#include "target.h"
4e052eda 34#include "regcache.h"
fb0e1ba7
MK
35
36#ifndef LIBTHREAD_DB_SO
37#define LIBTHREAD_DB_SO "libthread_db.so.1"
38#endif
39
8605d56e
AC
40/* If we're running on GNU/Linux, we must explicitly attach to any new
41 threads. */
fb0e1ba7
MK
42
43/* FIXME: There is certainly some room for improvements:
44 - Cache LWP ids.
45 - Bypass libthread_db when fetching or storing registers for
46 threads bound to a LWP. */
47
48/* This module's target vector. */
49static struct target_ops thread_db_ops;
50
51/* The target vector that we call for things this module can't handle. */
52static struct target_ops *target_beneath;
53
54/* Pointer to the next function on the objfile event chain. */
540af400 55static void (*target_new_objfile_chain) (struct objfile *objfile);
fb0e1ba7
MK
56
57/* Non-zero if we're using this module's target vector. */
58static int using_thread_db;
59
c194fbe1
MK
60/* Non-zero if we have to keep this module's target vector active
61 across re-runs. */
bda9cb72
MK
62static int keep_thread_db;
63
fb0e1ba7
MK
64/* Non-zero if we have determined the signals used by the threads
65 library. */
66static int thread_signals;
67static sigset_t thread_stop_set;
68static sigset_t thread_print_set;
69
70/* Structure that identifies the child process for the
71 <proc_service.h> interface. */
72static struct ps_prochandle proc_handle;
73
74/* Connection to the libthread_db library. */
75static td_thragent_t *thread_agent;
76
77/* Pointers to the libthread_db functions. */
78
79static td_err_e (*td_init_p) (void);
80
81static td_err_e (*td_ta_new_p) (struct ps_prochandle *ps, td_thragent_t **ta);
82static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
83 td_thrhandle_t *__th);
84static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta, lwpid_t lwpid,
85 td_thrhandle_t *th);
86static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
87 td_thr_iter_f *callback,
88 void *cbdata_p, td_thr_state_e state,
89 int ti_pri, sigset_t *ti_sigmask_p,
90 unsigned int ti_user_flags);
91static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
92 td_event_e event, td_notify_t *ptr);
93static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
94 td_thr_events_t *event);
95static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
96 td_event_msg_t *msg);
97
98static td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
99static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
100 td_thrinfo_t *infop);
101static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
102 gdb_prfpregset_t *regset);
103static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
104 prgregset_t gregs);
105static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
106 const gdb_prfpregset_t *fpregs);
107static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
108 prgregset_t gregs);
109static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event);
110
111/* Location of the thread creation event breakpoint. The code at this
112 location in the child process will be called by the pthread library
113 whenever a new thread is created. By setting a special breakpoint
114 at this location, GDB can detect when a new thread is created. We
115 obtain this location via the td_ta_event_addr call. */
116static CORE_ADDR td_create_bp_addr;
117
118/* Location of the thread death event breakpoint. */
119static CORE_ADDR td_death_bp_addr;
120
121/* Prototypes for local functions. */
bda9cb72 122static void thread_db_find_new_threads (void);
fb0e1ba7
MK
123\f
124
125/* Building process ids. */
126
ca6724c1
KB
127#define GET_PID(ptid) ptid_get_pid (ptid)
128#define GET_LWP(ptid) ptid_get_lwp (ptid)
129#define GET_THREAD(ptid) ptid_get_tid (ptid)
fb0e1ba7 130
ca6724c1
KB
131#define is_lwp(ptid) (GET_LWP (ptid) != 0)
132#define is_thread(ptid) (GET_THREAD (ptid) != 0)
fb0e1ba7 133
ca6724c1
KB
134#define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
135#define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
fb0e1ba7
MK
136\f
137
138struct private_thread_info
139{
140 /* Cached LWP id. Must come first, see lin-lwp.c. */
141 lwpid_t lwpid;
142};
fb0e1ba7 143\f
21bf60fe 144
fb0e1ba7
MK
145static char *
146thread_db_err_str (td_err_e err)
147{
148 static char buf[64];
149
150 switch (err)
151 {
152 case TD_OK:
153 return "generic 'call succeeded'";
154 case TD_ERR:
155 return "generic error";
156 case TD_NOTHR:
157 return "no thread to satisfy query";
158 case TD_NOSV:
159 return "no sync handle to satisfy query";
160 case TD_NOLWP:
161 return "no LWP to satisfy query";
162 case TD_BADPH:
163 return "invalid process handle";
164 case TD_BADTH:
165 return "invalid thread handle";
166 case TD_BADSH:
167 return "invalid synchronization handle";
168 case TD_BADTA:
169 return "invalid thread agent";
170 case TD_BADKEY:
171 return "invalid key";
172 case TD_NOMSG:
173 return "no event message for getmsg";
174 case TD_NOFPREGS:
175 return "FPU register set not available";
176 case TD_NOLIBTHREAD:
177 return "application not linked with libthread";
178 case TD_NOEVENT:
179 return "requested event is not supported";
180 case TD_NOCAPAB:
181 return "capability not available";
182 case TD_DBERR:
183 return "debugger service failed";
184 case TD_NOAPLIC:
185 return "operation not applicable to";
186 case TD_NOTSD:
187 return "no thread-specific data for this thread";
188 case TD_MALLOC:
189 return "malloc failed";
190 case TD_PARTIALREG:
191 return "only part of register set was written/read";
192 case TD_NOXREGS:
193 return "X register set not available for this thread";
194 default:
195 snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
196 return buf;
197 }
198}
199
200static char *
201thread_db_state_str (td_thr_state_e state)
202{
203 static char buf[64];
204
205 switch (state)
206 {
207 case TD_THR_STOPPED:
208 return "stopped by debugger";
209 case TD_THR_RUN:
210 return "runnable";
211 case TD_THR_ACTIVE:
212 return "active";
213 case TD_THR_ZOMBIE:
214 return "zombie";
215 case TD_THR_SLEEP:
216 return "sleeping";
217 case TD_THR_STOPPED_ASLEEP:
218 return "stopped by debugger AND blocked";
219 default:
220 snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
221 return buf;
222 }
223}
224\f
225
226/* Convert between user-level thread ids and LWP ids. */
227
39f77062
KB
228static ptid_t
229thread_from_lwp (ptid_t ptid)
fb0e1ba7
MK
230{
231 td_thrinfo_t ti;
232 td_thrhandle_t th;
233 td_err_e err;
234
39f77062
KB
235 if (GET_LWP (ptid) == 0)
236 ptid = BUILD_LWP (GET_PID (ptid), GET_PID (ptid));
fb0e1ba7 237
39f77062 238 gdb_assert (is_lwp (ptid));
fb0e1ba7 239
39f77062 240 err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
fb0e1ba7
MK
241 if (err != TD_OK)
242 error ("Cannot find user-level thread for LWP %d: %s",
39f77062 243 GET_LWP (ptid), thread_db_err_str (err));
fb0e1ba7
MK
244
245 err = td_thr_get_info_p (&th, &ti);
246 if (err != TD_OK)
247 error ("Cannot get thread info: %s", thread_db_err_str (err));
248
39f77062 249 return BUILD_THREAD (ti.ti_tid, GET_PID (ptid));
fb0e1ba7
MK
250}
251
39f77062
KB
252static ptid_t
253lwp_from_thread (ptid_t ptid)
fb0e1ba7
MK
254{
255 td_thrinfo_t ti;
256 td_thrhandle_t th;
257 td_err_e err;
258
21bf60fe 259 if (!is_thread (ptid))
39f77062 260 return ptid;
fb0e1ba7 261
39f77062 262 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
fb0e1ba7
MK
263 if (err != TD_OK)
264 error ("Cannot find thread %ld: %s",
39f77062 265 (long) GET_THREAD (ptid), thread_db_err_str (err));
fb0e1ba7
MK
266
267 err = td_thr_get_info_p (&th, &ti);
268 if (err != TD_OK)
269 error ("Cannot get thread info: %s", thread_db_err_str (err));
270
39f77062 271 return BUILD_LWP (ti.ti_lid, GET_PID (ptid));
fb0e1ba7
MK
272}
273\f
274
275void
276thread_db_init (struct target_ops *target)
277{
278 target_beneath = target;
279}
280
281static int
282thread_db_load (void)
283{
284 void *handle;
285 td_err_e err;
286
287 handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
288 if (handle == NULL)
289 return 0;
290
291 /* Initialize pointers to the dynamic library functions we will use.
292 Essential functions first. */
293
294 td_init_p = dlsym (handle, "td_init");
295 if (td_init_p == NULL)
296 return 0;
297
298 td_ta_new_p = dlsym (handle, "td_ta_new");
299 if (td_ta_new_p == NULL)
300 return 0;
301
302 td_ta_map_id2thr_p = dlsym (handle, "td_ta_map_id2thr");
303 if (td_ta_map_id2thr_p == NULL)
304 return 0;
305
306 td_ta_map_lwp2thr_p = dlsym (handle, "td_ta_map_lwp2thr");
307 if (td_ta_map_lwp2thr_p == NULL)
308 return 0;
309
310 td_ta_thr_iter_p = dlsym (handle, "td_ta_thr_iter");
311 if (td_ta_thr_iter_p == NULL)
312 return 0;
313
314 td_thr_validate_p = dlsym (handle, "td_thr_validate");
315 if (td_thr_validate_p == NULL)
316 return 0;
317
318 td_thr_get_info_p = dlsym (handle, "td_thr_get_info");
319 if (td_thr_get_info_p == NULL)
320 return 0;
321
322 td_thr_getfpregs_p = dlsym (handle, "td_thr_getfpregs");
323 if (td_thr_getfpregs_p == NULL)
324 return 0;
325
326 td_thr_getgregs_p = dlsym (handle, "td_thr_getgregs");
327 if (td_thr_getgregs_p == NULL)
328 return 0;
329
330 td_thr_setfpregs_p = dlsym (handle, "td_thr_setfpregs");
331 if (td_thr_setfpregs_p == NULL)
332 return 0;
333
334 td_thr_setgregs_p = dlsym (handle, "td_thr_setgregs");
335 if (td_thr_setgregs_p == NULL)
336 return 0;
337
338 /* Initialize the library. */
339 err = td_init_p ();
340 if (err != TD_OK)
341 {
342 warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
343 return 0;
344 }
345
346 /* These are not essential. */
347 td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
348 td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
349 td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
350 td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
351
352 return 1;
353}
354
355static void
356enable_thread_event_reporting (void)
357{
358 td_thr_events_t events;
359 td_notify_t notify;
360 td_err_e err;
361
362 /* We cannot use the thread event reporting facility if these
363 functions aren't available. */
364 if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
365 || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
366 return;
367
368 /* Set the process wide mask saying which events we're interested in. */
369 td_event_emptyset (&events);
370 td_event_addset (&events, TD_CREATE);
371#if 0
372 /* FIXME: kettenis/2000-04-23: The event reporting facility is
373 broken for TD_DEATH events in glibc 2.1.3, so don't enable it for
374 now. */
375 td_event_addset (&events, TD_DEATH);
376#endif
377
378 err = td_ta_set_event_p (thread_agent, &events);
379 if (err != TD_OK)
380 {
381 warning ("Unable to set global thread event mask: %s",
382 thread_db_err_str (err));
383 return;
384 }
385
386 /* Delete previous thread event breakpoints, if any. */
387 remove_thread_event_breakpoints ();
388
389 /* Get address for thread creation breakpoint. */
390 err = td_ta_event_addr_p (thread_agent, TD_CREATE, &notify);
391 if (err != TD_OK)
392 {
393 warning ("Unable to get location for thread creation breakpoint: %s",
394 thread_db_err_str (err));
395 return;
396 }
397
398 /* Set up the breakpoint. */
399 td_create_bp_addr = (CORE_ADDR) notify.u.bptaddr;
400 create_thread_event_breakpoint (td_create_bp_addr);
401
402 /* Get address for thread death breakpoint. */
403 err = td_ta_event_addr_p (thread_agent, TD_DEATH, &notify);
404 if (err != TD_OK)
405 {
936742ab 406 warning ("Unable to get location for thread death breakpoint: %s",
fb0e1ba7
MK
407 thread_db_err_str (err));
408 return;
409 }
410
411 /* Set up the breakpoint. */
412 td_death_bp_addr = (CORE_ADDR) notify.u.bptaddr;
413 create_thread_event_breakpoint (td_death_bp_addr);
414}
415
416static void
417disable_thread_event_reporting (void)
418{
419 td_thr_events_t events;
420
421 /* Set the process wide mask saying we aren't interested in any
422 events anymore. */
423 td_event_emptyset (&events);
424 td_ta_set_event_p (thread_agent, &events);
425
426 /* Delete thread event breakpoints, if any. */
427 remove_thread_event_breakpoints ();
428 td_create_bp_addr = 0;
429 td_death_bp_addr = 0;
430}
431
432static void
433check_thread_signals (void)
434{
435#ifdef GET_THREAD_SIGNALS
21bf60fe 436 if (!thread_signals)
fb0e1ba7
MK
437 {
438 sigset_t mask;
439 int i;
440
441 GET_THREAD_SIGNALS (&mask);
442 sigemptyset (&thread_stop_set);
443 sigemptyset (&thread_print_set);
444
b9569773 445 for (i = 1; i < NSIG; i++)
fb0e1ba7
MK
446 {
447 if (sigismember (&mask, i))
448 {
449 if (signal_stop_update (target_signal_from_host (i), 0))
450 sigaddset (&thread_stop_set, i);
451 if (signal_print_update (target_signal_from_host (i), 0))
452 sigaddset (&thread_print_set, i);
453 thread_signals = 1;
454 }
455 }
456 }
457#endif
458}
459
460static void
461disable_thread_signals (void)
462{
463#ifdef GET_THREAD_SIGNALS
464 if (thread_signals)
465 {
466 int i;
467
b9569773 468 for (i = 1; i < NSIG; i++)
fb0e1ba7
MK
469 {
470 if (sigismember (&thread_stop_set, i))
471 signal_stop_update (target_signal_from_host (i), 1);
472 if (sigismember (&thread_print_set, i))
473 signal_print_update (target_signal_from_host (i), 1);
474 }
475
476 thread_signals = 0;
477 }
478#endif
479}
480
fb0e1ba7
MK
481static void
482thread_db_new_objfile (struct objfile *objfile)
483{
484 td_err_e err;
485
5bbd998e
MS
486 /* Don't attempt to use thread_db on targets which can not run
487 (core files). */
488 if (objfile == NULL || !target_has_execution)
bda9cb72
MK
489 {
490 /* All symbols have been discarded. If the thread_db target is
c194fbe1 491 active, deactivate it now. */
bda9cb72 492 if (using_thread_db)
c194fbe1
MK
493 {
494 gdb_assert (proc_handle.pid == 0);
495 unpush_target (&thread_db_ops);
496 using_thread_db = 0;
497 }
498
499 keep_thread_db = 0;
bda9cb72
MK
500
501 goto quit;
502 }
503
fb0e1ba7
MK
504 if (using_thread_db)
505 /* Nothing to do. The thread library was already detected and the
506 target vector was already activated. */
507 goto quit;
508
bda9cb72
MK
509 /* Initialize the structure that identifies the child process. Note
510 that at this point there is no guarantee that we actually have a
511 child process. */
39f77062 512 proc_handle.pid = GET_PID (inferior_ptid);
fb0e1ba7 513
bda9cb72 514 /* Now attempt to open a connection to the thread library. */
fb0e1ba7
MK
515 err = td_ta_new_p (&proc_handle, &thread_agent);
516 switch (err)
517 {
518 case TD_NOLIBTHREAD:
bda9cb72 519 /* No thread library was detected. */
fb0e1ba7
MK
520 break;
521
522 case TD_OK:
bda9cb72
MK
523 /* The thread library was detected. Activate the thread_db target. */
524 push_target (&thread_db_ops);
525 using_thread_db = 1;
526
527 /* If the thread library was detected in the main symbol file
528 itself, we assume that the program was statically linked
529 against the thread library and well have to keep this
530 module's target vector activated until forever... Well, at
531 least until all symbols have been discarded anyway (see
532 above). */
533 if (objfile == symfile_objfile)
534 {
535 gdb_assert (proc_handle.pid == 0);
536 keep_thread_db = 1;
537 }
538
539 /* We can only poke around if there actually is a child process.
540 If there is no child process alive, postpone the steps below
541 until one has been created. */
542 if (proc_handle.pid != 0)
543 {
544 enable_thread_event_reporting ();
545 thread_db_find_new_threads ();
546 }
fb0e1ba7
MK
547 break;
548
549 default:
550 warning ("Cannot initialize thread debugging library: %s",
551 thread_db_err_str (err));
552 break;
553 }
554
555 quit:
540af400
MS
556 if (target_new_objfile_chain)
557 target_new_objfile_chain (objfile);
fb0e1ba7
MK
558}
559
560static void
39f77062 561attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
fb0e1ba7
MK
562 const td_thrinfo_t *ti_p, int verbose)
563{
564 struct thread_info *tp;
565 td_err_e err;
566
567 check_thread_signals ();
568
569 if (verbose)
39f77062 570 printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid));
fb0e1ba7
MK
571
572 /* Add the thread to GDB's thread list. */
39f77062 573 tp = add_thread (ptid);
fb0e1ba7
MK
574 tp->private = xmalloc (sizeof (struct private_thread_info));
575 tp->private->lwpid = ti_p->ti_lid;
576
21bf60fe
MK
577 if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE)
578 return; /* A zombie thread -- do not attach. */
5fd913cc 579
8605d56e 580 /* Under GNU/Linux, we have to attach to each and every thread. */
fb0e1ba7 581#ifdef ATTACH_LWP
c194fbe1 582 ATTACH_LWP (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)), 0);
fb0e1ba7
MK
583#endif
584
585 /* Enable thread event reporting for this thread. */
586 err = td_thr_event_enable_p (th_p, 1);
587 if (err != TD_OK)
588 error ("Cannot enable thread event reporting for %s: %s",
39f77062 589 target_pid_to_str (ptid), thread_db_err_str (err));
fb0e1ba7
MK
590}
591
c194fbe1
MK
592static void
593thread_db_attach (char *args, int from_tty)
594{
595 target_beneath->to_attach (args, from_tty);
596
597 /* Destroy thread info; it's no longer valid. */
598 init_thread_list ();
599
600 /* The child process is now the actual multi-threaded
601 program. Snatch its process ID... */
602 proc_handle.pid = GET_PID (inferior_ptid);
603
604 /* ...and perform the remaining initialization steps. */
605 enable_thread_event_reporting ();
606 thread_db_find_new_threads();
607}
608
fb0e1ba7 609static void
39f77062 610detach_thread (ptid_t ptid, int verbose)
fb0e1ba7
MK
611{
612 if (verbose)
39f77062 613 printf_unfiltered ("[%s exited]\n", target_pid_to_str (ptid));
fb0e1ba7
MK
614}
615
616static void
617thread_db_detach (char *args, int from_tty)
618{
619 disable_thread_event_reporting ();
c194fbe1
MK
620
621 /* There's no need to save & restore inferior_ptid here, since the
622 inferior is supposed to be survive this function call. */
623 inferior_ptid = lwp_from_thread (inferior_ptid);
624
625 /* Forget about the child's process ID. We shouldn't need it
626 anymore. */
627 proc_handle.pid = 0;
fb0e1ba7
MK
628
629 target_beneath->to_detach (args, from_tty);
630}
631
632static void
39f77062 633thread_db_resume (ptid_t ptid, int step, enum target_signal signo)
fb0e1ba7 634{
39f77062 635 struct cleanup *old_chain = save_inferior_ptid ();
fb0e1ba7 636
39f77062
KB
637 if (GET_PID (ptid) == -1)
638 inferior_ptid = lwp_from_thread (inferior_ptid);
639 else if (is_thread (ptid))
640 ptid = lwp_from_thread (ptid);
fb0e1ba7 641
39f77062 642 target_beneath->to_resume (ptid, step, signo);
fb0e1ba7
MK
643
644 do_cleanups (old_chain);
645}
646
647/* Check if PID is currently stopped at the location of a thread event
648 breakpoint location. If it is, read the event message and act upon
649 the event. */
650
651static void
39f77062 652check_event (ptid_t ptid)
fb0e1ba7
MK
653{
654 td_event_msg_t msg;
655 td_thrinfo_t ti;
656 td_err_e err;
657 CORE_ADDR stop_pc;
658
659 /* Bail out early if we're not at a thread event breakpoint. */
39f77062 660 stop_pc = read_pc_pid (ptid) - DECR_PC_AFTER_BREAK;
fb0e1ba7
MK
661 if (stop_pc != td_create_bp_addr && stop_pc != td_death_bp_addr)
662 return;
663
664 err = td_ta_event_getmsg_p (thread_agent, &msg);
665 if (err != TD_OK)
666 {
667 if (err == TD_NOMSG)
668 return;
669
670 error ("Cannot get thread event message: %s", thread_db_err_str (err));
671 }
672
673 err = td_thr_get_info_p (msg.th_p, &ti);
674 if (err != TD_OK)
675 error ("Cannot get thread info: %s", thread_db_err_str (err));
676
39f77062 677 ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid));
fb0e1ba7
MK
678
679 switch (msg.event)
680 {
681 case TD_CREATE:
682#if 0
683 /* FIXME: kettenis/2000-08-26: Since we use td_ta_event_getmsg,
684 there is no guarantee that the breakpoint will match the
685 event. Should we use td_thr_event_getmsg instead? */
686
687 if (stop_pc != td_create_bp_addr)
688 error ("Thread creation event doesn't match breakpoint.");
689#endif
690
540af400
MS
691 /* We may already know about this thread, for instance when the
692 user has issued the `info threads' command before the SIGTRAP
693 for hitting the thread creation breakpoint was reported. */
21bf60fe 694 if (!in_thread_list (ptid))
39f77062 695 attach_thread (ptid, msg.th_p, &ti, 1);
fb0e1ba7
MK
696 return;
697
698 case TD_DEATH:
699#if 0
700 /* FIXME: See TD_CREATE. */
701
702 if (stop_pc != td_death_bp_addr)
703 error ("Thread death event doesn't match breakpoint.");
704#endif
705
21bf60fe 706 if (!in_thread_list (ptid))
fb0e1ba7
MK
707 error ("Spurious thread death event.");
708
39f77062 709 detach_thread (ptid, 1);
fb0e1ba7
MK
710 return;
711
712 default:
713 error ("Spurious thread event.");
714 }
715}
716
39f77062
KB
717static ptid_t
718thread_db_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
fb0e1ba7 719{
39f77062 720 extern ptid_t trap_ptid;
fb0e1ba7 721
39f77062
KB
722 if (GET_PID (ptid) != -1 && is_thread (ptid))
723 ptid = lwp_from_thread (ptid);
fb0e1ba7 724
39f77062 725 ptid = target_beneath->to_wait (ptid, ourstatus);
fb0e1ba7 726
bda9cb72
MK
727 if (proc_handle.pid == 0)
728 /* The current child process isn't the actual multi-threaded
729 program yet, so don't try to do any special thread-specific
730 post-processing and bail out early. */
39f77062 731 return ptid;
bda9cb72 732
fb0e1ba7 733 if (ourstatus->kind == TARGET_WAITKIND_EXITED)
39f77062 734 return pid_to_ptid (-1);
fb0e1ba7
MK
735
736 if (ourstatus->kind == TARGET_WAITKIND_STOPPED
737 && ourstatus->value.sig == TARGET_SIGNAL_TRAP)
738 /* Check for a thread event. */
39f77062 739 check_event (ptid);
fb0e1ba7 740
39f77062
KB
741 if (!ptid_equal (trap_ptid, null_ptid))
742 trap_ptid = thread_from_lwp (trap_ptid);
fb0e1ba7 743
39f77062 744 return thread_from_lwp (ptid);
fb0e1ba7
MK
745}
746
747static int
748thread_db_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
e5da8f38 749 struct mem_attrib *attrib,
fb0e1ba7
MK
750 struct target_ops *target)
751{
39f77062 752 struct cleanup *old_chain = save_inferior_ptid ();
fb0e1ba7
MK
753 int xfer;
754
39f77062 755 if (is_thread (inferior_ptid))
fb0e1ba7
MK
756 {
757 /* FIXME: This seems to be necessary to make sure breakpoints
758 are removed. */
21bf60fe 759 if (!target_thread_alive (inferior_ptid))
39f77062 760 inferior_ptid = pid_to_ptid (GET_PID (inferior_ptid));
fb0e1ba7 761 else
39f77062 762 inferior_ptid = lwp_from_thread (inferior_ptid);
fb0e1ba7
MK
763 }
764
e5da8f38 765 xfer = target_beneath->to_xfer_memory (memaddr, myaddr, len, write, attrib, target);
fb0e1ba7
MK
766
767 do_cleanups (old_chain);
768 return xfer;
769}
770
771static void
772thread_db_fetch_registers (int regno)
773{
774 td_thrhandle_t th;
775 prgregset_t gregset;
776 gdb_prfpregset_t fpregset;
777 td_err_e err;
778
21bf60fe 779 if (!is_thread (inferior_ptid))
fb0e1ba7
MK
780 {
781 /* Pass the request to the target beneath us. */
782 target_beneath->to_fetch_registers (regno);
783 return;
784 }
785
39f77062 786 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
fb0e1ba7
MK
787 if (err != TD_OK)
788 error ("Cannot find thread %ld: %s",
39f77062 789 (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
fb0e1ba7
MK
790
791 err = td_thr_getgregs_p (&th, gregset);
792 if (err != TD_OK)
793 error ("Cannot fetch general-purpose registers for thread %ld: %s",
39f77062 794 (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
fb0e1ba7
MK
795
796 err = td_thr_getfpregs_p (&th, &fpregset);
797 if (err != TD_OK)
798 error ("Cannot get floating-point registers for thread %ld: %s",
39f77062 799 (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
fb0e1ba7
MK
800
801 /* Note that we must call supply_gregset after calling the thread_db
802 routines because the thread_db routines call ps_lgetgregs and
803 friends which clobber GDB's register cache. */
804 supply_gregset ((gdb_gregset_t *) gregset);
805 supply_fpregset (&fpregset);
806}
807
808static void
809thread_db_store_registers (int regno)
810{
811 td_thrhandle_t th;
812 prgregset_t gregset;
813 gdb_prfpregset_t fpregset;
814 td_err_e err;
815
21bf60fe 816 if (!is_thread (inferior_ptid))
fb0e1ba7
MK
817 {
818 /* Pass the request to the target beneath us. */
819 target_beneath->to_store_registers (regno);
820 return;
821 }
822
39f77062 823 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
fb0e1ba7
MK
824 if (err != TD_OK)
825 error ("Cannot find thread %ld: %s",
39f77062 826 (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
fb0e1ba7
MK
827
828 if (regno != -1)
829 {
830 char raw[MAX_REGISTER_RAW_SIZE];
831
832 read_register_gen (regno, raw);
833 thread_db_fetch_registers (-1);
834 supply_register (regno, raw);
835 }
836
837 fill_gregset ((gdb_gregset_t *) gregset, -1);
838 fill_fpregset (&fpregset, -1);
839
840 err = td_thr_setgregs_p (&th, gregset);
841 if (err != TD_OK)
842 error ("Cannot store general-purpose registers for thread %ld: %s",
39f77062 843 (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
fb0e1ba7
MK
844 err = td_thr_setfpregs_p (&th, &fpregset);
845 if (err != TD_OK)
846 error ("Cannot store floating-point registers for thread %ld: %s",
39f77062 847 (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
fb0e1ba7
MK
848}
849
850static void
851thread_db_kill (void)
852{
c194fbe1
MK
853 /* There's no need to save & restore inferior_ptid here, since the
854 inferior isn't supposed to survive this function call. */
855 inferior_ptid = lwp_from_thread (inferior_ptid);
fb0e1ba7
MK
856 target_beneath->to_kill ();
857}
858
859static void
860thread_db_create_inferior (char *exec_file, char *allargs, char **env)
861{
21bf60fe 862 if (!keep_thread_db)
c194fbe1
MK
863 {
864 unpush_target (&thread_db_ops);
865 using_thread_db = 0;
866 }
867
bda9cb72
MK
868 target_beneath->to_create_inferior (exec_file, allargs, env);
869}
fb0e1ba7 870
bda9cb72 871static void
39f77062 872thread_db_post_startup_inferior (ptid_t ptid)
bda9cb72
MK
873{
874 if (proc_handle.pid == 0)
875 {
876 /* The child process is now the actual multi-threaded
877 program. Snatch its process ID... */
39f77062 878 proc_handle.pid = GET_PID (ptid);
fb0e1ba7 879
bda9cb72
MK
880 /* ...and perform the remaining initialization steps. */
881 enable_thread_event_reporting ();
21bf60fe 882 thread_db_find_new_threads ();
bda9cb72 883 }
fb0e1ba7
MK
884}
885
886static void
887thread_db_mourn_inferior (void)
888{
889 remove_thread_event_breakpoints ();
c194fbe1
MK
890
891 /* Forget about the child's process ID. We shouldn't need it
892 anymore. */
893 proc_handle.pid = 0;
fb0e1ba7
MK
894
895 target_beneath->to_mourn_inferior ();
896}
897
898static int
39f77062 899thread_db_thread_alive (ptid_t ptid)
fb0e1ba7 900{
5fd913cc 901 td_thrhandle_t th;
21bf60fe
MK
902 td_thrinfo_t ti;
903 td_err_e err;
5fd913cc 904
39f77062 905 if (is_thread (ptid))
fb0e1ba7 906 {
39f77062 907 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
fb0e1ba7
MK
908 if (err != TD_OK)
909 return 0;
910
911 err = td_thr_validate_p (&th);
912 if (err != TD_OK)
913 return 0;
914
5fd913cc
MS
915 err = td_thr_get_info_p (&th, &ti);
916 if (err != TD_OK)
917 return 0;
918
21bf60fe
MK
919 if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
920 return 0; /* A zombie thread. */
5fd913cc 921
fb0e1ba7
MK
922 return 1;
923 }
924
925 if (target_beneath->to_thread_alive)
39f77062 926 return target_beneath->to_thread_alive (ptid);
fb0e1ba7
MK
927
928 return 0;
929}
930
931static int
932find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
933{
934 td_thrinfo_t ti;
935 td_err_e err;
39f77062 936 ptid_t ptid;
fb0e1ba7
MK
937
938 err = td_thr_get_info_p (th_p, &ti);
939 if (err != TD_OK)
940 error ("Cannot get thread info: %s", thread_db_err_str (err));
941
21bf60fe
MK
942 if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
943 return 0; /* A zombie -- ignore. */
5fd913cc 944
39f77062 945 ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid));
fb0e1ba7 946
21bf60fe 947 if (!in_thread_list (ptid))
39f77062 948 attach_thread (ptid, th_p, &ti, 1);
fb0e1ba7
MK
949
950 return 0;
951}
952
953static void
954thread_db_find_new_threads (void)
955{
956 td_err_e err;
957
958 /* Iterate over all user-space threads to discover new threads. */
959 err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
960 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
961 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
962 if (err != TD_OK)
963 error ("Cannot find new threads: %s", thread_db_err_str (err));
964}
965
966static char *
39f77062 967thread_db_pid_to_str (ptid_t ptid)
fb0e1ba7 968{
39f77062 969 if (is_thread (ptid))
fb0e1ba7
MK
970 {
971 static char buf[64];
972 td_thrhandle_t th;
973 td_thrinfo_t ti;
974 td_err_e err;
975
39f77062 976 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
fb0e1ba7
MK
977 if (err != TD_OK)
978 error ("Cannot find thread %ld: %s",
39f77062 979 (long) GET_THREAD (ptid), thread_db_err_str (err));
fb0e1ba7
MK
980
981 err = td_thr_get_info_p (&th, &ti);
982 if (err != TD_OK)
983 error ("Cannot get thread info for thread %ld: %s",
39f77062 984 (long) GET_THREAD (ptid), thread_db_err_str (err));
fb0e1ba7
MK
985
986 if (ti.ti_state == TD_THR_ACTIVE && ti.ti_lid != 0)
987 {
988 snprintf (buf, sizeof (buf), "Thread %ld (LWP %d)",
989 (long) ti.ti_tid, ti.ti_lid);
990 }
991 else
992 {
993 snprintf (buf, sizeof (buf), "Thread %ld (%s)",
994 (long) ti.ti_tid, thread_db_state_str (ti.ti_state));
995 }
996
997 return buf;
998 }
999
39f77062
KB
1000 if (target_beneath->to_pid_to_str (ptid))
1001 return target_beneath->to_pid_to_str (ptid);
fb0e1ba7 1002
39f77062 1003 return normal_pid_to_str (ptid);
fb0e1ba7
MK
1004}
1005
1006static void
1007init_thread_db_ops (void)
1008{
1009 thread_db_ops.to_shortname = "multi-thread";
1010 thread_db_ops.to_longname = "multi-threaded child process.";
1011 thread_db_ops.to_doc = "Threads and pthreads support.";
c194fbe1 1012 thread_db_ops.to_attach = thread_db_attach;
fb0e1ba7
MK
1013 thread_db_ops.to_detach = thread_db_detach;
1014 thread_db_ops.to_resume = thread_db_resume;
1015 thread_db_ops.to_wait = thread_db_wait;
1016 thread_db_ops.to_fetch_registers = thread_db_fetch_registers;
1017 thread_db_ops.to_store_registers = thread_db_store_registers;
1018 thread_db_ops.to_xfer_memory = thread_db_xfer_memory;
1019 thread_db_ops.to_kill = thread_db_kill;
1020 thread_db_ops.to_create_inferior = thread_db_create_inferior;
bda9cb72 1021 thread_db_ops.to_post_startup_inferior = thread_db_post_startup_inferior;
fb0e1ba7
MK
1022 thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
1023 thread_db_ops.to_thread_alive = thread_db_thread_alive;
1024 thread_db_ops.to_find_new_threads = thread_db_find_new_threads;
1025 thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
1026 thread_db_ops.to_stratum = thread_stratum;
1027 thread_db_ops.to_has_thread_control = tc_schedlock;
1028 thread_db_ops.to_magic = OPS_MAGIC;
1029}
1030
1031void
1032_initialize_thread_db (void)
1033{
1034 /* Only initialize the module if we can load libthread_db. */
1035 if (thread_db_load ())
1036 {
1037 init_thread_db_ops ();
1038 add_target (&thread_db_ops);
1039
1040 /* Add ourselves to objfile event chain. */
540af400 1041 target_new_objfile_chain = target_new_objfile_hook;
fb0e1ba7
MK
1042 target_new_objfile_hook = thread_db_new_objfile;
1043 }
1044}
This page took 0.184202 seconds and 4 git commands to generate.