* gdb.texinfo (Command Files): Mention -x, use @enumerate for
[deliverable/binutils-gdb.git] / gdb / lin-thread.c
CommitLineData
ed9a39eb
JM
1/* Multi-threaded debugging support for the thread_db interface,
2 used on operating systems such as Solaris and Linux.
3 Copyright 1999 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22/* This module implements a thread_stratum target that sits on top of
23 a normal process_stratum target (such as procfs or ptrace). The
24 process_stratum target must install this thread_stratum target when
25 it detects the presence of the thread_db shared library.
26
27 This module will then use the thread_db API to add thread-awareness
28 to the functionality provided by the process_stratum target (or in
29 some cases, to add user-level thread awareness on top of the
30 kernel-level thread awareness that is already provided by the
31 process_stratum target).
32
33 Solaris threads (for instance) are a multi-level thread implementation;
34 the kernel provides a Light Weight Process (LWP) which the procfs
35 process_stratum module is aware of. This module must then mediate
36 the relationship between kernel LWP threads and user (eg. posix)
37 threads.
38
39 Linux threads are likely to be different -- but the thread_db
40 library API should make the difference largely transparent to GDB.
41
42 */
43
44/* The thread_db API provides a number of functions that give the caller
45 access to the inner workings of the child process's thread library.
46 We will be using the following (others may be added):
47
48 td_thr_validate Confirm valid "live" thread
49 td_thr_get_info Get info about a thread
50 td_thr_getgregs Get thread's general registers
51 td_thr_getfpregs Get thread's floating point registers
52 td_thr_setgregs Set thread's general registers
53 td_thr_setfpregs Set thread's floating point registers
54 td_ta_map_id2thr Get thread handle from thread id
55 td_ta_map_lwp2thr Get thread handle from LWP id
56 td_ta_thr_iter Iterate over all threads (with callback)
57
58 In return, the debugger has to provide certain services to the
59 thread_db library. Some of these aren't actually required to do
60 anything in practice. For instance, the thread_db expects to be
61 able to stop the child process and start it again: but in our
62 context, the child process will always be stopped already when we
63 invoke the thread_db library, so the functions that we provide for
64 the library to stop and start the child process are no-ops.
65
66 Here is the list of functions which we export to the thread_db
67 library, divided into no-op functions vs. functions that actually
68 have to do something:
69
70 No-op functions:
71
72 ps_pstop Stop the child process
73 ps_pcontinue Continue the child process
74 ps_lstop Stop a specific LWP (kernel thread)
75 ps_lcontinue Continue an LWP
76 ps_lgetxregsize Get size of LWP's xregs (sparc)
77 ps_lgetxregs Get LWP's xregs (sparc)
78 ps_lsetxregs Set LWP's xregs (sparc)
79
80 Functions that have to do useful work:
81
82 ps_pglobal_lookup Get the address of a global symbol
83 ps_pdread Read memory, data segment
84 ps_ptread Read memory, text segment
85 ps_pdwrite Write memory, data segment
86 ps_ptwrite Write memory, text segment
87 ps_lgetregs Get LWP's general registers
88 ps_lgetfpregs Get LWP's floating point registers
89 ps_lsetregs Set LWP's general registers
90 ps_lsetfpregs Set LWP's floating point registers
91 ps_lgetLDT Get LWP's Local Descriptor Table (x86)
92
93 Thus, if we ask the thread_db library to give us the general registers
94 for user thread X, thread_db may figure out that user thread X is
95 actually mapped onto kernel thread Y. Thread_db does not know how
96 to obtain the registers for kernel thread Y, but GDB does, so thread_db
97 turns the request right back to us via the ps_lgetregs callback. */
98
99#include "defs.h"
100#include "gdbthread.h"
101#include "target.h"
102#include "inferior.h"
103#include "gdbcmd.h"
104
03f2053f 105#include "gdb_wait.h"
ed9a39eb
JM
106
107#include <time.h>
108
109#if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T)
110#include <sys/procfs.h>
111#endif
112
113#if defined (HAVE_PROC_SERVICE_H)
114#include <proc_service.h> /* defines incoming API (ps_* callbacks) */
115#else
116#include "gdb_proc_service.h"
117#endif
118
119#if defined HAVE_STDINT_H /* Pre-5.2 systems don't have this header */
120#if defined (HAVE_THREAD_DB_H)
121#include <thread_db.h> /* defines outgoing API (td_thr_* calls) */
122#else
123#include "gdb_thread_db.h"
124#endif
125
126#include <dlfcn.h> /* dynamic library interface */
127
128#ifndef TIDGET
129#define TIDGET(PID) (((PID) & 0x7fffffff) >> 16)
130#define PIDGET(PID) (((PID) & 0xffff))
131#define MERGEPID(PID, TID) (((PID) & 0xffff) | ((TID) << 16))
132#endif
133
134/* Macros for superimposing PID and TID into inferior_pid. */
135#define THREAD_FLAG 0x80000000
136#define is_thread(ARG) (((ARG) & THREAD_FLAG) != 0)
137#define is_lwp(ARG) (((ARG) & THREAD_FLAG) == 0)
138#define GET_LWP(PID) TIDGET (PID)
139#define GET_THREAD(PID) TIDGET (PID)
140#define BUILD_LWP(TID, PID) MERGEPID (PID, TID)
141#define BUILD_THREAD(TID, PID) (MERGEPID (PID, TID) | THREAD_FLAG)
142
143/*
144 * target_beneath is a pointer to the target_ops underlying this one.
145 */
146
147static struct target_ops *target_beneath;
148
149
150/*
151 * target vector defined in this module:
152 */
153
154static struct target_ops thread_db_ops;
155
156/*
157 * Typedefs required to resolve differences between the thread_db
158 * and proc_service API defined on different versions of Solaris:
159 */
160
161#if defined(PROC_SERVICE_IS_OLD)
162typedef const struct ps_prochandle *gdb_ps_prochandle_t;
163typedef char *gdb_ps_read_buf_t;
164typedef char *gdb_ps_write_buf_t;
165typedef int gdb_ps_size_t;
166#else
167typedef struct ps_prochandle *gdb_ps_prochandle_t;
168typedef void *gdb_ps_read_buf_t;
169typedef const void *gdb_ps_write_buf_t;
170typedef size_t gdb_ps_size_t;
171#endif
172
d84dd0c5
MK
173/* Unfortunately glibc 2.1.3 was released with a broken prfpregset_t
174 type. We let configure check for this lossage, and make
175 appropriate typedefs here. */
176
177#ifdef PRFPREGSET_T_BROKEN
178typedef elf_fpregset_t gdb_prfpregset_t;
179#else
180typedef prfpregset_t gdb_prfpregset_t;
181#endif
182
ed9a39eb
JM
183/*
184 * proc_service callback functions, called by thread_db.
185 */
186
187ps_err_e
188ps_pstop (gdb_ps_prochandle_t ph) /* Process stop */
189{
190 return PS_OK;
191}
192
193ps_err_e
194ps_pcontinue (gdb_ps_prochandle_t ph) /* Process continue */
195{
196 return PS_OK;
197}
198
199ps_err_e
200ps_lstop (gdb_ps_prochandle_t ph, /* LWP stop */
201 lwpid_t lwpid)
202{
203 return PS_OK;
204}
205
206ps_err_e
207ps_lcontinue (gdb_ps_prochandle_t ph, /* LWP continue */
208 lwpid_t lwpid)
209{
210 return PS_OK;
211}
212
213ps_err_e
214ps_lgetxregsize (gdb_ps_prochandle_t ph, /* Get XREG size */
215 lwpid_t lwpid,
216 int *xregsize)
217{
218 return PS_OK;
219}
220
221ps_err_e
222ps_lgetxregs (gdb_ps_prochandle_t ph, /* Get XREGS */
223 lwpid_t lwpid,
224 caddr_t xregset)
225{
226 return PS_OK;
227}
228
229ps_err_e
230ps_lsetxregs (gdb_ps_prochandle_t ph, /* Set XREGS */
231 lwpid_t lwpid,
232 caddr_t xregset)
233{
234 return PS_OK;
235}
236
237void
238ps_plog (const char *fmt, ...)
239{
240 va_list args;
241
242 va_start (args, fmt);
243 vfprintf_filtered (gdb_stderr, fmt, args);
244}
245
246/* Look up a symbol in GDB's global symbol table.
247 Return the symbol's address.
248 FIXME: it would be more correct to look up the symbol in the context
249 of the LD_OBJECT_NAME provided. However we're probably fairly safe
250 as long as there aren't name conflicts with other libraries. */
251
252ps_err_e
253ps_pglobal_lookup (gdb_ps_prochandle_t ph,
254 const char *ld_object_name, /* the library name */
255 const char *ld_symbol_name, /* the symbol name */
256 paddr_t *ld_symbol_addr) /* return the symbol addr */
257{
258 struct minimal_symbol *ms;
259
260 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
261
262 if (!ms)
263 return PS_NOSYM;
264
265 *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
266
267 return PS_OK;
268}
269
270/* Worker function for all memory reads and writes: */
271static ps_err_e rw_common (const struct ps_prochandle *ph,
272 paddr_t addr,
273 char *buf,
274 int size,
275 int write_p);
276
277/* target_xfer_memory direction consts */
278enum {PS_READ = 0, PS_WRITE = 1};
279
280ps_err_e
281ps_pdread (gdb_ps_prochandle_t ph, /* read from data segment */
282 paddr_t addr,
283 gdb_ps_read_buf_t buf,
284 gdb_ps_size_t size)
285{
286 return rw_common (ph, addr, buf, size, PS_READ);
287}
288
289ps_err_e
290ps_pdwrite (gdb_ps_prochandle_t ph, /* write to data segment */
291 paddr_t addr,
292 gdb_ps_write_buf_t buf,
293 gdb_ps_size_t size)
294{
295 return rw_common (ph, addr, (char *) buf, size, PS_WRITE);
296}
297
298ps_err_e
299ps_ptread (gdb_ps_prochandle_t ph, /* read from text segment */
300 paddr_t addr,
301 gdb_ps_read_buf_t buf,
302 gdb_ps_size_t size)
303{
304 return rw_common (ph, addr, buf, size, PS_READ);
305}
306
307ps_err_e
308ps_ptwrite (gdb_ps_prochandle_t ph, /* write to text segment */
309 paddr_t addr,
310 gdb_ps_write_buf_t buf,
311 gdb_ps_size_t size)
312{
313 return rw_common (ph, addr, (char *) buf, size, PS_WRITE);
314}
315
316static struct cleanup *save_inferior_pid (void);
317static void restore_inferior_pid (void *saved_pid);
318static char *thr_err_string (td_err_e);
319static char *thr_state_string (td_thr_state_e);
320
321struct ps_prochandle {
322 int pid;
323};
324
325struct ps_prochandle main_prochandle;
326td_thragent_t * main_threadagent;
327
328/*
329 * Common proc_service routine for reading and writing memory.
330 */
331
332/* FIXME: once we've munged the inferior_pid, why can't we
333 simply call target_read/write_memory and return? */
334
335
336static ps_err_e
337rw_common (const struct ps_prochandle *ph,
338 paddr_t addr,
339 char *buf,
340 int size,
341 int write_p)
342{
343 struct cleanup *old_chain = save_inferior_pid ();
344 int to_do = size;
345 int done = 0;
346
347 inferior_pid = main_prochandle.pid;
348
349 while (to_do > 0)
350 {
351 done = current_target.to_xfer_memory (addr, buf, size, write_p,
352 &current_target);
353 if (done <= 0)
354 {
355 if (write_p == PS_READ)
356 print_sys_errmsg ("rw_common (): read", errno);
357 else
358 print_sys_errmsg ("rw_common (): write", errno);
359
360 return PS_ERR;
361 }
362 to_do -= done;
363 buf += done;
364 }
365 do_cleanups (old_chain);
366 return PS_OK;
367}
368
369/* Cleanup functions used by the register callbacks
370 (which have to manipulate the global inferior_pid). */
371
372ps_err_e
373ps_lgetregs (gdb_ps_prochandle_t ph, /* Get LWP general regs */
374 lwpid_t lwpid,
375 prgregset_t gregset)
376{
377 struct cleanup *old_chain = save_inferior_pid ();
378
379 inferior_pid = BUILD_LWP (lwpid, main_prochandle.pid);
380 current_target.to_fetch_registers (-1);
381
382 fill_gregset (gregset, -1);
383 do_cleanups (old_chain);
384
385 return PS_OK;
386}
387
388ps_err_e
389ps_lsetregs (gdb_ps_prochandle_t ph, /* Set LWP general regs */
390 lwpid_t lwpid,
391 const prgregset_t gregset)
392{
393 struct cleanup *old_chain = save_inferior_pid ();
394
395 inferior_pid = BUILD_LWP (lwpid, main_prochandle.pid);
396 supply_gregset (gregset);
397 current_target.to_store_registers (-1);
398 do_cleanups (old_chain);
399 return PS_OK;
400}
401
402ps_err_e
403ps_lgetfpregs (gdb_ps_prochandle_t ph, /* Get LWP float regs */
404 lwpid_t lwpid,
d84dd0c5 405 gdb_prfpregset_t *fpregset)
ed9a39eb
JM
406{
407 struct cleanup *old_chain = save_inferior_pid ();
408
409 inferior_pid = BUILD_LWP (lwpid, main_prochandle.pid);
410 current_target.to_fetch_registers (-1);
411 fill_fpregset (fpregset, -1);
412 do_cleanups (old_chain);
413 return PS_OK;
414}
415
416ps_err_e
417ps_lsetfpregs (gdb_ps_prochandle_t ph, /* Set LWP float regs */
418 lwpid_t lwpid,
d84dd0c5 419 const gdb_prfpregset_t *fpregset)
ed9a39eb
JM
420{
421 struct cleanup *old_chain = save_inferior_pid ();
422
423 inferior_pid = BUILD_LWP (lwpid, main_prochandle.pid);
424 supply_fpregset (fpregset);
425 current_target.to_store_registers (-1);
426 do_cleanups (old_chain);
427 return PS_OK;
428}
429
430/*
431 * ps_getpid
432 *
433 * return the main pid for the child process
434 * (special for Linux -- not used on Solaris)
435 */
436
437pid_t
438ps_getpid (gdb_ps_prochandle_t ph)
439{
440 return ph->pid;
441}
442
443#ifdef TM_I386SOL2_H
444
445/* Reads the local descriptor table of a LWP. */
446
447ps_err_e
448ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
449 struct ssd *pldt)
450{
451 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c */
452 extern struct ssd *procfs_find_LDT_entry (int);
453 struct ssd *ret;
454
455 ret = procfs_find_LDT_entry (BUILD_LWP (lwpid,
456 PIDGET (main_prochandle.pid)));
457 if (ret)
458 {
459 memcpy (pldt, ret, sizeof (struct ssd));
460 return PS_OK;
461 }
462 else /* LDT not found. */
463 return PS_ERR;
464}
465#endif /* TM_I386SOL2_H */
466
467/*
468 * Pointers to thread_db functions:
469 *
470 * These are a dynamic library mechanism.
471 * The dlfcn.h interface will be used to initialize these
472 * so that they point to the appropriate functions in the
473 * thread_db dynamic library. This is done dynamically
474 * so that GDB can still run on systems that lack thread_db.
475 */
476
477static td_err_e (*p_td_init) (void);
478
479static td_err_e (*p_td_ta_new) (const struct ps_prochandle *ph_p,
480 td_thragent_t **ta_pp);
481
482static td_err_e (*p_td_ta_delete) (td_thragent_t *ta_p);
483
484static td_err_e (*p_td_ta_get_nthreads) (const td_thragent_t *ta_p,
485 int *nthread_p);
486
487
488static td_err_e (*p_td_ta_thr_iter) (const td_thragent_t *ta_p,
489 td_thr_iter_f *cb,
490 void *cbdata_p,
491 td_thr_state_e state,
492 int ti_pri,
493 sigset_t *ti_sigmask_p,
494 unsigned ti_user_flags);
495
496static td_err_e (*p_td_ta_event_addr) (const td_thragent_t *ta_p,
497 u_long event,
498 td_notify_t *notify_p);
499
500static td_err_e (*p_td_ta_event_getmsg) (const td_thragent_t *ta_p,
501 td_event_msg_t *msg);
502
503static td_err_e (*p_td_ta_set_event) (const td_thragent_t *ta_p,
504 td_thr_events_t *events);
505
506static td_err_e (*p_td_thr_validate) (const td_thrhandle_t *th_p);
507
508static td_err_e (*p_td_thr_event_enable) (const td_thrhandle_t *th_p,
509 int on_off);
510
511static td_err_e (*p_td_thr_get_info) (const td_thrhandle_t *th_p,
512 td_thrinfo_t *ti_p);
513
514static td_err_e (*p_td_thr_getgregs) (const td_thrhandle_t *th_p,
515 prgregset_t regset);
516
517static td_err_e (*p_td_thr_setgregs) (const td_thrhandle_t *th_p,
518 const prgregset_t regset);
519
520static td_err_e (*p_td_thr_getfpregs) (const td_thrhandle_t *th_p,
d84dd0c5 521 gdb_prfpregset_t *fpregset);
ed9a39eb
JM
522
523static td_err_e (*p_td_thr_setfpregs) (const td_thrhandle_t *th_p,
d84dd0c5 524 const gdb_prfpregset_t *fpregset);
ed9a39eb
JM
525
526static td_err_e (*p_td_ta_map_id2thr) (const td_thragent_t *ta_p,
527 thread_t tid,
528 td_thrhandle_t *th_p);
529
530static td_err_e (*p_td_ta_map_lwp2thr) (const td_thragent_t *ta_p,
531 lwpid_t lwpid,
532 td_thrhandle_t *th_p);
533
534/*
535 * API and target vector initialization function: thread_db_initialize.
536 *
537 * NOTE: this function is deliberately NOT named with the GDB convention
538 * of module initializer function names that begin with "_initialize".
539 * This module is NOT intended to be auto-initialized at GDB startup.
540 * Rather, it will only be initialized when a multi-threaded child
541 * process is detected.
542 *
543 */
544
545/*
546 * Initializer for thread_db library interface.
547 * This function does the dynamic library stuff (dlopen, dlsym),
548 * and then calls the thread_db library's one-time initializer
549 * function (td_init). If everything succeeds, this function
550 * returns true; otherwise it returns false, and this module
551 * cannot be used.
552 */
553
554static int
555init_thread_db_library ()
556{
557 void *dlhandle;
558 td_err_e ret;
559
560 /* Open a handle to the "thread_db" dynamic library. */
561 if ((dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW)) == NULL)
562 return 0; /* fail */
563
564 /* Initialize pointers to the dynamic library functions we will use.
565 * Note that we are not calling the functions here -- we are only
566 * establishing pointers to them.
567 */
568
569 /* td_init: initialize thread_db library. */
570 if ((p_td_init = dlsym (dlhandle, "td_init")) == NULL)
571 return 0; /* fail */
572 /* td_ta_new: register a target process with thread_db. */
573 if ((p_td_ta_new = dlsym (dlhandle, "td_ta_new")) == NULL)
574 return 0; /* fail */
575 /* td_ta_delete: un-register a target process with thread_db. */
576 if ((p_td_ta_delete = dlsym (dlhandle, "td_ta_delete")) == NULL)
577 return 0; /* fail */
578
579 /* td_ta_map_id2thr: get thread handle from thread id. */
580 if ((p_td_ta_map_id2thr = dlsym (dlhandle, "td_ta_map_id2thr")) == NULL)
581 return 0; /* fail */
582 /* td_ta_map_lwp2thr: get thread handle from lwp id. */
583 if ((p_td_ta_map_lwp2thr = dlsym (dlhandle, "td_ta_map_lwp2thr")) == NULL)
584 return 0; /* fail */
585 /* td_ta_get_nthreads: get number of threads in target process. */
586 if ((p_td_ta_get_nthreads = dlsym (dlhandle, "td_ta_get_nthreads")) == NULL)
587 return 0; /* fail */
588 /* td_ta_thr_iter: iterate over all thread handles. */
589 if ((p_td_ta_thr_iter = dlsym (dlhandle, "td_ta_thr_iter")) == NULL)
590 return 0; /* fail */
591
592 /* td_thr_validate: make sure a thread handle is real and alive. */
593 if ((p_td_thr_validate = dlsym (dlhandle, "td_thr_validate")) == NULL)
594 return 0; /* fail */
595 /* td_thr_get_info: get a bunch of info about a thread. */
596 if ((p_td_thr_get_info = dlsym (dlhandle, "td_thr_get_info")) == NULL)
597 return 0; /* fail */
598 /* td_thr_getgregs: get general registers for thread. */
599 if ((p_td_thr_getgregs = dlsym (dlhandle, "td_thr_getgregs")) == NULL)
600 return 0; /* fail */
601 /* td_thr_setgregs: set general registers for thread. */
602 if ((p_td_thr_setgregs = dlsym (dlhandle, "td_thr_setgregs")) == NULL)
603 return 0; /* fail */
604 /* td_thr_getfpregs: get floating point registers for thread. */
605 if ((p_td_thr_getfpregs = dlsym (dlhandle, "td_thr_getfpregs")) == NULL)
606 return 0; /* fail */
607 /* td_thr_setfpregs: set floating point registers for thread. */
608 if ((p_td_thr_setfpregs = dlsym (dlhandle, "td_thr_setfpregs")) == NULL)
609 return 0; /* fail */
610
611 ret = p_td_init ();
612 if (ret != TD_OK)
613 {
614 warning ("init_thread_db: td_init: %s", thr_err_string (ret));
615 return 0;
616 }
617
618 /* Optional functions:
619 We can still debug even if the following functions are not found. */
620
621 /* td_ta_event_addr: get the breakpoint address for specified event. */
622 p_td_ta_event_addr = dlsym (dlhandle, "td_ta_event_addr");
623
624 /* td_ta_event_getmsg: get the next event message for the process. */
625 p_td_ta_event_getmsg = dlsym (dlhandle, "td_ta_event_getmsg");
626
627 /* td_ta_set_event: request notification of an event. */
628 p_td_ta_set_event = dlsym (dlhandle, "td_ta_set_event");
629
630 /* td_thr_event_enable: enable event reporting in a thread. */
631 p_td_thr_event_enable = dlsym (dlhandle, "td_thr_event_enable");
632
633 return 1; /* success */
634}
635
636/*
637 * Local utility functions:
638 */
639
640
641/*
642
643 LOCAL FUNCTION
644
645 save_inferior_pid - Save inferior_pid on the cleanup list
646 restore_inferior_pid - Restore inferior_pid from the cleanup list
647
648 SYNOPSIS
649
650 struct cleanup *save_inferior_pid (void);
651 void restore_inferior_pid (void *saved_pid);
652
653 DESCRIPTION
654
655 These two functions act in unison to restore inferior_pid in
656 case of an error.
657
658 NOTES
659
660 inferior_pid is a global variable that needs to be changed by many
661 of these routines before calling functions in procfs.c. In order
662 to guarantee that inferior_pid gets restored (in case of errors),
663 you need to call save_inferior_pid before changing it. At the end
664 of the function, you should invoke do_cleanups to restore it.
665
666 */
667
668static struct cleanup *
669save_inferior_pid (void)
670{
a91f7ea9
KB
671 int *saved_pid_ptr;
672
673 saved_pid_ptr = xmalloc (sizeof (int));
674 *saved_pid_ptr = inferior_pid;
675 return make_cleanup (restore_inferior_pid, saved_pid_ptr);
ed9a39eb
JM
676}
677
678static void
a91f7ea9 679restore_inferior_pid (void *arg)
ed9a39eb 680{
a91f7ea9
KB
681 int *saved_pid_ptr = arg;
682 inferior_pid = *saved_pid_ptr;
683 free (arg);
ed9a39eb
JM
684}
685
686/*
687
688 LOCAL FUNCTION
689
690 thr_err_string - Convert a thread_db error code to a string
691
692 SYNOPSIS
693
694 char * thr_err_string (errcode)
695
696 DESCRIPTION
697
698 Return a string description of the thread_db errcode. If errcode
699 is unknown, then return an <unknown> message.
700
701 */
702
703static char *
704thr_err_string (errcode)
705 td_err_e errcode;
706{
707 static char buf[50];
708
709 switch (errcode) {
710 case TD_OK: return "generic 'call succeeded'";
711 case TD_ERR: return "generic error";
712 case TD_NOTHR: return "no thread to satisfy query";
713 case TD_NOSV: return "no sync handle to satisfy query";
714 case TD_NOLWP: return "no lwp to satisfy query";
715 case TD_BADPH: return "invalid process handle";
716 case TD_BADTH: return "invalid thread handle";
717 case TD_BADSH: return "invalid synchronization handle";
718 case TD_BADTA: return "invalid thread agent";
719 case TD_BADKEY: return "invalid key";
720 case TD_NOMSG: return "no event message for getmsg";
721 case TD_NOFPREGS: return "FPU register set not available";
722 case TD_NOLIBTHREAD: return "application not linked with libthread";
723 case TD_NOEVENT: return "requested event is not supported";
724 case TD_NOCAPAB: return "capability not available";
725 case TD_DBERR: return "debugger service failed";
726 case TD_NOAPLIC: return "operation not applicable to";
727 case TD_NOTSD: return "no thread-specific data for this thread";
728 case TD_MALLOC: return "malloc failed";
729 case TD_PARTIALREG: return "only part of register set was written/read";
730 case TD_NOXREGS: return "X register set not available for this thread";
731 default:
732 sprintf (buf, "unknown thread_db error '%d'", errcode);
733 return buf;
734 }
735}
736
737/*
738
739 LOCAL FUNCTION
740
741 thr_state_string - Convert a thread_db state code to a string
742
743 SYNOPSIS
744
745 char *thr_state_string (statecode)
746
747 DESCRIPTION
748
749 Return the thread_db state string associated with statecode.
750 If statecode is unknown, then return an <unknown> message.
751
752 */
753
754static char *
755thr_state_string (statecode)
756 td_thr_state_e statecode;
757{
758 static char buf[50];
759
760 switch (statecode) {
761 case TD_THR_STOPPED: return "stopped by debugger";
762 case TD_THR_RUN: return "runnable";
763 case TD_THR_ACTIVE: return "active";
764 case TD_THR_ZOMBIE: return "zombie";
765 case TD_THR_SLEEP: return "sleeping";
766 case TD_THR_STOPPED_ASLEEP: return "stopped by debugger AND blocked";
767 default:
768 sprintf (buf, "unknown thread_db state %d", statecode);
769 return buf;
770 }
771}
772
773/*
774 * Local thread/event list.
775 * This data structure will be used to hold a list of threads and
776 * pending/deliverable events.
777 */
778
779typedef struct THREADINFO {
780 thread_t tid; /* thread ID */
781 pid_t lid; /* process/lwp ID */
782 td_thr_state_e state; /* thread state (a la thread_db) */
783 td_thr_type_e type; /* thread type (a la thread_db) */
784 int pending; /* true if holding a pending event */
785 int status; /* wait status of any interesting event */
786} threadinfo;
787
788threadinfo * threadlist;
789int threadlist_max = 0; /* current size of table */
790int threadlist_top = 0; /* number of threads now in table */
791#define THREADLIST_ALLOC 100 /* chunk size by which to expand table */
792
793static threadinfo *
794insert_thread (tid, lid, state, type)
795 int tid;
796 int lid;
797 td_thr_state_e state;
798 td_thr_type_e type;
799{
800 if (threadlist_top >= threadlist_max)
801 {
802 threadlist_max += THREADLIST_ALLOC;
803 threadlist = realloc (threadlist,
804 threadlist_max * sizeof (threadinfo));
805 if (threadlist == NULL)
806 return NULL;
807 }
808 threadlist[threadlist_top].tid = tid;
809 threadlist[threadlist_top].lid = lid;
810 threadlist[threadlist_top].state = state;
811 threadlist[threadlist_top].type = type;
812 threadlist[threadlist_top].pending = 0;
813 threadlist[threadlist_top].status = 0;
814
815 return &threadlist[threadlist_top++];
816}
817
818static void
819empty_threadlist ()
820{
821 threadlist_top = 0;
822}
823
824static threadinfo *
825next_pending_event ()
826{
827 int i;
828
829 for (i = 0; i < threadlist_top; i++)
830 if (threadlist[i].pending)
831 return &threadlist[i];
832
833 return NULL;
834}
835
836static void
837threadlist_iter (func, data, state, type)
838 int (*func) ();
839 void *data;
840 td_thr_state_e state;
841 td_thr_type_e type;
842{
843 int i;
844
845 for (i = 0; i < threadlist_top; i++)
846 if ((state == TD_THR_ANY_STATE || state == threadlist[i].state) &&
847 (type == TD_THR_ANY_TYPE || type == threadlist[i].type))
848 if ((*func) (&threadlist[i], data) != 0)
849 break;
850
851 return;
852}
853
854/*
855 * Global state
856 *
857 * Here we keep state information all collected in one place.
858 */
859
860/* This flag is set when we activate, so that we don't do it twice.
861 Defined in linux-thread.c and used for inter-target syncronization. */
862extern int using_thread_db;
863
864/* The process id for which we've stopped.
865 * This is only set when we actually stop all threads.
866 * Otherwise it's zero.
867 */
868static int event_pid;
869
870/*
871 * The process id for a new thread to which we've just attached.
872 * This process needs special handling at resume time.
873 */
874static int attach_pid;
875
876
877/*
878 * thread_db event handling:
879 *
880 * The mechanism for event notification via the thread_db API.
881 * These events are implemented as breakpoints. The thread_db
882 * library gives us an address where we can set a breakpoint.
883 * When the breakpoint is hit, it represents an event of interest
884 * such as:
885 * Thread creation
886 * Thread death
887 * Thread reap
888 */
889
890/* Location of the thread creation event breakpoint. The code at this
891 location in the child process will be called by the pthread library
892 whenever a new thread is created. By setting a special breakpoint
893 at this location, GDB can detect when a new thread is created. We
894 obtain this location via the td_ta_event_addr call. */
895
896static CORE_ADDR thread_creation_bkpt_address;
897
898/* Location of the thread death event breakpoint. The code at this
899 location in the child process will be called by the pthread library
900 whenever a thread is destroyed. By setting a special breakpoint at
901 this location, GDB can detect when a new thread is created. We
902 obtain this location via the td_ta_event_addr call. */
903
904static CORE_ADDR thread_death_bkpt_address;
905
906/* This function handles the global parts of enabling thread events.
907 The thread-specific enabling is handled per-thread elsewhere. */
908
909static void
910enable_thread_event_reporting (ta)
911 td_thragent_t *ta;
912{
913 td_thr_events_t events;
914 td_notify_t notify;
915 CORE_ADDR addr;
916
917 if (p_td_ta_set_event == NULL ||
918 p_td_ta_event_addr == NULL ||
919 p_td_ta_event_getmsg == NULL ||
920 p_td_thr_event_enable == NULL)
921 return; /* can't do thread event reporting without these funcs */
922
923 /* set process wide mask saying which events we are interested in */
924 td_event_emptyset (&events);
925 td_event_addset (&events, TD_CREATE);
926 td_event_addset (&events, TD_DEATH);
927
928 if (p_td_ta_set_event (ta, &events) != TD_OK)
929 {
930 warning ("unable to set global thread event mask");
931 return;
932 }
933
934 /* Delete previous thread event breakpoints, if any. */
935 remove_thread_event_breakpoints ();
936
937 /* create breakpoints -- thread creation and death */
938 /* thread creation */
939 /* get breakpoint location */
940 if (p_td_ta_event_addr (ta, TD_CREATE, &notify) != TD_OK)
941 {
942 warning ("unable to get location for thread creation breakpoint");
943 return;
944 }
945
946 /* Set up the breakpoint. */
947 create_thread_event_breakpoint (notify.u.bptaddr);
948
949 /* Save it's location. */
950 thread_creation_bkpt_address = notify.u.bptaddr;
951
952 /* thread death */
953 /* get breakpoint location */
954 if (p_td_ta_event_addr (ta, TD_DEATH, &notify) != TD_OK)
955 {
956 warning ("unable to get location for thread death breakpoint");
957 return;
958 }
959 /* Set up the breakpoint. */
960 create_thread_event_breakpoint (notify.u.bptaddr);
961
962 /* Save it's location. */
963 thread_death_bkpt_address = notify.u.bptaddr;
964}
965
966/* This function handles the global parts of disabling thread events.
967 The thread-specific enabling is handled per-thread elsewhere. */
968
969static void
970disable_thread_event_reporting (ta)
971 td_thragent_t *ta;
972{
973 td_thr_events_t events;
974
975 /* set process wide mask saying we aren't interested in any events */
976 td_event_emptyset (&events);
977 p_td_ta_set_event (main_threadagent, &events);
978
979 /* Delete thread event breakpoints, if any. */
980 remove_thread_event_breakpoints ();
981 thread_creation_bkpt_address = 0;
982 thread_death_bkpt_address = 0;
983}
984
985/* check_for_thread_event
986
987 if it's a thread event we recognize (currently
988 we only recognize creation and destruction
989 events), return 1; else return 0. */
990
991
992static int
993check_for_thread_event (struct target_waitstatus *tws, int event_pid)
994{
995 /* FIXME: to be more efficient, we should keep a static
996 list of threads, and update it only here (with td_ta_thr_iter). */
997}
998
999static void
1000thread_db_push_target (void)
1001{
1002 /* Called ONLY from thread_db_new_objfile after td_ta_new call succeeds. */
1003
1004 /* Push this target vector */
1005 push_target (&thread_db_ops);
1006 /* Find the underlying process-layer target for calling later. */
1007 target_beneath = find_target_beneath (&thread_db_ops);
1008 using_thread_db = 1;
1009 /* Turn on thread_db event-reporting API. */
1010 enable_thread_event_reporting (main_threadagent);
1011}
1012
1013static void
1014thread_db_unpush_target (void)
1015{
1016 /* Must be called whenever we remove ourself from the target stack! */
1017
1018 using_thread_db = 0;
1019 target_beneath = NULL;
1020
1021 /* delete local list of threads */
1022 empty_threadlist ();
1023 /* Turn off the thread_db API. */
1024 p_td_ta_delete (main_threadagent);
1025 /* Unpush this target vector */
1026 unpush_target (&thread_db_ops);
1027 /* Reset linuxthreads module. */
1028 linuxthreads_discard_global_state ();
1029}
1030
1031/*
1032 * New objfile hook function:
1033 * Called for each new objfile (image, shared lib) in the target process.
1034 *
1035 * The purpose of this function is to detect that the target process
1036 * is linked with the (appropriate) thread library. So every time a
1037 * new target shared library is detected, we will call td_ta_new.
1038 * If it succeeds, we know we have a multi-threaded target process
1039 * that we can debug using the thread_db API.
1040 */
1041
1042/*
1043 * new_objfile function:
1044 *
1045 * connected to target_new_objfile_hook, this function gets called
1046 * every time a new binary image is loaded.
1047 *
1048 * At each call, we attempt to open the thread_db connection to the
1049 * child process. If it succeeds, we know we have a libthread process
1050 * and we can debug it with this target vector. Therefore we push
1051 * ourself onto the target stack.
1052 */
1053
1054static void (*target_new_objfile_chain) (struct objfile *objfile);
1055static int stop_or_attach_thread_callback (const td_thrhandle_t *th,
1056 void *data);
1057static int wait_thread_callback (const td_thrhandle_t *th,
1058 void *data);
1059
1060static void
1061thread_db_new_objfile (struct objfile *objfile)
1062{
1063 td_err_e ret;
1064
1065 if (using_thread_db) /* libthread already detected, and */
1066 goto quit; /* thread target vector activated. */
1067
1068 if (objfile == NULL)
1069 goto quit; /* un-interesting object file */
1070
1071 /* Initialize our "main prochandle" with the main inferior pid. */
1072 main_prochandle.pid = PIDGET (inferior_pid);
1073
1074 /* Now attempt to open a thread_db connection to the
1075 thread library running in the child process. */
1076 ret = p_td_ta_new (&main_prochandle, &main_threadagent);
1077 switch (ret) {
1078 default:
1079 warning ("Unexpected error initializing thread_db: %s",
1080 thr_err_string (ret));
1081 break;
1082 case TD_NOLIBTHREAD: /* expected: no libthread in child process (yet) */
1083 break;
1084 case TD_OK: /* libthread detected in child: we go live now! */
1085 thread_db_push_target ();
1086 event_pid = inferior_pid; /* for resume */
1087
1088 /* Now stop everyone else, and attach any new threads you find. */
1089 p_td_ta_thr_iter (main_threadagent,
1090 stop_or_attach_thread_callback,
1091 (void *) 0,
1092 TD_THR_ANY_STATE,
1093 TD_THR_LOWEST_PRIORITY,
1094 TD_SIGNO_MASK,
1095 TD_THR_ANY_USER_FLAGS);
1096
1097 /* Now go call wait on all the threads you've stopped:
1098 This allows us to absorb the SIGKILL event, and to make sure
1099 that the thread knows that it is stopped (Linux peculiarity). */
1100 p_td_ta_thr_iter (main_threadagent,
1101 wait_thread_callback,
1102 (void *) 0,
1103 TD_THR_ANY_STATE,
1104 TD_THR_LOWEST_PRIORITY,
1105 TD_SIGNO_MASK,
1106 TD_THR_ANY_USER_FLAGS);
1107
1108 break;
1109 }
1110quit:
1111 if (target_new_objfile_chain)
1112 target_new_objfile_chain (objfile);
1113}
1114
1115
1116/*
1117
1118 LOCAL FUNCTION
1119
1120 thread_db_alive - test thread for "aliveness"
1121
1122 SYNOPSIS
1123
1124 static bool thread_db_alive (int pid);
1125
1126 DESCRIPTION
1127
1128 returns true if thread still active in inferior.
1129
1130 */
1131
1132static int
1133thread_db_alive (pid)
1134 int pid;
1135{
1136 if (is_thread (pid)) /* user-space (non-kernel) thread */
1137 {
1138 td_thrhandle_t th;
1139 td_err_e ret;
1140
1141 pid = GET_THREAD (pid);
1142 if ((ret = p_td_ta_map_id2thr (main_threadagent, pid, &th)) != TD_OK)
1143 return 0; /* thread not found */
1144 if ((ret = p_td_thr_validate (&th)) != TD_OK)
1145 return 0; /* thread not valid */
1146 return 1; /* known thread: return true */
1147 }
1148 else if (target_beneath->to_thread_alive)
1149 return target_beneath->to_thread_alive (pid);
1150 else
1151 return 0; /* default to "not alive" (shouldn't happen anyway) */
1152}
1153
1154/*
1155 * get_lwp_from_thread_handle
1156 */
1157
1158static int /* lwpid_t or pid_t */
1159get_lwp_from_thread_handle (th)
1160 td_thrhandle_t *th;
1161{
1162 td_thrinfo_t ti;
1163 td_err_e ret;
1164
1165 if ((ret = p_td_thr_get_info (th, &ti)) != TD_OK)
1166 error ("get_lwp_from_thread_handle: thr_get_info failed: %s",
1167 thr_err_string (ret));
1168
1169 return ti.ti_lid;
1170}
1171
1172/*
1173 * get_lwp_from_thread_id
1174 */
1175
1176static int /* lwpid_t or pid_t */
1177get_lwp_from_thread_id (tid)
1178 int tid; /* thread_t? */
1179{
1180 td_thrhandle_t th;
1181 td_err_e ret;
1182
1183 if ((ret = p_td_ta_map_id2thr (main_threadagent, tid, &th)) != TD_OK)
1184 error ("get_lwp_from_thread_id: map_id2thr failed: %s",
1185 thr_err_string (ret));
1186
1187 return get_lwp_from_thread_handle (&th);
1188}
1189
1190/*
1191 * pid_to_str has to handle user-space threads.
1192 * If not a user-space thread, then pass the request on to the
1193 * underlying stratum if it can handle it: else call normal_pid_to_str.
1194 */
1195
1196static char *
1197thread_db_pid_to_str (int pid)
1198{
1199 static char buf[100];
1200 td_thrhandle_t th;
1201 td_thrinfo_t ti;
1202 td_err_e ret;
1203
1204 if (is_thread (pid))
1205 {
1206 if ((ret = p_td_ta_map_id2thr (main_threadagent,
1207 GET_THREAD (pid),
1208 &th)) != TD_OK)
1209 error ("thread_db: map_id2thr failed: %s", thr_err_string (ret));
1210
1211 if ((ret = p_td_thr_get_info (&th, &ti)) != TD_OK)
1212 error ("thread_db: thr_get_info failed: %s", thr_err_string (ret));
1213
1214 if (ti.ti_state == TD_THR_ACTIVE &&
1215 ti.ti_lid != 0)
1216 sprintf (buf, "Thread %d (LWP %d)", ti.ti_tid, ti.ti_lid);
1217 else
1218 sprintf (buf, "Thread %d (%s)", ti.ti_tid,
1219 thr_state_string (ti.ti_state));
1220 }
1221 else if (GET_LWP (pid))
1222 sprintf (buf, "LWP %d", GET_LWP (pid));
1223 else return normal_pid_to_str (pid);
1224
1225 return buf;
1226}
1227
1228/*
1229 * thread_db target vector functions:
1230 */
1231
1232static void
1233thread_db_files_info (struct target_ops *tgt_vector)
1234{
1235 /* This function will be unnecessary in real life. */
1236 printf_filtered ("thread_db stratum:\n");
1237 target_beneath->to_files_info (tgt_vector);
1238}
1239
1240/*
1241 * xfer_memory has to munge the inferior_pid before passing the call
1242 * down to the target layer.
1243 */
1244
1245static int
1246thread_db_xfer_memory (memaddr, myaddr, len, dowrite, target)
1247 CORE_ADDR memaddr;
1248 char *myaddr;
1249 int len;
1250 int dowrite;
1251 struct target_ops *target; /* ignored */
1252{
1253 struct cleanup *old_chain;
1254 int ret;
1255
1256 old_chain = save_inferior_pid ();
1257
1258 if (is_thread (inferior_pid) ||
1259 !target_thread_alive (inferior_pid))
1260 {
1261 /* FIXME: use the LID/LWP, so that underlying process layer
1262 can read memory from specific threads? */
1263 inferior_pid = main_prochandle.pid;
1264 }
1265
1266 ret = target_beneath->to_xfer_memory (memaddr, myaddr, len,
1267 dowrite, target);
1268 do_cleanups (old_chain);
1269 return ret;
1270}
1271
1272/*
1273 * fetch_registers has to determine if inferior_pid is a user-space thread.
1274 * If so, we use the thread_db API to get the registers.
1275 * And if not, we call the underlying process stratum.
1276 */
1277
1278static void
1279thread_db_fetch_registers (regno)
1280 int regno;
1281{
1282 td_thrhandle_t thandle;
d84dd0c5 1283 gdb_prfpregset_t fpregset;
ed9a39eb
JM
1284 prgregset_t gregset;
1285 thread_t thread;
1286 td_err_e ret;
1287
1288 if (!is_thread (inferior_pid)) /* kernel thread */
1289 { /* pass the request on to the target underneath. */
1290 target_beneath->to_fetch_registers (regno);
1291 return;
1292 }
1293
1294 /* convert inferior_pid into a td_thrhandle_t */
1295
1296 if ((thread = GET_THREAD (inferior_pid)) == 0)
1297 error ("fetch_registers: thread == 0");
1298
1299 if ((ret = p_td_ta_map_id2thr (main_threadagent, thread, &thandle)) != TD_OK)
1300 error ("fetch_registers: td_ta_map_id2thr: %s", thr_err_string (ret));
1301
1302 /* Get the integer regs:
1303 For the sparc, TD_PARTIALREG means that only i0->i7, l0->l7,
1304 pc and sp are saved (by a thread context switch). */
1305 if ((ret = p_td_thr_getgregs (&thandle, gregset)) != TD_OK &&
1306 ret != TD_PARTIALREG)
1307 error ("fetch_registers: td_thr_getgregs %s", thr_err_string (ret));
1308
1309 /* And, now the fp regs */
1310 if ((ret = p_td_thr_getfpregs (&thandle, &fpregset)) != TD_OK &&
1311 ret != TD_NOFPREGS)
1312 error ("fetch_registers: td_thr_getfpregs %s", thr_err_string (ret));
1313
1314/* Note that we must call supply_{g fp}regset *after* calling the td routines
1315 because the td routines call ps_lget* which affect the values stored in the
1316 registers array. */
1317
1318 supply_gregset (gregset);
1319 supply_fpregset (&fpregset);
1320
1321}
1322
1323/*
1324 * store_registers has to determine if inferior_pid is a user-space thread.
1325 * If so, we use the thread_db API to get the registers.
1326 * And if not, we call the underlying process stratum.
1327 */
1328
1329static void
1330thread_db_store_registers (regno)
1331 int regno;
1332{
1333 td_thrhandle_t thandle;
d84dd0c5 1334 gdb_prfpregset_t fpregset;
ed9a39eb
JM
1335 prgregset_t gregset;
1336 thread_t thread;
1337 td_err_e ret;
1338
1339 if (!is_thread (inferior_pid)) /* Kernel thread: */
1340 { /* pass the request on to the underlying target vector. */
1341 target_beneath->to_store_registers (regno);
1342 return;
1343 }
1344
1345 /* convert inferior_pid into a td_thrhandle_t */
1346
1347 if ((thread = GET_THREAD (inferior_pid)) == 0)
1348 error ("store_registers: thread == 0");
1349
1350 if ((ret = p_td_ta_map_id2thr (main_threadagent, thread, &thandle)) != TD_OK)
1351 error ("store_registers: td_ta_map_id2thr %s", thr_err_string (ret));
1352
1353 if (regno != -1)
1354 { /* Not writing all the regs */
1355 /* save new register value */
1356 /* MVS: I don't understand this... */
1357 char old_value[REGISTER_SIZE];
1358
1359 memcpy (old_value, &registers[REGISTER_BYTE (regno)], REGISTER_SIZE);
1360
1361 if ((ret = p_td_thr_getgregs (&thandle, gregset)) != TD_OK)
1362 error ("store_registers: td_thr_getgregs %s", thr_err_string (ret));
1363 if ((ret = p_td_thr_getfpregs (&thandle, &fpregset)) != TD_OK)
1364 error ("store_registers: td_thr_getfpregs %s", thr_err_string (ret));
1365
1366 /* restore new register value */
1367 memcpy (&registers[REGISTER_BYTE (regno)], old_value, REGISTER_SIZE);
1368
1369 }
1370
1371 fill_gregset (gregset, regno);
1372 fill_fpregset (&fpregset, regno);
1373
1374 if ((ret = p_td_thr_setgregs (&thandle, gregset)) != TD_OK)
1375 error ("store_registers: td_thr_setgregs %s", thr_err_string (ret));
1376 if ((ret = p_td_thr_setfpregs (&thandle, &fpregset)) != TD_OK &&
1377 ret != TD_NOFPREGS)
1378 error ("store_registers: td_thr_setfpregs %s", thr_err_string (ret));
1379}
1380
1381static void
1382handle_new_thread (tid, lid, verbose)
1383 int tid; /* user thread id */
1384 int lid; /* kernel thread id */
1385 int verbose;
1386{
1387 int gdb_pid = BUILD_THREAD (tid, main_prochandle.pid);
1388 int wait_pid, wait_status;
1389
1390 if (verbose)
1391 printf_filtered ("[New %s]\n", target_pid_to_str (gdb_pid));
1392 add_thread (gdb_pid);
1393
1394 if (lid != main_prochandle.pid)
1395 {
1396 attach_thread (lid);
1397 /* According to the Eric Paire model, we now have to send
1398 the restart signal to the new thread -- however, empirically,
1399 I do not find that to be necessary. */
1400 attach_pid = lid;
1401 }
1402}
1403
1404static void
1405test_for_new_thread (tid, lid, verbose)
1406 int tid;
1407 int lid;
1408 int verbose;
1409{
1410 if (!in_thread_list (BUILD_THREAD (tid, main_prochandle.pid)))
1411 handle_new_thread (tid, lid, verbose);
1412}
1413
1414/*
1415 * Callback function that gets called once per USER thread
1416 * (i.e., not kernel) thread by td_ta_thr_iter.
1417 */
1418
1419static int
1420find_new_threads_callback (th, ignored)
1421 const td_thrhandle_t *th;
1422 void *ignored;
1423{
1424 td_thrinfo_t ti;
1425 td_err_e ret;
1426
1427 if ((ret = p_td_thr_get_info (th, &ti)) != TD_OK)
1428 {
1429 warning ("find_new_threads_callback: %s", thr_err_string (ret));
1430 return -1; /* bail out, get_info failed. */
1431 }
1432
1433 /* FIXME:
1434 As things now stand, this should never detect a new thread.
1435 But if it does, we could be in trouble because we aren't calling
1436 wait_thread_callback for it. */
1437 test_for_new_thread (ti.ti_tid, ti.ti_lid, 0);
1438 return 0;
1439}
1440
1441/*
1442 * find_new_threads uses the thread_db iterator function to discover
1443 * user-space threads. Then if the underlying process stratum has a
1444 * find_new_threads method, we call that too.
1445 */
1446
1447static void
1448thread_db_find_new_threads ()
1449{
1450 if (inferior_pid == -1) /* FIXME: still necessary? */
1451 {
1452 printf_filtered ("No process.\n");
1453 return;
1454 }
1455 p_td_ta_thr_iter (main_threadagent,
1456 find_new_threads_callback,
1457 (void *) 0,
1458 TD_THR_ANY_STATE,
1459 TD_THR_LOWEST_PRIORITY,
1460 TD_SIGNO_MASK,
1461 TD_THR_ANY_USER_FLAGS);
1462 if (target_beneath->to_find_new_threads)
1463 target_beneath->to_find_new_threads ();
1464}
1465
1466/*
1467 * Resume all threads, or resume a single thread.
1468 * If step is true, then single-step the appropriate thread
1469 * (or single-step inferior_pid, but continue everyone else).
1470 * If signo is true, then send that signal to at least one thread.
1471 */
1472
1473/*
1474 * This function is called once for each thread before resuming.
1475 * It sends continue (no step, and no signal) to each thread except
1476 * the main thread, and
1477 * the event thread (the one that stopped at a breakpoint etc.)
1478 *
1479 * The event thread is handled separately so that it can be sent
1480 * the stepping and signal args with which target_resume was called.
1481 *
1482 * The main thread is resumed last, so that the thread_db proc_service
1483 * callbacks will still work during the iterator function.
1484 */
1485
1486static int
1487resume_thread_callback (th, data)
1488 const td_thrhandle_t *th;
1489 void *data;
1490{
1491 td_thrinfo_t ti;
1492 td_err_e ret;
1493
1494 if ((ret = p_td_thr_get_info (th, &ti)) != TD_OK)
1495 {
1496 warning ("resume_thread_callback: %s", thr_err_string (ret));
1497 return -1; /* bail out, get_info failed. */
1498 }
1499 /* FIXME:
1500 As things now stand, this should never detect a new thread.
1501 But if it does, we could be in trouble because we aren't calling
1502 wait_thread_callback for it. */
1503 test_for_new_thread (ti.ti_tid, ti.ti_lid, 1);
1504
1505 if (ti.ti_lid != main_prochandle.pid &&
1506 ti.ti_lid != event_pid)
1507 {
1508 /* Unconditionally continue the thread with no signal.
1509 Only the event thread will get a signal of any kind. */
1510
1511 target_beneath->to_resume (ti.ti_lid, 0, 0);
1512 }
1513 return 0;
1514}
1515
1516static int
1517new_resume_thread_callback (thread, data)
1518 threadinfo *thread;
1519 void *data;
1520{
1521 if (thread->lid != event_pid &&
1522 thread->lid != main_prochandle.pid)
1523 {
1524 /* Unconditionally continue the thread with no signal (for now). */
1525
1526 target_beneath->to_resume (thread->lid, 0, 0);
1527 }
1528 return 0;
1529}
1530
1531static int last_resume_pid;
1532static int last_resume_step;
1533static int last_resume_signo;
1534
1535static void
1536thread_db_resume (pid, step, signo)
1537 int pid;
1538 int step;
1539 enum target_signal signo;
1540{
1541 last_resume_pid = pid;
1542 last_resume_step = step;
1543 last_resume_signo = signo;
1544
1545 /* resuming a specific pid? */
1546 if (pid != -1)
1547 {
1548 if (is_thread (pid))
1549 pid = get_lwp_from_thread_id (GET_THREAD (pid));
1550 else if (GET_LWP (pid))
1551 pid = GET_LWP (pid);
1552 }
1553
1554 /* Apparently the interpretation of 'pid' is dependent on 'step':
1555 If step is true, then a specific pid means 'step only this pid'.
1556 But if step is not true, then pid means 'continue ALL pids, but
1557 give the signal only to this one'. */
1558 if (pid != -1 && step)
1559 {
1560 /* FIXME: is this gonna work in all circumstances? */
1561 target_beneath->to_resume (pid, step, signo);
1562 }
1563 else
1564 {
1565 /* 1) Continue all threads except the event thread and the main thread.
1566 2) resume the event thread with step and signo.
1567 3) If event thread != main thread, continue the main thread.
1568
1569 Note: order of 2 and 3 may need to be reversed. */
1570
1571 threadlist_iter (new_resume_thread_callback,
1572 (void *) 0,
1573 TD_THR_ANY_STATE,
1574 TD_THR_ANY_TYPE);
1575 /* now resume event thread, and if necessary also main thread. */
1576 if (event_pid)
1577 {
1578 target_beneath->to_resume (event_pid, step, signo);
1579 }
1580 if (event_pid != main_prochandle.pid)
1581 {
1582 target_beneath->to_resume (main_prochandle.pid, 0, 0);
1583 }
1584 }
1585}
1586
1587/* All new threads will be attached.
1588 All previously known threads will be stopped using kill (SIGKILL). */
1589
1590static int
1591stop_or_attach_thread_callback (const td_thrhandle_t *th, void *data)
1592{
1593 td_thrinfo_t ti;
1594 td_err_e ret;
1595 int gdb_pid;
1596 int on_off = 1;
1597
1598 if ((ret = p_td_thr_get_info (th, &ti)) != TD_OK)
1599 {
1600 warning ("stop_or_attach_thread_callback: %s", thr_err_string (ret));
1601 return -1; /* bail out, get_info failed. */
1602 }
1603
1604 /* First add it to our internal list.
1605 We build this list anew at every wait event. */
1606 insert_thread (ti.ti_tid, ti.ti_lid, ti.ti_state, ti.ti_type);
1607 /* Now: if we've already seen it, stop it, else add it and attach it. */
1608 gdb_pid = BUILD_THREAD (ti.ti_tid, main_prochandle.pid);
1609 if (!in_thread_list (gdb_pid)) /* new thread */
1610 {
1611 handle_new_thread (ti.ti_tid, ti.ti_lid, 1);
1612 /* Enable thread events */
1613 if (p_td_thr_event_enable)
1614 if ((ret = p_td_thr_event_enable (th, on_off)) != TD_OK)
1615 warning ("stop_or_attach_thread: %s", thr_err_string (ret));
1616 }
1617 else if (ti.ti_lid != event_pid &&
1618 ti.ti_lid != main_prochandle.pid)
1619 {
1620 ret = (td_err_e) kill (ti.ti_lid, SIGSTOP);
1621 }
1622
1623 return 0;
1624}
1625
1626/*
1627 * Wait for signal N from pid PID.
1628 * If wait returns any other signals, put them back before returning.
1629 */
1630
1631static void
1632wait_for_stop (pid)
1633 int pid;
1634{
1635 int i;
1636 int retpid;
1637 int status;
1638
1639 /* Array of wait/signal status */
1640 /* FIXME: wrong data structure, we need a queue.
1641 Realtime signals may be delivered more than once.
1642 And at that, we really can't handle them (see below). */
1643#if defined (NSIG)
1644 static int wstatus [NSIG];
1645#elif defined (_NSIG)
1646 static int wstatus [_NSIG];
1647#else
1648#error No definition for number of signals!
1649#endif
1650
1651 /* clear wait/status list */
1652 memset (&wstatus, 0, sizeof (wstatus));
1653
1654 /* Now look for SIGSTOP event on all threads except event thread. */
1655 do {
1656 errno = 0;
1657 if (pid == main_prochandle.pid)
1658 retpid = waitpid (pid, &status, 0);
1659 else
1660 retpid = waitpid (pid, &status, __WCLONE);
1661
1662 if (retpid > 0)
1663 if (WSTOPSIG (status) == SIGSTOP)
1664 {
1665 /* Got the SIGSTOP event we're looking for.
1666 Throw it away, and throw any other events back! */
1667 for (i = 0; i < sizeof(wstatus) / sizeof (wstatus[0]); i++)
1668 if (wstatus[i])
1669 if (i != SIGSTOP)
1670 {
1671 kill (retpid, i);
1672 }
1673 break; /* all done */
1674 }
1675 else
1676 {
1677 int signo;
1678 /* Oops, got an event other than SIGSTOP.
1679 Save it, and throw it back after we find the SIGSTOP event. */
1680
1681 /* FIXME (how?) This method is going to fail for realtime
1682 signals, which cannot be put back simply by using kill. */
1683
1684 if (WIFEXITED (status))
1685 error ("Ack! Thread Exited event. What do I do now???");
1686 else if (WIFSTOPPED (status))
1687 signo = WSTOPSIG (status);
1688 else
1689 signo = WTERMSIG (status);
1690
1691 /* If a thread other than the event thread has hit a GDB
1692 breakpoint (as opposed to some random trap signal), then
1693 just arrange for it to hit it again later. Back up the
1694 PC if necessary. Don't forward the SIGTRAP signal to
1695 the thread. We will handle the current event, eventually
1696 we will resume all the threads, and this one will get
1697 it's breakpoint trap again.
1698
1699 If we do not do this, then we run the risk that the user
1700 will delete or disable the breakpoint, but the thread will
1701 have already tripped on it. */
1702
1703 if (retpid != event_pid &&
1704 signo == SIGTRAP &&
1705 breakpoint_inserted_here_p (read_pc_pid (retpid) -
1706 DECR_PC_AFTER_BREAK))
1707 {
1708 /* Set the pc to before the trap and DO NOT re-send the signal */
1709 if (DECR_PC_AFTER_BREAK)
1710 write_pc_pid (read_pc_pid (retpid) - DECR_PC_AFTER_BREAK,
1711 retpid);
1712 }
1713
1714 /* Since SIGINT gets forwarded to the entire process group
1715 (in the case where ^C is typed at the tty / console),
1716 just ignore all SIGINTs from other than the event thread. */
1717 else if (retpid != event_pid && signo == SIGINT)
1718 { /* do nothing. Signal will disappear into oblivion! */
1719 ;
1720 }
1721
1722 else /* This is some random signal other than a breakpoint. */
1723 {
1724 wstatus [signo] = 1;
1725 }
1726 child_resume (retpid, 0, TARGET_SIGNAL_0);
1727 continue;
1728 }
1729
1730 } while (errno == 0 || errno == EINTR);
1731}
1732
1733/*
1734 * wait_thread_callback
1735 *
1736 * Calls waitpid for each thread, repeatedly if necessary, until
1737 * SIGSTOP is returned. Afterward, if any other signals were returned
1738 * by waitpid, return them to the thread's pending queue by calling kill.
1739 */
1740
1741static int
1742wait_thread_callback (const td_thrhandle_t *th, void *data)
1743{
1744 td_thrinfo_t ti;
1745 td_err_e ret;
1746
1747 if ((ret = p_td_thr_get_info (th, &ti)) != TD_OK)
1748 {
1749 warning ("wait_thread_callback: %s", thr_err_string (ret));
1750 return -1; /* bail out, get_info failed. */
1751 }
1752
1753 /* This callback to act on all threads except the event thread: */
1754 if (ti.ti_lid == event_pid || /* no need to wait (no sigstop) */
1755 ti.ti_lid == main_prochandle.pid) /* no need to wait (already waited) */
1756 return 0; /* don't wait on the event thread. */
1757
1758 wait_for_stop (ti.ti_lid);
1759 return 0; /* finished: next thread. */
1760}
1761
1762static int
1763new_wait_thread_callback (thread, data)
1764 threadinfo *thread;
1765 void *data;
1766{
1767 /* don't wait on the event thread -- it's already stopped and waited.
1768 Ditto the main thread. */
1769 if (thread->lid != event_pid &&
1770 thread->lid != main_prochandle.pid)
1771 {
1772 wait_for_stop (thread->lid);
1773 }
1774 return 0;
1775}
1776
1777/*
1778 * Wait for any thread to stop, by calling the underlying wait method.
1779 * The PID returned by the underlying target may be a kernel thread,
1780 * in which case we will want to convert it to the corresponding
1781 * user-space thread.
1782 */
1783
1784static int
1785thread_db_wait (int pid, struct target_waitstatus *ourstatus)
1786{
1787 td_thrhandle_t thandle;
1788 td_thrinfo_t ti;
1789 td_err_e ret;
1790 lwpid_t lwp;
1791 int retpid;
1792 int status;
1793 int save_errno;
1794
1795 /* OK, we're about to wait for an event from the running inferior.
1796 Make sure we're ignoring the right signals. */
1797
1798 check_all_signal_numbers (); /* see if magic signals changed. */
1799
1800 event_pid = 0;
1801 attach_pid = 0;
1802
1803 /* FIXME: should I do the wait right here inline? */
1804#if 0
1805 if (pid == -1)
1806 lwp = -1;
1807 else
1808 lwp = get_lwp_from_thread_id (GET_THREAD (pid));
1809#endif
1810
1811
1812 save_errno = linux_child_wait (-1, &retpid, &status);
1813 store_waitstatus (ourstatus, status);
1814
1815 /* Thread ID is irrelevant if the target process exited.
1816 FIXME: do I have any killing to do?
1817 Can I get this event mistakenly from a thread? */
1818 if (ourstatus->kind == TARGET_WAITKIND_EXITED)
1819 return retpid;
1820
1821 /* OK, we got an event of interest.
1822 Go stop all threads and look for new ones.
1823 FIXME: maybe don't do this for the restart signal? Optimization... */
1824 event_pid = retpid;
1825
1826 /* If the last call to resume was for a specific thread, then we don't
1827 need to stop everyone else: they should already be stopped. */
1828 if (last_resume_step == 0 || last_resume_pid == -1)
1829 {
1830 /* Main thread must be stopped before calling the iterator. */
1831 if (retpid != main_prochandle.pid)
1832 {
1833 kill (main_prochandle.pid, SIGSTOP);
1834 wait_for_stop (main_prochandle.pid);
1835 }
1836
1837 empty_threadlist ();
1838 /* Now stop everyone else, and attach any new threads you find. */
1839 p_td_ta_thr_iter (main_threadagent,
1840 stop_or_attach_thread_callback,
1841 (void *) 0,
1842 TD_THR_ANY_STATE,
1843 TD_THR_LOWEST_PRIORITY,
1844 TD_SIGNO_MASK,
1845 TD_THR_ANY_USER_FLAGS);
1846
1847 /* Now go call wait on all the threads we've stopped:
1848 This allows us to absorb the SIGKILL event, and to make sure
1849 that the thread knows that it is stopped (Linux peculiarity). */
1850
1851 threadlist_iter (new_wait_thread_callback,
1852 (void *) 0,
1853 TD_THR_ANY_STATE,
1854 TD_THR_ANY_TYPE);
1855 }
1856
1857 /* Convert the kernel thread id to the corresponding thread id. */
1858
1859 /* If the process layer does not furnish an lwp,
1860 then perhaps the returned pid IS the lwp... */
1861 if ((lwp = GET_LWP (retpid)) == 0)
1862 lwp = retpid;
1863
1864 if ((ret = p_td_ta_map_lwp2thr (main_threadagent, lwp, &thandle)) != TD_OK)
1865 return retpid; /* LWP is not mapped onto a user-space thread. */
1866
1867 if ((ret = p_td_thr_validate (&thandle)) != TD_OK)
1868 return retpid; /* LWP is not mapped onto a valid thread. */
1869
1870 if ((ret = p_td_thr_get_info (&thandle, &ti)) != TD_OK)
1871 {
1872 warning ("thread_db: thr_get_info failed ('%s')", thr_err_string (ret));
1873 return retpid;
1874 }
1875
1876 retpid = BUILD_THREAD (ti.ti_tid, main_prochandle.pid);
1877 /* If this is a new user thread, notify GDB about it. */
1878 if (!in_thread_list (retpid))
1879 {
1880 printf_filtered ("[New %s]\n", target_pid_to_str (retpid));
1881 add_thread (retpid);
1882 }
1883
1884#if 0
1885 /* Now detect if this is a thread creation/deletion event: */
1886 check_for_thread_event (ourstatus, retpid);
1887#endif
1888 return retpid;
1889}
1890
1891/*
1892 * kill has to call the underlying kill.
1893 * FIXME: I'm not sure if it's necessary to check inferior_pid any more,
1894 * but we might need to fix inferior_pid up if it's a user thread.
1895 */
1896
1897static int
1898kill_thread_callback (th, data)
1899 td_thrhandle_t *th;
1900 void *data;
1901{
1902 td_thrinfo_t ti;
1903 td_err_e ret;
1904
1905 /* Fixme:
1906 For Linux, threads may need to be waited. */
1907 if ((ret = p_td_thr_get_info (th, &ti)) != TD_OK)
1908 {
1909 warning ("kill_thread_callback: %s", thr_err_string (ret));
1910 return -1; /* bail out, get_info failed. */
1911 }
1912
1913 if (ti.ti_lid != main_prochandle.pid)
1914 {
1915 kill (ti.ti_lid, SIGKILL);
1916 }
1917 return 0;
1918}
1919
1920
1921static void thread_db_kill (void)
1922{
1923 int rpid;
1924 int status;
1925
1926 /* Fixme:
1927 For Linux, threads may need to be waited. */
1928 if (inferior_pid != 0)
1929 {
1930 /* Go kill the children first. Save the main thread for last. */
1931 p_td_ta_thr_iter (main_threadagent,
1932 kill_thread_callback,
1933 (void *) 0,
1934 TD_THR_ANY_STATE,
1935 TD_THR_LOWEST_PRIORITY,
1936 TD_SIGNO_MASK,
1937 TD_THR_ANY_USER_FLAGS);
1938
1939 /* Turn off thread_db event-reporting API *before* killing the
1940 main thread, since this operation requires child memory access.
1941 Can't move this into thread_db_unpush target because then
1942 detach would not work. */
1943 disable_thread_event_reporting (main_threadagent);
1944
1945 inferior_pid = main_prochandle.pid;
1946
1947 /*
1948 * Since both procfs_kill and ptrace_kill call target_mourn,
1949 * it should be sufficient for me to call one of them.
1950 * That will result in my mourn being called, which will both
1951 * unpush me and call the underlying mourn.
1952 */
1953 target_beneath->to_kill ();
1954 }
1955
1956 /* Wait for all threads. */
1957 /* FIXME: need a universal wait_for_signal func? */
1958 do
1959 {
1960 rpid = waitpid (-1, &status, __WCLONE | WNOHANG);
1961 }
1962 while (rpid > 0 || errno == EINTR);
1963
1964 do
1965 {
1966 rpid = waitpid (-1, &status, WNOHANG);
1967 }
1968 while (rpid > 0 || errno == EINTR);
1969}
1970
1971/*
1972 * Mourn has to remove us from the target stack,
1973 * and then call the underlying mourn.
1974 */
1975
1976static void thread_db_mourn_inferior (void)
1977{
1978 thread_db_unpush_target ();
1979 target_mourn_inferior (); /* call the underlying mourn */
1980}
1981
1982/*
1983 * Detach has to remove us from the target stack,
1984 * and then call the underlying detach.
1985 *
1986 * But first, it has to detach all the cloned threads!
1987 */
1988
1989static int
1990detach_thread_callback (th, data)
1991 td_thrhandle_t *th;
1992 void *data;
1993{
1994 /* Called once per thread. */
1995 td_thrinfo_t ti;
1996 td_err_e ret;
1997
1998 if ((ret = p_td_thr_get_info (th, &ti)) != TD_OK)
1999 {
2000 warning ("detach_thread_callback: %s", thr_err_string (ret));
2001 return -1; /* bail out, get_info failed. */
2002 }
2003
2004 if (!in_thread_list (BUILD_THREAD (ti.ti_tid, main_prochandle.pid)))
2005 return 0; /* apparently we don't know this one. */
2006
2007 /* Save main thread for last, or the iterator will fail! */
2008 if (ti.ti_lid != main_prochandle.pid)
2009 {
2010 struct cleanup *old_chain;
2011 int off = 0;
2012
2013 /* Time to detach this thread.
2014 First disable thread_db event reporting for the thread. */
2015 if (p_td_thr_event_enable &&
2016 (ret = p_td_thr_event_enable (th, off)) != TD_OK)
2017 {
2018 warning ("detach_thread_callback: %s\n", thr_err_string (ret));
2019 return 0;
2020 }
2021
2022 /* Now cancel any pending SIGTRAPS. FIXME! */
2023
2024 /* Call underlying detach method. FIXME just detach it. */
2025 old_chain = save_inferior_pid ();
2026 inferior_pid = ti.ti_lid;
2027 detach (TARGET_SIGNAL_0);
2028 do_cleanups (old_chain);
2029 }
2030 return 0;
2031}
2032
2033static void
2034thread_db_detach (char *args, int from_tty)
2035{
2036 td_err_e ret;
2037
2038 if ((ret = p_td_ta_thr_iter (main_threadagent,
2039 detach_thread_callback,
2040 (void *) 0,
2041 TD_THR_ANY_STATE,
2042 TD_THR_LOWEST_PRIORITY,
2043 TD_SIGNO_MASK,
2044 TD_THR_ANY_USER_FLAGS))
2045 != TD_OK)
2046 warning ("detach (thr_iter): %s", thr_err_string (ret));
2047
2048 /* Turn off thread_db event-reporting API
2049 (before detaching the main thread) */
2050 disable_thread_event_reporting (main_threadagent);
2051
2052 thread_db_unpush_target ();
2053
2054 /* above call nullifies target_beneath, so don't use that! */
2055 inferior_pid = PIDGET (inferior_pid);
2056 target_detach (args, from_tty);
2057}
2058
2059
2060/*
2061 * We never want to actually create the inferior!
2062 *
2063 * If this is ever called, it means we were on the target stack
2064 * when the user said "run". But we don't want to be on the new
2065 * inferior's target stack until the thread_db / libthread
2066 * connection is ready to be made.
2067 *
2068 * So, what shall we do?
2069 * Unpush ourselves from the stack, and then invoke
2070 * find_default_create_inferior, which will invoke the
2071 * appropriate process_stratum target to do the create.
2072 */
2073
2074static void
2075thread_db_create_inferior (exec_file, allargs, env)
2076 char *exec_file;
2077 char *allargs;
2078 char **env;
2079{
2080 thread_db_unpush_target ();
2081 find_default_create_inferior (exec_file, allargs, env);
2082}
2083
2084/*
2085 * Thread_db target vector initializer.
2086 */
2087
2088void
2089init_thread_db_ops ()
2090{
2091 thread_db_ops.to_shortname = "multi-thread";
2092 thread_db_ops.to_longname = "multi-threaded child process.";
2093 thread_db_ops.to_doc = "Threads and pthreads support.";
2094 thread_db_ops.to_files_info = thread_db_files_info;
2095 thread_db_ops.to_create_inferior = thread_db_create_inferior;
2096 thread_db_ops.to_detach = thread_db_detach;
2097 thread_db_ops.to_wait = thread_db_wait;
2098 thread_db_ops.to_resume = thread_db_resume;
2099 thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
2100 thread_db_ops.to_kill = thread_db_kill;
2101 thread_db_ops.to_xfer_memory = thread_db_xfer_memory;
2102 thread_db_ops.to_fetch_registers = thread_db_fetch_registers;
2103 thread_db_ops.to_store_registers = thread_db_store_registers;
2104 thread_db_ops.to_thread_alive = thread_db_alive;
2105 thread_db_ops.to_find_new_threads = thread_db_find_new_threads;
2106 thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
2107 thread_db_ops.to_stratum = thread_stratum;
2108 thread_db_ops.to_has_thread_control = tc_schedlock;
2109 thread_db_ops.to_magic = OPS_MAGIC;
2110}
2111#endif /* HAVE_STDINT_H */
2112
2113/*
2114 * Module constructor / initializer function.
2115 * If connection to thread_db dynamic library is successful,
2116 * then initialize this module's target vectors and the
2117 * new_objfile hook.
2118 */
2119
2120
2121void
2122_initialize_thread_db ()
2123{
2124#ifdef HAVE_STDINT_H /* stub out entire module, leave initializer empty */
2125 if (init_thread_db_library ())
2126 {
2127 init_thread_db_ops ();
2128 add_target (&thread_db_ops);
2129 /*
2130 * Hook up to the new_objfile event.
2131 * If someone is already there, arrange for him to be called
2132 * after we are.
2133 */
2134 target_new_objfile_chain = target_new_objfile_hook;
2135 target_new_objfile_hook = thread_db_new_objfile;
2136 }
2137#endif /* HAVE_STDINT_H */
2138}
2139
This page took 0.124025 seconds and 4 git commands to generate.