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