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