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