X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ffbsd-nat.c;h=1d189a250136525244ea0adfe8071b6500fdcdaf;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=08976da2263acfed599ca6571c542e8242fc7a7f;hpb=f6ac5f3d63e03a81c4ff3749aba234961cc9090e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c index 08976da226..1d189a2501 100644 --- a/gdb/fbsd-nat.c +++ b/gdb/fbsd-nat.c @@ -1,6 +1,6 @@ /* Native-dependent code for FreeBSD. - Copyright (C) 2002-2018 Free Software Foundation, Inc. + Copyright (C) 2002-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -18,14 +18,15 @@ along with this program. If not, see . */ #include "defs.h" -#include "byte-vector.h" +#include "gdbsupport/byte-vector.h" #include "gdbcore.h" #include "inferior.h" #include "regcache.h" #include "regset.h" +#include "gdbarch.h" #include "gdbcmd.h" #include "gdbthread.h" -#include "gdb_wait.h" +#include "gdbsupport/gdb_wait.h" #include "inf-ptrace.h" #include #include @@ -37,7 +38,7 @@ #include #endif #if !defined(HAVE_KINFO_GETVMMAP) -#include "filestuff.h" +#include "gdbsupport/filestuff.h" #endif #include "elf-bfd.h" @@ -92,7 +93,7 @@ int fbsd_nat_target::find_memory_regions (find_memory_region_ftype func, void *obfd) { - pid_t pid = ptid_get_pid (inferior_ptid); + pid_t pid = inferior_ptid.pid (); struct kinfo_vmentry *kve; uint64_t size; int i, nitems; @@ -166,7 +167,7 @@ int fbsd_nat_target::find_memory_regions (find_memory_region_ftype func, void *obfd) { - pid_t pid = ptid_get_pid (inferior_ptid); + pid_t pid = inferior_ptid.pid (); unsigned long start, end, size; char protection[4]; int read, write, exec; @@ -231,6 +232,13 @@ fbsd_fetch_cmdline (pid_t pid) if (sysctl (mib, 4, cmdline.get (), &len, NULL, 0) == -1) return nullptr; + /* Join the arguments with spaces to form a single string. */ + char *cp = cmdline.get (); + for (size_t i = 0; i < len - 1; i++) + if (cp[i] == '\0') + cp[i] = ' '; + cp[len - 1] = '\0'; + return cmdline; } @@ -261,11 +269,13 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what) int nfd = 0; #endif struct kinfo_proc kp; - char *tmp; pid_t pid; bool do_cmdline = false; bool do_cwd = false; bool do_exe = false; +#ifdef HAVE_KINFO_GETFILE + bool do_files = false; +#endif #ifdef HAVE_KINFO_GETVMMAP bool do_mappings = false; #endif @@ -296,10 +306,18 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what) case IP_CWD: do_cwd = true; break; +#ifdef HAVE_KINFO_GETFILE + case IP_FILES: + do_files = true; + break; +#endif case IP_ALL: do_cmdline = true; do_cwd = true; do_exe = true; +#ifdef HAVE_KINFO_GETFILE + do_files = true; +#endif #ifdef HAVE_KINFO_GETVMMAP do_mappings = true; #endif @@ -312,7 +330,7 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what) gdb_argv built_argv (args); if (built_argv.count () == 0) { - pid = ptid_get_pid (inferior_ptid); + pid = inferior_ptid.pid (); if (pid == 0) error (_("No current process: you must name one.")); } @@ -323,7 +341,7 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what) printf_filtered (_("process %d\n"), pid); #ifdef HAVE_KINFO_GETFILE - if (do_cwd || do_exe) + if (do_cwd || do_exe || do_files) fdtbl.reset (kinfo_getfile (pid, &nfd)); #endif @@ -375,6 +393,25 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what) else warning (_("unable to fetch executable path name")); } +#ifdef HAVE_KINFO_GETFILE + if (do_files) + { + struct kinfo_file *kf = fdtbl.get (); + + if (nfd > 0) + { + fbsd_info_proc_files_header (); + for (int i = 0; i < nfd; i++, kf++) + fbsd_info_proc_files_entry (kf->kf_type, kf->kf_fd, kf->kf_flags, + kf->kf_offset, kf->kf_vnode_type, + kf->kf_sock_domain, kf->kf_sock_type, + kf->kf_sock_protocol, &kf->kf_sa_local, + &kf->kf_sa_peer, kf->kf_path); + } + else + warning (_("unable to fetch list of open files")); + } +#endif #ifdef HAVE_KINFO_GETVMMAP if (do_mappings) { @@ -384,46 +421,15 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what) if (vmentl != nullptr) { - printf_filtered (_("Mapped address spaces:\n\n")); -#ifdef __LP64__ - printf_filtered (" %18s %18s %10s %10s %9s %s\n", - "Start Addr", - " End Addr", - " Size", " Offset", "Flags ", "File"); -#else - printf_filtered ("\t%10s %10s %10s %10s %9s %s\n", - "Start Addr", - " End Addr", - " Size", " Offset", "Flags ", "File"); -#endif + int addr_bit = TARGET_CHAR_BIT * sizeof (void *); + fbsd_info_proc_mappings_header (addr_bit); struct kinfo_vmentry *kve = vmentl.get (); for (int i = 0; i < nvment; i++, kve++) - { - ULONGEST start, end; - - start = kve->kve_start; - end = kve->kve_end; -#ifdef __LP64__ - printf_filtered (" %18s %18s %10s %10s %9s %s\n", - hex_string (start), - hex_string (end), - hex_string (end - start), - hex_string (kve->kve_offset), - fbsd_vm_map_entry_flags (kve->kve_flags, - kve->kve_protection), - kve->kve_path); -#else - printf_filtered ("\t%10s %10s %10s %10s %9s %s\n", - hex_string (start), - hex_string (end), - hex_string (end - start), - hex_string (kve->kve_offset), - fbsd_vm_map_entry_flags (kve->kve_flags, - kve->kve_protection), - kve->kve_path); -#endif - } + fbsd_info_proc_mappings_entry (addr_bit, kve->kve_start, + kve->kve_end, kve->kve_offset, + kve->kve_flags, kve->kve_protection, + kve->kve_path); } else warning (_("unable to fetch virtual memory map")); @@ -534,9 +540,17 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what) return true; } -#ifdef KERN_PROC_AUXV +/* + * The current layout of siginfo_t on FreeBSD was adopted in SVN + * revision 153154 which shipped in FreeBSD versions 7.0 and later. + * Don't bother supporting the older layout on older kernels. The + * older format was also never used in core dump notes. + */ +#if __FreeBSD_version >= 700009 +#define USE_SIGINFO +#endif -#ifdef PT_LWPINFO +#ifdef USE_SIGINFO /* Return the size of siginfo for the current inferior. */ #ifdef __LP64__ @@ -674,11 +688,11 @@ fbsd_nat_target::xfer_partial (enum target_object object, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) { - pid_t pid = ptid_get_pid (inferior_ptid); + pid_t pid = inferior_ptid.pid (); switch (object) { -#ifdef PT_LWPINFO +#ifdef USE_SIGINFO case TARGET_OBJECT_SIGNAL_INFO: { struct ptrace_lwpinfo pl; @@ -710,6 +724,7 @@ fbsd_nat_target::xfer_partial (enum target_object object, return TARGET_XFER_OK; } #endif +#ifdef KERN_PROC_AUXV case TARGET_OBJECT_AUXV: { gdb::byte_vector buf_storage; @@ -751,17 +766,74 @@ fbsd_nat_target::xfer_partial (enum target_object object, } return TARGET_XFER_E_IO; } +#endif +#if defined(KERN_PROC_VMMAP) && defined(KERN_PROC_PS_STRINGS) + case TARGET_OBJECT_FREEBSD_VMMAP: + case TARGET_OBJECT_FREEBSD_PS_STRINGS: + { + gdb::byte_vector buf_storage; + gdb_byte *buf; + size_t buflen; + int mib[4]; + + int proc_target; + uint32_t struct_size; + switch (object) + { + case TARGET_OBJECT_FREEBSD_VMMAP: + proc_target = KERN_PROC_VMMAP; + struct_size = sizeof (struct kinfo_vmentry); + break; + case TARGET_OBJECT_FREEBSD_PS_STRINGS: + proc_target = KERN_PROC_PS_STRINGS; + struct_size = sizeof (void *); + break; + } + + if (writebuf != NULL) + return TARGET_XFER_E_IO; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = proc_target; + mib[3] = pid; + + if (sysctl (mib, 4, NULL, &buflen, NULL, 0) != 0) + return TARGET_XFER_E_IO; + buflen += sizeof (struct_size); + + if (offset >= buflen) + { + *xfered_len = 0; + return TARGET_XFER_EOF; + } + + buf_storage.resize (buflen); + buf = buf_storage.data (); + + memcpy (buf, &struct_size, sizeof (struct_size)); + buflen -= sizeof (struct_size); + if (sysctl (mib, 4, buf + sizeof (struct_size), &buflen, NULL, 0) != 0) + return TARGET_XFER_E_IO; + buflen += sizeof (struct_size); + + if (buflen - offset < len) + len = buflen - offset; + memcpy (readbuf, buf + offset, len); + *xfered_len = len; + return TARGET_XFER_OK; + } +#endif default: return inf_ptrace_target::xfer_partial (object, annex, readbuf, writebuf, offset, len, xfered_len); } } -#endif #ifdef PT_LWPINFO -static int debug_fbsd_lwp; -static int debug_fbsd_nat; +static bool debug_fbsd_lwp; +static bool debug_fbsd_nat; static void show_fbsd_lwp_debug (struct ui_file *file, int from_tty, @@ -807,41 +879,38 @@ show_fbsd_nat_debug (struct ui_file *file, int from_tty, /* Return true if PTID is still active in the inferior. */ -int +bool fbsd_nat_target::thread_alive (ptid_t ptid) { - if (ptid_lwp_p (ptid)) + if (ptid.lwp_p ()) { struct ptrace_lwpinfo pl; - if (ptrace (PT_LWPINFO, ptid_get_lwp (ptid), (caddr_t) &pl, sizeof pl) + if (ptrace (PT_LWPINFO, ptid.lwp (), (caddr_t) &pl, sizeof pl) == -1) - return 0; + return false; #ifdef PL_FLAG_EXITED if (pl.pl_flags & PL_FLAG_EXITED) - return 0; + return false; #endif } - return 1; + return true; } -/* Convert PTID to a string. Returns the string in a static - buffer. */ +/* Convert PTID to a string. */ -const char * +std::string fbsd_nat_target::pid_to_str (ptid_t ptid) { lwpid_t lwp; - lwp = ptid_get_lwp (ptid); + lwp = ptid.lwp (); if (lwp != 0) { - static char buf[64]; - int pid = ptid_get_pid (ptid); + int pid = ptid.pid (); - xsnprintf (buf, sizeof buf, "LWP %d of process %d", lwp, pid); - return buf; + return string_printf ("LWP %d of process %d", lwp, pid); } return normal_pid_to_str (ptid); @@ -856,8 +925,8 @@ fbsd_nat_target::thread_name (struct thread_info *thr) { struct ptrace_lwpinfo pl; struct kinfo_proc kp; - int pid = ptid_get_pid (thr->ptid); - long lwp = ptid_get_lwp (thr->ptid); + int pid = thr->ptid.pid (); + long lwp = thr->ptid.lwp (); static char buf[sizeof pl.pl_tdname + 1]; /* Note that ptrace_lwpinfo returns the process command in pl_tdname @@ -922,11 +991,11 @@ fbsd_enable_proc_events (pid_t pid) called to discover new threads each time the thread list is updated. */ static void -fbsd_add_threads (pid_t pid) +fbsd_add_threads (fbsd_nat_target *target, pid_t pid) { int i, nlwps; - gdb_assert (!in_thread_list (pid_to_ptid (pid))); + gdb_assert (!in_thread_list (target, ptid_t (pid))); nlwps = ptrace (PT_GETNUMLWPS, pid, NULL, 0); if (nlwps == -1) perror_with_name (("ptrace")); @@ -939,9 +1008,9 @@ fbsd_add_threads (pid_t pid) for (i = 0; i < nlwps; i++) { - ptid_t ptid = ptid_build (pid, lwps[i], 0); + ptid_t ptid = ptid_t (pid, lwps[i], 0); - if (!in_thread_list (ptid)) + if (!in_thread_list (target, ptid)) { #ifdef PT_LWP_EVENTS struct ptrace_lwpinfo pl; @@ -957,7 +1026,7 @@ fbsd_add_threads (pid_t pid) fprintf_unfiltered (gdb_stdlog, "FLWP: adding thread for LWP %u\n", lwps[i]); - add_thread (ptid); + add_thread (target, ptid); } } } @@ -974,7 +1043,7 @@ fbsd_nat_target::update_thread_list () #else prune_threads (); - fbsd_add_threads (ptid_get_pid (inferior_ptid)); + fbsd_add_threads (this, inferior_ptid.pid ()); #endif } @@ -1089,10 +1158,10 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo) pid_t pid; /* Don't PT_CONTINUE a process which has a pending vfork done event. */ - if (ptid_equal (minus_one_ptid, ptid)) - pid = ptid_get_pid (inferior_ptid); + if (minus_one_ptid == ptid) + pid = inferior_ptid.pid (); else - pid = ptid_get_pid (ptid); + pid = ptid.pid (); if (fbsd_is_vfork_done_pending (pid)) return; #endif @@ -1100,25 +1169,23 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo) if (debug_fbsd_lwp) fprintf_unfiltered (gdb_stdlog, "FLWP: fbsd_resume for ptid (%d, %ld, %ld)\n", - ptid_get_pid (ptid), ptid_get_lwp (ptid), - ptid_get_tid (ptid)); - if (ptid_lwp_p (ptid)) + ptid.pid (), ptid.lwp (), + ptid.tid ()); + if (ptid.lwp_p ()) { /* If ptid is a specific LWP, suspend all other LWPs in the process. */ - struct thread_info *tp; - int request; + inferior *inf = find_inferior_ptid (this, ptid); - ALL_NON_EXITED_THREADS (tp) + for (thread_info *tp : inf->non_exited_threads ()) { - if (ptid_get_pid (tp->ptid) != ptid_get_pid (ptid)) - continue; + int request; - if (ptid_get_lwp (tp->ptid) == ptid_get_lwp (ptid)) + if (tp->ptid.lwp () == ptid.lwp ()) request = PT_RESUME; else request = PT_SUSPEND; - if (ptrace (request, ptid_get_lwp (tp->ptid), NULL, 0) == -1) + if (ptrace (request, tp->ptid.lwp (), NULL, 0) == -1) perror_with_name (("ptrace")); } } @@ -1126,16 +1193,9 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo) { /* If ptid is a wildcard, resume all matching threads (they won't run until the process is continued however). */ - struct thread_info *tp; - - ALL_NON_EXITED_THREADS (tp) - { - if (!ptid_match (tp->ptid, ptid)) - continue; - - if (ptrace (PT_RESUME, ptid_get_lwp (tp->ptid), NULL, 0) == -1) - perror_with_name (("ptrace")); - } + for (thread_info *tp : all_non_exited_threads (this, ptid)) + if (ptrace (PT_RESUME, tp->ptid.lwp (), NULL, 0) == -1) + perror_with_name (("ptrace")); ptid = inferior_ptid; } @@ -1179,12 +1239,19 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo) core, return true. */ static bool -fbsd_handle_debug_trap (ptid_t ptid, const struct ptrace_lwpinfo &pl) +fbsd_handle_debug_trap (fbsd_nat_target *target, ptid_t ptid, + const struct ptrace_lwpinfo &pl) { /* Ignore traps without valid siginfo or for signals other than - SIGTRAP. */ - if (! (pl.pl_flags & PL_FLAG_SI) || pl.pl_siginfo.si_signo != SIGTRAP) + SIGTRAP. + + FreeBSD kernels prior to r341800 can return stale siginfo for at + least some events, but those events can be identified by + additional flags set in pl_flags. True breakpoint and + single-step traps should not have other flags set in + pl_flags. */ + if (pl.pl_flags != PL_FLAG_SI || pl.pl_siginfo.si_signo != SIGTRAP) return false; /* Trace traps are either a single step or a hardware watchpoint or @@ -1200,7 +1267,7 @@ fbsd_handle_debug_trap (ptid_t ptid, const struct ptrace_lwpinfo &pl) if (pl.pl_siginfo.si_code == TRAP_BRKPT) { /* Fixup PC for the software breakpoint. */ - struct regcache *regcache = get_thread_regcache (ptid); + struct regcache *regcache = get_thread_regcache (target, ptid); struct gdbarch *gdbarch = regcache->arch (); int decr_pc = gdbarch_decr_pc_after_break (gdbarch); @@ -1236,7 +1303,7 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, { #ifndef PTRACE_VFORK wptid = fbsd_next_vfork_done (); - if (!ptid_equal (wptid, null_ptid)) + if (wptid != null_ptid) { ourstatus->kind = TARGET_WAITKIND_VFORK_DONE; return wptid; @@ -1249,11 +1316,11 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, pid_t pid; int status; - pid = ptid_get_pid (wptid); + pid = wptid.pid (); if (ptrace (PT_LWPINFO, pid, (caddr_t) &pl, sizeof pl) == -1) perror_with_name (("ptrace")); - wptid = ptid_build (pid, pl.pl_lwpid, 0); + wptid = ptid_t (pid, pl.pl_lwpid, 0); if (debug_fbsd_nat) { @@ -1274,16 +1341,17 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, threads might be skipped during post_attach that have not yet reported their PL_FLAG_EXITED event. Ignore EXITED events for an unknown LWP. */ - if (in_thread_list (wptid)) + thread_info *thr = find_thread_ptid (this, wptid); + if (thr != nullptr) { if (debug_fbsd_lwp) fprintf_unfiltered (gdb_stdlog, "FLWP: deleting thread for LWP %u\n", pl.pl_lwpid); if (print_thread_events) - printf_unfiltered (_("[%s exited]\n"), target_pid_to_str - (wptid)); - delete_thread (wptid); + printf_unfiltered (_("[%s exited]\n"), + target_pid_to_str (wptid).c_str ()); + delete_thread (thr); } if (ptrace (PT_CONTINUE, pid, (caddr_t) 1, 0) == -1) perror_with_name (("ptrace")); @@ -1297,13 +1365,13 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, PL_FLAG_BORN in case the first stop reported after attaching to an existing process is a PL_FLAG_BORN event. */ - if (in_thread_list (pid_to_ptid (pid))) + if (in_thread_list (this, ptid_t (pid))) { if (debug_fbsd_lwp) fprintf_unfiltered (gdb_stdlog, "FLWP: using LWP %u for first thread\n", pl.pl_lwpid); - thread_change_ptid (pid_to_ptid (pid), wptid); + thread_change_ptid (this, ptid_t (pid), wptid); } #ifdef PT_LWP_EVENTS @@ -1313,13 +1381,13 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, threads might be added by fbsd_add_threads that have not yet reported their PL_FLAG_BORN event. Ignore BORN events for an already-known LWP. */ - if (!in_thread_list (wptid)) + if (!in_thread_list (this, wptid)) { if (debug_fbsd_lwp) fprintf_unfiltered (gdb_stdlog, "FLWP: adding thread for LWP %u\n", pl.pl_lwpid); - add_thread (wptid); + add_thread (this, wptid); } ourstatus->kind = TARGET_WAITKIND_SPURIOUS; return wptid; @@ -1344,7 +1412,7 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, /* Make sure the other end of the fork is stopped too. */ child_ptid = fbsd_is_child_pending (child); - if (ptid_equal (child_ptid, null_ptid)) + if (child_ptid == null_ptid) { pid = waitpid (child, &status, 0); if (pid == -1) @@ -1356,11 +1424,11 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, perror_with_name (("ptrace")); gdb_assert (pl.pl_flags & PL_FLAG_CHILD); - child_ptid = ptid_build (child, pl.pl_lwpid, 0); + child_ptid = ptid_t (child, pl.pl_lwpid, 0); } /* Enable additional events on the child process. */ - fbsd_enable_proc_events (ptid_get_pid (child_ptid)); + fbsd_enable_proc_events (child_ptid.pid ()); #ifndef PTRACE_VFORK /* For vfork, the child process will have the P_PPWAIT @@ -1407,7 +1475,7 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, #endif #ifdef USE_SIGTRAP_SIGINFO - if (fbsd_handle_debug_trap (wptid, pl)) + if (fbsd_handle_debug_trap (this, wptid, pl)) return wptid; #endif @@ -1452,16 +1520,16 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, #ifdef USE_SIGTRAP_SIGINFO /* Implement the "stopped_by_sw_breakpoint" target_ops method. */ -int +bool fbsd_nat_target::stopped_by_sw_breakpoint () { struct ptrace_lwpinfo pl; if (ptrace (PT_LWPINFO, get_ptrace_pid (inferior_ptid), (caddr_t) &pl, sizeof pl) == -1) - return 0; + return false; - return ((pl.pl_flags & PL_FLAG_SI) + return (pl.pl_flags == PL_FLAG_SI && pl.pl_siginfo.si_signo == SIGTRAP && pl.pl_siginfo.si_code == TRAP_BRKPT); } @@ -1469,10 +1537,10 @@ fbsd_nat_target::stopped_by_sw_breakpoint () /* Implement the "supports_stopped_by_sw_breakpoint" target_ops method. */ -int +bool fbsd_nat_target::supports_stopped_by_sw_breakpoint () { - return 1; + return true; } #endif @@ -1480,13 +1548,13 @@ fbsd_nat_target::supports_stopped_by_sw_breakpoint () /* Target hook for follow_fork. On entry and at return inferior_ptid is the ptid of the followed inferior. */ -int -fbsd_nat_target::follow_fork (int follow_child, int detach_fork) +bool +fbsd_nat_target::follow_fork (bool follow_child, bool detach_fork) { if (!follow_child && detach_fork) { struct thread_info *tp = inferior_thread (); - pid_t child_pid = ptid_get_pid (tp->pending_follow.value.related_pid); + pid_t child_pid = tp->pending_follow.value.related_pid.pid (); /* Breakpoints have already been detached from the child by infrun.c. */ @@ -1524,7 +1592,7 @@ fbsd_nat_target::follow_fork (int follow_child, int detach_fork) #endif } - return 0; + return false; } int @@ -1557,7 +1625,7 @@ fbsd_nat_target::remove_vfork_catchpoint (int pid) void fbsd_nat_target::post_startup_inferior (ptid_t pid) { - fbsd_enable_proc_events (ptid_get_pid (pid)); + fbsd_enable_proc_events (pid.pid ()); } /* Implement the "post_attach" target_ops method. */ @@ -1566,7 +1634,7 @@ void fbsd_nat_target::post_attach (int pid) { fbsd_enable_proc_events (pid); - fbsd_add_threads (pid); + fbsd_add_threads (this, pid); } #ifdef PL_FLAG_EXEC @@ -1601,8 +1669,9 @@ fbsd_nat_target::set_syscall_catchpoint (int pid, bool needed, #endif #endif +void _initialize_fbsd_nat (); void -_initialize_fbsd_nat (void) +_initialize_fbsd_nat () { #ifdef PT_LWPINFO add_setshow_boolean_cmd ("fbsd-lwp", class_maintenance,