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