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