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