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