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