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