2 /* FreeBSD libthread_db assisted debugging support.
3 Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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. */
23 #include <sys/types.h>
24 #include <sys/ptrace.h>
27 #include "proc_service.h"
28 #include "thread_db.h"
33 #include "gdb_assert.h"
35 #include "gdbthread.h"
43 #include "solib-svr4.h"
47 #include "i387-tdep.h"
50 #define LIBTHREAD_DB_SO "libthread_db.so"
57 extern int child_suppress_run;
59 extern struct target_ops child_ops;
61 /* This module's target vectors. */
62 static struct target_ops fbsd_thread_ops;
63 static struct target_ops fbsd_core_ops;
65 /* Saved copy of orignal core_ops. */
66 static struct target_ops orig_core_ops;
67 extern struct target_ops core_ops;
69 /* Pointer to the next function on the objfile event chain. */
70 static void (*target_new_objfile_chain) (struct objfile *objfile);
72 /* Non-zero if there is a thread module */
73 static int fbsd_thread_present;
75 /* Non-zero if we're using this module's target vector. */
76 static int fbsd_thread_active;
78 /* Non-zero if core_open is called */
79 static int fbsd_thread_core = 0;
81 /* Non-zero if we have to keep this module's target vector active
83 static int keep_thread_db;
85 /* Structure that identifies the child process for the
86 <proc_service.h> interface. */
87 static struct ps_prochandle proc_handle;
89 /* Connection to the libthread_db library. */
90 static td_thragent_t *thread_agent;
92 /* The last thread we are single stepping */
93 static ptid_t last_single_step_thread;
95 /* Pointers to the libthread_db functions. */
97 static td_err_e (*td_init_p) (void);
99 static td_err_e (*td_ta_new_p) (struct ps_prochandle *ps, td_thragent_t **ta);
100 static td_err_e (*td_ta_delete_p) (td_thragent_t *);
101 static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
102 td_thrhandle_t *__th);
103 static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta, lwpid_t lwpid,
105 static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
106 td_thr_iter_f *callback,
107 void *cbdata_p, td_thr_state_e state,
108 int ti_pri, sigset_t *ti_sigmask_p,
109 unsigned int ti_user_flags);
110 static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
111 td_event_e event, td_notify_t *ptr);
112 static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
113 td_thr_events_t *event);
114 static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
115 td_event_msg_t *msg);
116 static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
117 td_thrinfo_t *infop);
119 static td_err_e (*td_thr_getxmmregs_p) (const td_thrhandle_t *th,
122 static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
123 prfpregset_t *regset);
124 static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
127 static td_err_e (*td_thr_setxmmregs_p) (const td_thrhandle_t *th,
130 static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
131 const prfpregset_t *fpregs);
132 static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
134 static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event);
136 static td_err_e (*td_thr_sstep_p) (td_thrhandle_t *th, int step);
138 static td_err_e (*td_ta_tsd_iter_p) (const td_thragent_t *ta,
139 td_key_iter_f *func, void *data);
140 static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
142 size_t offset, void **address);
143 static td_err_e (*td_thr_dbsuspend_p) (const td_thrhandle_t *);
144 static td_err_e (*td_thr_dbresume_p) (const td_thrhandle_t *);
146 static CORE_ADDR td_create_bp_addr;
148 /* Location of the thread death event breakpoint. */
149 static CORE_ADDR td_death_bp_addr;
151 /* Prototypes for local functions. */
152 static void fbsd_thread_find_new_threads (void);
153 static int fbsd_thread_alive (ptid_t ptid);
154 static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
155 const td_thrinfo_t *ti_p, int verbose);
156 static void fbsd_thread_detach (char *args, int from_tty);
158 /* Building process ids. */
160 #define GET_PID(ptid) ptid_get_pid (ptid)
161 #define GET_LWP(ptid) ptid_get_lwp (ptid)
162 #define GET_THREAD(ptid) ptid_get_tid (ptid)
164 #define IS_LWP(ptid) (GET_LWP (ptid) != 0)
165 #define IS_THREAD(ptid) (GET_THREAD (ptid) != 0)
167 #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
168 #define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
171 thread_db_err_str (td_err_e err)
178 return "generic 'call succeeded'";
180 return "generic error";
182 return "no thread to satisfy query";
184 return "no sync handle to satisfy query";
186 return "no LWP to satisfy query";
188 return "invalid process handle";
190 return "invalid thread handle";
192 return "invalid synchronization handle";
194 return "invalid thread agent";
196 return "invalid key";
198 return "no event message for getmsg";
200 return "FPU register set not available";
202 return "application not linked with libthread";
204 return "requested event is not supported";
206 return "capability not available";
208 return "debugger service failed";
210 return "operation not applicable to";
212 return "no thread-specific data for this thread";
214 return "malloc failed";
216 return "only part of register set was written/read";
218 return "X register set not available for this thread";
220 snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
226 thread_db_state_str (td_thr_state_e state)
233 return "stopped by debugger";
242 case TD_THR_STOPPED_ASLEEP:
243 return "stopped by debugger AND blocked";
245 snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
250 /* Convert LWP to user-level thread id. */
252 thread_from_lwp (ptid_t ptid, td_thrhandle_t *th, td_thrinfo_t *ti)
256 gdb_assert (IS_LWP (ptid));
258 if (fbsd_thread_active)
260 err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), th);
263 err = td_thr_get_info_p (th, ti);
265 error ("Cannot get thread info: %s", thread_db_err_str (err));
266 return BUILD_THREAD (ti->ti_tid, GET_PID (ptid));
270 /* the LWP is not mapped to user thread */
271 return BUILD_LWP (GET_LWP (ptid), GET_PID (ptid));
275 fbsd_core_get_first_lwp (bfd *abfd, asection *asect, void *obj)
277 if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
280 if (*(lwpid_t *)obj != 0)
283 *(lwpid_t *)obj = atoi (bfd_section_name (abfd, asect) + 5);
287 get_current_lwp (int pid)
289 struct ptrace_lwpinfo pl;
292 if (!target_has_execution)
295 bfd_map_over_sections (core_bfd, fbsd_core_get_first_lwp, &lwpid);
298 if (ptrace (PT_LWPINFO, pid, (caddr_t)&pl, sizeof(pl)))
299 perror_with_name("PT_LWPINFO");
301 return (long)pl.pl_lwpid;
305 get_current_thread ()
312 lwp = get_current_lwp (proc_handle.pid);
313 tmp = BUILD_LWP (lwp, proc_handle.pid);
314 ptid = thread_from_lwp (tmp, &th, &ti);
315 if (!in_thread_list (ptid))
317 attach_thread (ptid, &th, &ti, 1);
319 inferior_ptid = ptid;
323 enable_thread_event (td_thragent_t *thread_agent, int event, CORE_ADDR *bp)
328 /* Get the breakpoint address for thread EVENT. */
329 err = td_ta_event_addr_p (thread_agent, event, ¬ify);
333 /* Set up the breakpoint. */
334 (*bp) = gdbarch_convert_from_func_ptr_addr (current_gdbarch,
335 extract_typed_address(¬ify.u.bptaddr, builtin_type_void_func_ptr),
337 create_thread_event_breakpoint ((*bp));
343 enable_thread_event_reporting (void)
345 td_thr_events_t events;
349 /* We cannot use the thread event reporting facility if these
350 functions aren't available. */
351 if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
352 || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
355 /* Set the process wide mask saying which events we're interested in. */
356 td_event_emptyset (&events);
357 td_event_addset (&events, TD_CREATE);
358 td_event_addset (&events, TD_DEATH);
360 err = td_ta_set_event_p (thread_agent, &events);
363 warning ("Unable to set global thread event mask: %s",
364 thread_db_err_str (err));
368 /* Delete previous thread event breakpoints, if any. */
369 remove_thread_event_breakpoints ();
370 td_create_bp_addr = 0;
371 td_death_bp_addr = 0;
373 /* Set up the thread creation event. */
374 err = enable_thread_event (thread_agent, TD_CREATE, &td_create_bp_addr);
377 warning ("Unable to get location for thread creation breakpoint: %s",
378 thread_db_err_str (err));
382 /* Set up the thread death event. */
383 err = enable_thread_event (thread_agent, TD_DEATH, &td_death_bp_addr);
386 warning ("Unable to get location for thread death breakpoint: %s",
387 thread_db_err_str (err));
393 disable_thread_event_reporting (void)
395 td_thr_events_t events;
397 /* Set the process wide mask saying we aren't interested in any
399 td_event_emptyset (&events);
400 td_ta_set_event_p (thread_agent, &events);
402 /* Delete thread event breakpoints, if any. */
403 remove_thread_event_breakpoints ();
404 td_create_bp_addr = 0;
405 td_death_bp_addr = 0;
409 fbsd_thread_activate (void)
411 fbsd_thread_active = 1;
413 if (fbsd_thread_core == 0)
414 enable_thread_event_reporting ();
415 fbsd_thread_find_new_threads ();
416 get_current_thread ();
420 fbsd_thread_deactivate (void)
422 if (fbsd_thread_core == 0)
423 disable_thread_event_reporting();
424 td_ta_delete_p (thread_agent);
426 inferior_ptid = pid_to_ptid (proc_handle.pid);
428 fbsd_thread_active = 0;
429 fbsd_thread_present = 0;
434 fbsd_thread_get_name (lwpid_t lwpid)
436 static char last_thr_name[MAXCOMLEN + 1];
437 char section_name[32];
438 struct ptrace_lwpinfo lwpinfo;
440 struct bfd_section *section;
442 if (target_has_execution)
444 if (ptrace (PT_LWPINFO, lwpid, (caddr_t)&lwpinfo, sizeof (lwpinfo)) == -1)
446 strncpy (last_thr_name, lwpinfo.pl_tdname, sizeof (last_thr_name) - 1);
450 snprintf (section_name, sizeof (section_name), ".tname/%u", lwpid);
451 section = bfd_get_section_by_name (core_bfd, section_name);
455 /* Section size fix-up. */
456 size = bfd_section_size (core_bfd, section);
457 if (size > sizeof (last_thr_name))
458 size = sizeof (last_thr_name);
460 if (! bfd_get_section_contents (core_bfd, section, last_thr_name,
463 if (last_thr_name[0] == '\0')
466 last_thr_name[sizeof (last_thr_name) - 1] = '\0';
467 return last_thr_name;
469 strcpy (last_thr_name, "<unknown>");
470 return last_thr_name;
474 fbsd_thread_new_objfile (struct objfile *objfile)
480 /* All symbols have been discarded. If the thread_db target is
481 active, deactivate it now. */
482 if (fbsd_thread_active)
484 gdb_assert (proc_handle.pid == 0);
485 fbsd_thread_active = 0;
491 if (!child_suppress_run)
494 /* Nothing to do. The thread library was already detected and the
495 target vector was already activated. */
496 if (fbsd_thread_active)
499 /* Initialize the structure that identifies the child process. Note
500 that at this point there is no guarantee that we actually have a
502 proc_handle.pid = GET_PID (inferior_ptid);
504 /* Now attempt to open a connection to the thread library. */
505 err = td_ta_new_p (&proc_handle, &thread_agent);
509 /* No thread library was detected. */
513 /* The thread library was detected. Activate the thread_db target. */
514 fbsd_thread_present = 1;
516 /* We can only poke around if there actually is a child process.
517 If there is no child process alive, postpone the steps below
518 until one has been created. */
519 if (fbsd_thread_core == 0 && proc_handle.pid != 0)
521 push_target(&fbsd_thread_ops);
522 fbsd_thread_activate();
526 td_ta_delete_p(thread_agent);
532 warning ("Cannot initialize thread debugging library: %s",
533 thread_db_err_str (err));
538 if (target_new_objfile_chain)
539 target_new_objfile_chain (objfile);
543 fbsd_thread_attach (char *args, int from_tty)
545 fbsd_thread_core = 0;
547 child_ops.to_attach (args, from_tty);
549 /* Must get symbols from solibs before libthread_db can run! */
550 SOLIB_ADD ((char *) 0, from_tty, (struct target_ops *) 0, auto_solib_add);
552 if (fbsd_thread_present && !fbsd_thread_active)
553 push_target(&fbsd_thread_ops);
557 fbsd_thread_post_attach (int pid)
559 child_ops.to_post_attach (pid);
561 if (fbsd_thread_present && !fbsd_thread_active)
563 proc_handle.pid = GET_PID (inferior_ptid);
564 fbsd_thread_activate ();
569 fbsd_thread_detach (char *args, int from_tty)
571 fbsd_thread_deactivate ();
572 unpush_target (&fbsd_thread_ops);
574 /* Clear gdb solib information and symbol file
575 cache, so that after detach and re-attach, new_objfile
576 hook will be called */
579 symbol_file_clear(0);
581 child_ops.to_detach (args, from_tty);
585 suspend_thread_callback (const td_thrhandle_t *th_p, void *data)
587 int err = td_thr_dbsuspend_p (th_p);
589 fprintf_filtered(gdb_stderr, "%s %s\n", __func__, thread_db_err_str (err));
594 resume_thread_callback (const td_thrhandle_t *th_p, void *data)
596 int err = td_thr_dbresume_p (th_p);
598 fprintf_filtered(gdb_stderr, "%s %s\n", __func__, thread_db_err_str (err));
603 fbsd_thread_resume (ptid_t ptid, int step, enum target_signal signo)
609 long lwp, thvalid = 0;
611 if (!fbsd_thread_active)
613 child_ops.to_resume (ptid, step, signo);
617 if (GET_PID(ptid) != -1 && step != 0)
625 work_ptid = inferior_ptid;
628 lwp = GET_LWP (work_ptid);
631 /* check user thread */
632 ret = td_ta_map_id2thr_p (thread_agent, GET_THREAD(work_ptid), &th);
634 error (thread_db_err_str (ret));
636 /* For M:N thread, we need to tell UTS to set/unset single step
637 flag at context switch time, the flag will be written into
638 thread mailbox. This becauses some architecture may not have
639 machine single step flag in ucontext, so we put the flag in mailbox,
640 when the thread switches back, kse_switchin restores the single step
642 ret = td_thr_sstep_p (&th, step);
644 error (thread_db_err_str (ret));
645 ret = td_thr_get_info_p (&th, &ti);
647 error (thread_db_err_str (ret));
654 int req = step ? PT_SETSTEP : PT_CLEARSTEP;
655 if (ptrace (req, (pid_t) lwp, (caddr_t) 1, target_signal_to_host(signo)))
656 perror_with_name ("PT_SETSTEP/PT_CLEARSTEP");
659 if (!ptid_equal (last_single_step_thread, null_ptid))
661 ret = td_ta_thr_iter_p (thread_agent, resume_thread_callback, NULL,
662 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
663 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
665 error ("resume error: %s", thread_db_err_str (ret));
670 ret = td_ta_thr_iter_p (thread_agent, suspend_thread_callback, NULL,
671 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
672 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
674 error ("suspend error: %s", thread_db_err_str (ret));
675 last_single_step_thread = work_ptid;
678 last_single_step_thread = null_ptid;
682 ret = td_thr_dbresume_p (&th);
684 error ("resume error: %s", thread_db_err_str (ret));
688 /* it is not necessary, put it here for completness */
689 ret = ptrace(PT_RESUME, lwp, 0, 0);
692 /* now continue the process, suspended thread wont run */
693 if (ptrace (PT_CONTINUE, proc_handle.pid , (caddr_t)1,
694 target_signal_to_host(signo)))
695 perror_with_name ("PT_CONTINUE");
699 attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
700 const td_thrinfo_t *ti_p, int verbose)
704 /* Add the thread to GDB's thread list. */
705 if (!in_thread_list (ptid)) {
708 printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid));
711 if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE)
712 return; /* A zombie thread -- do not attach. */
714 if (! IS_THREAD(ptid))
716 if (fbsd_thread_core != 0)
718 /* Enable thread event reporting for this thread. */
719 err = td_thr_event_enable_p (th_p, 1);
721 error ("Cannot enable thread event reporting for %s: %s",
722 target_pid_to_str (ptid), thread_db_err_str (err));
726 detach_thread (ptid_t ptid, int verbose)
729 printf_unfiltered ("[%s exited]\n", target_pid_to_str (ptid));
733 check_event (ptid_t ptid)
741 /* Bail out early if we're not at a thread event breakpoint. */
742 stop_pc = read_pc_pid (ptid) - DECR_PC_AFTER_BREAK;
743 if (stop_pc != td_create_bp_addr && stop_pc != td_death_bp_addr)
749 err = td_ta_event_getmsg_p (thread_agent, &msg);
754 error ("Cannot get thread event message: %s",
755 thread_db_err_str (err));
757 err = td_thr_get_info_p ((void *)(uintptr_t)msg.th_p, &ti);
759 error ("Cannot get thread info: %s", thread_db_err_str (err));
760 ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid));
764 /* We may already know about this thread, for instance when the
765 user has issued the `info threads' command before the SIGTRAP
766 for hitting the thread creation breakpoint was reported. */
767 attach_thread (ptid, (void *)(uintptr_t)msg.th_p, &ti, 1);
770 if (!in_thread_list (ptid))
771 error ("Spurious thread death event.");
772 detach_thread (ptid, 1);
775 error ("Spurious thread event.");
782 fbsd_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
790 ret = child_ops.to_wait (ptid, ourstatus);
791 if (GET_PID(ret) >= 0 && ourstatus->kind == TARGET_WAITKIND_STOPPED)
793 lwp = get_current_lwp (GET_PID(ret));
794 ret = thread_from_lwp (BUILD_LWP(lwp, GET_PID(ret)),
796 if (!in_thread_list(ret)) {
798 * We have to enable event reporting for initial thread
799 * which was not mapped before.
801 attach_thread(ret, &th, &ti, 1);
803 if (ourstatus->value.sig == TARGET_SIGNAL_TRAP)
805 /* this is a hack, if an event won't cause gdb to stop, for example,
806 SIGARLM, gdb resumes the process immediatly without setting
807 inferior_ptid to the new thread returned here, this is a bug
808 because inferior_ptid may already not exist there, and passing
809 a none existing thread to fbsd_thread_resume causes error. */
810 if (!fbsd_thread_alive (inferior_ptid))
812 delete_thread (inferior_ptid);
821 fbsd_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
822 struct mem_attrib *attrib, struct target_ops *target)
826 if (target_has_execution)
827 err = child_ops.to_xfer_memory (memaddr, myaddr, len, write, attrib,
830 err = orig_core_ops.to_xfer_memory (memaddr, myaddr, len, write, attrib,
837 fbsd_lwp_fetch_registers (int regno)
846 if (!target_has_execution)
848 orig_core_ops.to_fetch_registers (-1);
852 /* XXX: We've replaced the pid with the lwpid for GDB's benefit. */
853 lwp = GET_PID (inferior_ptid);
855 if (ptrace (PT_GETREGS, lwp, (caddr_t) &gregs, 0) == -1)
856 error ("Cannot get lwp %d registers: %s\n", lwp, safe_strerror (errno));
857 supply_gregset (&gregs);
860 if (ptrace (PT_GETXMMREGS, lwp, xmmregs, 0) == 0)
862 i387_supply_fxsave (current_regcache, -1, xmmregs);
867 if (ptrace (PT_GETFPREGS, lwp, (caddr_t) &fpregs, 0) == -1)
868 error ("Cannot get lwp %d registers: %s\n ", lwp, safe_strerror (errno));
869 supply_fpregset (&fpregs);
876 fbsd_thread_fetch_registers (int regno)
879 prfpregset_t fpregset;
886 if (!IS_THREAD (inferior_ptid))
888 fbsd_lwp_fetch_registers (regno);
892 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
894 error ("Cannot find thread %d: Thread ID=%ld, %s",
895 pid_to_thread_id (inferior_ptid),
896 GET_THREAD (inferior_ptid), thread_db_err_str (err));
898 err = td_thr_getgregs_p (&th, gregset);
900 error ("Cannot fetch general-purpose registers for thread %d: Thread ID=%ld, %s",
901 pid_to_thread_id (inferior_ptid),
902 GET_THREAD (inferior_ptid), thread_db_err_str (err));
904 err = td_thr_getxmmregs_p (&th, xmmregs);
907 i387_supply_fxsave (current_regcache, -1, xmmregs);
912 err = td_thr_getfpregs_p (&th, &fpregset);
914 error ("Cannot get floating-point registers for thread %d: Thread ID=%ld, %s",
915 pid_to_thread_id (inferior_ptid),
916 GET_THREAD (inferior_ptid), thread_db_err_str (err));
917 supply_fpregset (&fpregset);
922 supply_gregset (gregset);
926 fbsd_lwp_store_registers (int regno)
935 /* FIXME, is it possible ? */
936 if (!IS_LWP (inferior_ptid))
938 child_ops.to_store_registers (regno);
942 lwp = GET_LWP (inferior_ptid);
944 if (ptrace (PT_GETREGS, lwp, (caddr_t) &gregs, 0) == -1)
945 error ("Cannot get lwp %d registers: %s\n", lwp, safe_strerror (errno));
947 fill_gregset (&gregs, regno);
948 if (ptrace (PT_SETREGS, lwp, (caddr_t) &gregs, 0) == -1)
949 error ("Cannot set lwp %d registers: %s\n", lwp, safe_strerror (errno));
953 if (ptrace (PT_GETXMMREGS, lwp, xmmregs, 0) == -1)
956 i387_fill_fxsave (xmmregs, regno);
957 if (ptrace (PT_SETXMMREGS, lwp, xmmregs, 0) == -1)
966 if (ptrace (PT_GETFPREGS, lwp, (caddr_t) &fpregs, 0) == -1)
967 error ("Cannot get lwp %d float registers: %s\n", lwp,
968 safe_strerror (errno));
970 fill_fpregset (&fpregs, regno);
971 if (ptrace (PT_SETFPREGS, lwp, (caddr_t) &fpregs, 0) == -1)
972 error ("Cannot set lwp %d float registers: %s\n", lwp,
973 safe_strerror (errno));
977 fbsd_thread_store_registers (int regno)
980 prfpregset_t fpregset;
987 if (!IS_THREAD (inferior_ptid))
989 fbsd_lwp_store_registers (regno);
993 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
995 error ("Cannot find thread %d: Thread ID=%ld, %s",
996 pid_to_thread_id (inferior_ptid),
997 GET_THREAD (inferior_ptid),
998 thread_db_err_str (err));
1002 char old_value[MAX_REGISTER_SIZE];
1004 regcache_collect (regno, old_value);
1005 err = td_thr_getgregs_p (&th, gregset);
1007 error ("%s: td_thr_getgregs %s", __func__, thread_db_err_str (err));
1008 #ifdef PT_GETXMMREGS
1009 err = td_thr_getxmmregs_p (&th, xmmregs);
1013 err = td_thr_getfpregs_p (&th, &fpregset);
1015 error ("%s: td_thr_getfpgregs %s", __func__, thread_db_err_str (err));
1016 #ifdef PT_GETXMMREGS
1019 supply_register (regno, old_value);
1022 fill_gregset (gregset, regno);
1023 err = td_thr_setgregs_p (&th, gregset);
1025 error ("Cannot store general-purpose registers for thread %d: Thread ID=%d, %s",
1026 pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid),
1027 thread_db_err_str (err));
1029 #ifdef PT_GETXMMREGS
1030 i387_fill_fxsave (xmmregs, regno);
1031 err = td_thr_setxmmregs_p (&th, xmmregs);
1036 fill_fpregset (&fpregset, regno);
1037 err = td_thr_setfpregs_p (&th, &fpregset);
1039 error ("Cannot store floating-point registers for thread %d: Thread ID=%d, %s",
1040 pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid),
1041 thread_db_err_str (err));
1045 fbsd_thread_kill (void)
1047 child_ops.to_kill();
1051 fbsd_thread_can_run (void)
1053 return child_suppress_run;
1057 fbsd_thread_create_inferior (char *exec_file, char *allargs, char **env)
1059 if (fbsd_thread_present && !fbsd_thread_active)
1060 push_target(&fbsd_thread_ops);
1062 child_ops.to_create_inferior (exec_file, allargs, env);
1066 fbsd_thread_post_startup_inferior (ptid_t ptid)
1068 if (fbsd_thread_present && !fbsd_thread_active)
1070 /* The child process is now the actual multi-threaded
1071 program. Snatch its process ID... */
1072 proc_handle.pid = GET_PID (ptid);
1073 td_ta_new_p (&proc_handle, &thread_agent);
1074 fbsd_thread_activate();
1079 fbsd_thread_mourn_inferior (void)
1081 if (fbsd_thread_active)
1082 fbsd_thread_deactivate ();
1084 unpush_target (&fbsd_thread_ops);
1086 child_ops.to_mourn_inferior ();
1090 fbsd_core_check_lwp (bfd *abfd, asection *asect, void *obj)
1094 if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
1098 if (*(lwpid_t *)obj == 0)
1101 lwp = atoi (bfd_section_name (abfd, asect) + 5);
1102 if (*(lwpid_t *)obj == lwp)
1103 *(lwpid_t *)obj = 0;
1107 fbsd_thread_alive (ptid_t ptid)
1115 if (IS_THREAD (ptid))
1117 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
1121 err = td_thr_get_info_p (&th, &ti);
1125 /* A zombie thread. */
1126 if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
1131 else if (GET_LWP (ptid) == 0)
1133 /* we sometimes are called with lwp == 0 */
1137 if (fbsd_thread_active)
1139 err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
1142 * if the lwp was already mapped to user thread, don't use it
1143 * directly, please use user thread id instead.
1149 if (!target_has_execution)
1151 lwp = GET_LWP (ptid);
1152 bfd_map_over_sections (core_bfd, fbsd_core_check_lwp, &lwp);
1156 /* check lwp in kernel */
1157 return ptrace (PT_GETREGS, GET_LWP (ptid), (caddr_t)&gregs, 0) == 0;
1161 fbsd_thread_files_info (struct target_ops *ignore)
1163 child_ops.to_files_info (ignore);
1167 find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
1173 err = td_thr_get_info_p (th_p, &ti);
1175 error ("Cannot get thread info: %s", thread_db_err_str (err));
1178 if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
1181 ptid = BUILD_THREAD (ti.ti_tid, proc_handle.pid);
1182 attach_thread (ptid, th_p, &ti, 1);
1187 fbsd_thread_find_new_threads (void)
1191 if (!fbsd_thread_active)
1194 /* Iterate over all user-space threads to discover new threads. */
1195 err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
1196 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1197 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1199 error ("Cannot find new threads: %s", thread_db_err_str (err));
1203 fbsd_thread_pid_to_str (ptid_t ptid)
1205 static char buf[64 + MAXCOMLEN];
1207 if (IS_THREAD (ptid))
1213 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
1215 error ("Cannot find thread, Thread ID=%ld, %s",
1216 GET_THREAD (ptid), thread_db_err_str (err));
1218 err = td_thr_get_info_p (&th, &ti);
1220 error ("Cannot get thread info, Thread ID=%ld, %s",
1221 GET_THREAD (ptid), thread_db_err_str (err));
1225 snprintf (buf, sizeof (buf), "Thread %llx (LWP %d/%s)",
1226 (unsigned long long)th.th_thread, ti.ti_lid,
1227 fbsd_thread_get_name (ti.ti_lid));
1231 snprintf (buf, sizeof (buf), "Thread %llx (%s)",
1232 (unsigned long long)th.th_thread,
1233 thread_db_state_str (ti.ti_state));
1238 else if (IS_LWP (ptid))
1240 snprintf (buf, sizeof (buf), "LWP %d", (int) GET_LWP (ptid));
1243 return normal_pid_to_str (ptid);
1247 fbsd_thread_get_local_address(ptid_t ptid, struct objfile *objfile,
1254 int ret, is_library = (objfile->flags & OBJF_SHARED);
1256 if (IS_THREAD (ptid))
1258 if (!td_thr_tls_get_addr_p)
1259 error ("Cannot find thread-local interface in thread_db library.");
1261 /* Get the address of the link map for this objfile. */
1262 lm = svr4_fetch_objfile_link_map (objfile);
1264 /* Couldn't find link map. Bail out. */
1268 error ("Cannot find shared library `%s' link_map in dynamic"
1269 " linker's module list", objfile->name);
1271 error ("Cannot find executable file `%s' link_map in dynamic"
1272 " linker's module list", objfile->name);
1275 ret = td_ta_map_id2thr_p (thread_agent, GET_THREAD(ptid), &th);
1277 /* get the address of the variable. */
1278 store_typed_address(&lm2, builtin_type_void_data_ptr, lm);
1279 ret = td_thr_tls_get_addr_p (&th, lm2, offset, &address);
1284 error ("Cannot find thread-local storage for thread %ld, "
1285 "shared library %s:\n%s",
1286 (long) GET_THREAD (ptid),
1287 objfile->name, thread_db_err_str (ret));
1289 error ("Cannot find thread-local storage for thread %ld, "
1290 "executable file %s:\n%s",
1291 (long) GET_THREAD (ptid),
1292 objfile->name, thread_db_err_str (ret));
1295 /* Cast assuming host == target. */
1296 return extract_typed_address(&address, builtin_type_void_data_ptr);
1302 tsd_cb (thread_key_t key, void (*destructor)(void *), void *ignore)
1304 struct minimal_symbol *ms;
1307 ms = lookup_minimal_symbol_by_pc (
1308 extract_typed_address(&destructor, builtin_type_void_func_ptr));
1312 name = DEPRECATED_SYMBOL_NAME (ms);
1314 printf_filtered ("Destructor %p <%s>\n", destructor, name);
1319 fbsd_thread_tsd_cmd (char *exp, int from_tty)
1321 if (fbsd_thread_active)
1322 td_ta_tsd_iter_p (thread_agent, tsd_cb, NULL);
1326 fbsd_print_sigset (sigset_t *set)
1330 for (i = 1; i <= _SIG_MAXSIG; ++i) {
1331 if (sigismember(set, i)) {
1332 if (i < sizeof(sys_signame)/sizeof(sys_signame[0]))
1333 printf_filtered("%s ", sys_signame[i]);
1335 printf_filtered("sig%d ", i);
1338 printf_filtered("\n");
1342 fbsd_thread_signal_cmd (char *exp, int from_tty)
1349 if (!fbsd_thread_active || !IS_THREAD(inferior_ptid))
1352 err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
1356 err = td_thr_get_info_p (&th, &ti);
1360 printf_filtered("signal mask:\n");
1361 fbsd_print_sigset(&ti.ti_sigmask);
1362 printf_filtered("signal pending:\n");
1363 fbsd_print_sigset(&ti.ti_pending);
1364 if (ti.ti_siginfo.si_signo != 0) {
1365 printf_filtered("si_signo %d si_errno %d", ti.ti_siginfo.si_signo,
1366 ti.ti_siginfo.si_errno);
1367 if (ti.ti_siginfo.si_errno != 0)
1368 printf_filtered(" (%s)", strerror(ti.ti_siginfo.si_errno));
1369 printf_filtered("\n");
1370 switch (ti.ti_siginfo.si_code) {
1396 printf_filtered("si_code %s (%d) si_pid %d si_uid %d si_status %x "
1398 code, ti.ti_siginfo.si_code, ti.ti_siginfo.si_pid, ti.ti_siginfo.si_uid,
1399 ti.ti_siginfo.si_status, ti.ti_siginfo.si_addr);
1404 ignore (CORE_ADDR addr, char *contents)
1410 fbsd_core_open (char *filename, int from_tty)
1414 fbsd_thread_core = 1;
1416 orig_core_ops.to_open (filename, from_tty);
1418 if (fbsd_thread_present)
1420 err = td_ta_new_p (&proc_handle, &thread_agent);
1423 proc_handle.pid = elf_tdata (core_bfd)->core_pid;
1424 fbsd_thread_activate ();
1427 error ("fbsd_core_open: td_ta_new: %s", thread_db_err_str (err));
1432 fbsd_core_close (int quitting)
1434 orig_core_ops.to_close (quitting);
1438 fbsd_core_detach (char *args, int from_tty)
1440 if (fbsd_thread_active)
1441 fbsd_thread_deactivate ();
1442 unpush_target (&fbsd_thread_ops);
1443 orig_core_ops.to_detach (args, from_tty);
1445 /* Clear gdb solib information and symbol file
1446 cache, so that after detach and re-attach, new_objfile
1447 hook will be called */
1449 symbol_file_clear(0);
1453 fbsd_core_files_info (struct target_ops *ignore)
1455 orig_core_ops.to_files_info (ignore);
1459 init_fbsd_core_ops (void)
1461 fbsd_core_ops.to_shortname = "FreeBSD-core";
1462 fbsd_core_ops.to_longname = "FreeBSD multithreaded core dump file";
1463 fbsd_core_ops.to_doc =
1464 "Use a core file as a target. Specify the filename of the core file.";
1465 fbsd_core_ops.to_open = fbsd_core_open;
1466 fbsd_core_ops.to_close = fbsd_core_close;
1467 fbsd_core_ops.to_attach = 0;
1468 fbsd_core_ops.to_post_attach = 0;
1469 fbsd_core_ops.to_detach = fbsd_core_detach;
1470 /* fbsd_core_ops.to_resume = 0; */
1471 /* fbsd_core_ops.to_wait = 0; */
1472 fbsd_core_ops.to_fetch_registers = fbsd_thread_fetch_registers;
1473 /* fbsd_core_ops.to_store_registers = 0; */
1474 /* fbsd_core_ops.to_prepare_to_store = 0; */
1475 fbsd_core_ops.to_xfer_memory = fbsd_thread_xfer_memory;
1476 fbsd_core_ops.to_files_info = fbsd_core_files_info;
1477 fbsd_core_ops.to_insert_breakpoint = ignore;
1478 fbsd_core_ops.to_remove_breakpoint = ignore;
1479 /* fbsd_core_ops.to_lookup_symbol = 0; */
1480 fbsd_core_ops.to_create_inferior = fbsd_thread_create_inferior;
1481 fbsd_core_ops.to_stratum = core_stratum;
1482 fbsd_core_ops.to_has_all_memory = 0;
1483 fbsd_core_ops.to_has_memory = 1;
1484 fbsd_core_ops.to_has_stack = 1;
1485 fbsd_core_ops.to_has_registers = 1;
1486 fbsd_core_ops.to_has_execution = 0;
1487 fbsd_core_ops.to_has_thread_control = tc_none;
1488 fbsd_core_ops.to_thread_alive = fbsd_thread_alive;
1489 fbsd_core_ops.to_pid_to_str = fbsd_thread_pid_to_str;
1490 fbsd_core_ops.to_find_new_threads = fbsd_thread_find_new_threads;
1491 fbsd_core_ops.to_sections = 0;
1492 fbsd_core_ops.to_sections_end = 0;
1493 fbsd_core_ops.to_magic = OPS_MAGIC;
1497 init_fbsd_thread_ops (void)
1499 fbsd_thread_ops.to_shortname = "freebsd-threads";
1500 fbsd_thread_ops.to_longname = "FreeBSD multithreaded child process.";
1501 fbsd_thread_ops.to_doc = "FreeBSD threads support.";
1502 fbsd_thread_ops.to_attach = fbsd_thread_attach;
1503 fbsd_thread_ops.to_detach = fbsd_thread_detach;
1504 fbsd_thread_ops.to_post_attach = fbsd_thread_post_attach;
1505 fbsd_thread_ops.to_resume = fbsd_thread_resume;
1506 fbsd_thread_ops.to_wait = fbsd_thread_wait;
1507 fbsd_thread_ops.to_fetch_registers = fbsd_thread_fetch_registers;
1508 fbsd_thread_ops.to_store_registers = fbsd_thread_store_registers;
1509 fbsd_thread_ops.to_xfer_memory = fbsd_thread_xfer_memory;
1510 fbsd_thread_ops.to_files_info = fbsd_thread_files_info;
1511 fbsd_thread_ops.to_kill = fbsd_thread_kill;
1512 fbsd_thread_ops.to_create_inferior = fbsd_thread_create_inferior;
1513 fbsd_thread_ops.to_post_startup_inferior = fbsd_thread_post_startup_inferior;
1514 fbsd_thread_ops.to_mourn_inferior = fbsd_thread_mourn_inferior;
1515 fbsd_thread_ops.to_can_run = fbsd_thread_can_run;
1516 fbsd_thread_ops.to_thread_alive = fbsd_thread_alive;
1517 fbsd_thread_ops.to_find_new_threads = fbsd_thread_find_new_threads;
1518 fbsd_thread_ops.to_pid_to_str = fbsd_thread_pid_to_str;
1519 fbsd_thread_ops.to_stratum = thread_stratum;
1520 fbsd_thread_ops.to_has_thread_control = tc_none;
1521 fbsd_thread_ops.to_has_all_memory = 1;
1522 fbsd_thread_ops.to_has_memory = 1;
1523 fbsd_thread_ops.to_has_stack = 1;
1524 fbsd_thread_ops.to_has_registers = 1;
1525 fbsd_thread_ops.to_has_execution = 1;
1526 fbsd_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
1527 fbsd_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
1528 fbsd_thread_ops.to_get_thread_local_address = fbsd_thread_get_local_address;
1529 fbsd_thread_ops.to_magic = OPS_MAGIC;
1533 thread_db_load (void)
1538 handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
1542 #define resolve(X) \
1543 if (!(X##_p = dlsym (handle, #X))) \
1548 resolve(td_ta_delete);
1549 resolve(td_ta_map_id2thr);
1550 resolve(td_ta_map_lwp2thr);
1551 resolve(td_ta_thr_iter);
1552 resolve(td_thr_get_info);
1553 #ifdef PT_GETXMMREGS
1554 resolve(td_thr_getxmmregs);
1556 resolve(td_thr_getfpregs);
1557 resolve(td_thr_getgregs);
1558 #ifdef PT_GETXMMREGS
1559 resolve(td_thr_setxmmregs);
1561 resolve(td_thr_setfpregs);
1562 resolve(td_thr_setgregs);
1563 resolve(td_thr_sstep);
1564 resolve(td_ta_tsd_iter);
1565 resolve(td_thr_dbsuspend);
1566 resolve(td_thr_dbresume);
1567 resolve(td_thr_tls_get_addr);
1569 /* Initialize the library. */
1573 warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
1577 /* These are not essential. */
1578 td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
1579 td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
1580 td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
1581 td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
1582 td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
1587 /* we suppress the call to add_target of core_ops in corelow because
1588 if there are two targets in the stratum core_stratum, find_core_target
1589 won't know which one to return. see corelow.c for an additonal
1590 comment on coreops_suppress_target. */
1592 int coreops_suppress_target = 1;
1594 /* similarly we allow this target to be completely skipped. This is used
1595 by kgdb which uses its own core target. */
1597 int fbsdcoreops_suppress_target;
1600 _initialize_thread_db (void)
1603 if (fbsdcoreops_suppress_target)
1605 init_fbsd_thread_ops ();
1606 init_fbsd_core_ops ();
1608 if (thread_db_load ())
1610 add_target (&fbsd_thread_ops);
1612 /* "thread tsd" command */
1613 add_cmd ("tsd", class_run, fbsd_thread_tsd_cmd,
1614 "Show the thread-specific data keys and destructors "
1615 "for the process.\n",
1618 add_cmd ("signal", class_run, fbsd_thread_signal_cmd,
1619 "Show the thread signal info.\n",
1622 memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
1623 memcpy (&core_ops, &fbsd_core_ops, sizeof (struct target_ops));
1624 add_target (&core_ops);
1626 /* Add ourselves to objfile event chain. */
1627 target_new_objfile_chain = target_new_objfile_hook;
1628 target_new_objfile_hook = fbsd_thread_new_objfile;
1630 child_suppress_run = 1;
1634 fprintf_unfiltered (gdb_stderr,
1635 "[GDB will not be able to debug user-mode threads: %s]\n", dlerror());
1637 /* allow the user to debug non-threaded core files */
1638 add_target (&core_ops);
1642 /* proc service functions */
1644 ps_plog (const char *fmt, ...)
1648 va_start (args, fmt);
1649 vfprintf_filtered (gdb_stderr, fmt, args);
1654 ps_pglobal_lookup (struct ps_prochandle *ph, const char *obj,
1655 const char *name, psaddr_t *sym_addr)
1657 struct minimal_symbol *ms;
1660 ms = lookup_minimal_symbol (name, NULL, NULL);
1664 addr = SYMBOL_VALUE_ADDRESS (ms);
1665 store_typed_address(sym_addr, builtin_type_void_data_ptr, addr);
1670 ps_pread (struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t len)
1672 int err = target_read_memory (
1673 extract_typed_address(&addr, builtin_type_void_data_ptr), buf, len);
1674 return (err == 0 ? PS_OK : PS_ERR);
1678 ps_pwrite (struct ps_prochandle *ph, psaddr_t addr, const void *buf,
1681 int err = target_write_memory (
1682 extract_typed_address(&addr, builtin_type_void_data_ptr), (void *)buf, len);
1683 return (err == 0 ? PS_OK : PS_ERR);
1687 ps_lgetregs (struct ps_prochandle *ph, lwpid_t lwpid, prgregset_t gregset)
1689 struct cleanup *old_chain;
1691 old_chain = save_inferior_ptid ();
1693 /* XXX: Target operation isn't lwp aware: replace pid with lwp */
1694 inferior_ptid = BUILD_LWP (0, lwpid);
1696 target_fetch_registers (-1);
1697 fill_gregset (gregset, -1);
1698 do_cleanups (old_chain);
1703 ps_lsetregs (struct ps_prochandle *ph, lwpid_t lwpid, const prgregset_t gregset)
1705 struct cleanup *old_chain;
1707 old_chain = save_inferior_ptid ();
1708 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1709 supply_gregset ((gdb_gregset_t *) gregset);
1710 target_store_registers (-1);
1711 do_cleanups (old_chain);
1716 ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid, prfpregset_t *fpregset)
1718 struct cleanup *old_chain;
1720 old_chain = save_inferior_ptid ();
1721 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1722 target_fetch_registers (-1);
1723 fill_fpregset (fpregset, -1);
1724 do_cleanups (old_chain);
1729 ps_lsetfpregs (struct ps_prochandle *ph, lwpid_t lwpid,
1730 const prfpregset_t *fpregset)
1732 struct cleanup *old_chain;
1734 old_chain = save_inferior_ptid ();
1735 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1736 supply_fpregset ((gdb_fpregset_t *) fpregset);
1737 target_store_registers (-1);
1738 do_cleanups (old_chain);
1742 #ifdef PT_GETXMMREGS
1744 ps_lgetxmmregs (struct ps_prochandle *ph, lwpid_t lwpid, char *xmmregs)
1746 struct cleanup *old_chain;
1748 old_chain = save_inferior_ptid ();
1749 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1750 target_fetch_registers (-1);
1751 i387_fill_fxsave (xmmregs, -1);
1752 do_cleanups (old_chain);
1757 ps_lsetxmmregs (struct ps_prochandle *ph, lwpid_t lwpid,
1758 const char *xmmregs)
1760 struct cleanup *old_chain;
1762 old_chain = save_inferior_ptid ();
1763 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1764 i387_supply_fxsave (current_regcache, -1, xmmregs);
1765 target_store_registers (-1);
1766 do_cleanups (old_chain);
1772 ps_lstop(struct ps_prochandle *ph, lwpid_t lwpid)
1774 if (ptrace (PT_SUSPEND, lwpid, 0, 0) == -1)
1780 ps_lcontinue(struct ps_prochandle *ph, lwpid_t lwpid)
1782 if (ptrace (PT_RESUME, lwpid, 0, 0) == -1)
1788 ps_linfo(struct ps_prochandle *ph, lwpid_t lwpid, void *info)
1790 if (fbsd_thread_core) {
1791 /* XXX should verify lwpid and make a pseudo lwp info */
1792 memset(info, 0, sizeof(struct ptrace_lwpinfo));
1796 if (ptrace (PT_LWPINFO, lwpid, info, sizeof(struct ptrace_lwpinfo)) == -1)