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