Changeset View
Changeset View
Standalone View
Standalone View
head/devel/gdb/files/commit-92fce24de2
Property | Old Value | New Value |
---|---|---|
fbsd:nokeywords | null | yes \ No newline at end of property |
svn:eol-style | null | native \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
commit 92fce24de299a8b9a9a1c0c6b98e0e9c1656f99c | |||||
Author: John Baldwin <jhb@FreeBSD.org> | |||||
Date: Tue Jan 9 13:35:17 2018 -0800 | |||||
Support 'info proc' for native FreeBSD processes. | |||||
- Command line arguments are fetched via the kern.proc.args.<pid> | |||||
sysctl. | |||||
- The 'cwd' and 'exe' values are obtained from the per-process | |||||
file descriptor table returned by kinfo_getfile() from libutil. | |||||
- 'mappings' is implemented by walking the array of VM map entries | |||||
returned by kinfo_getvmmap() from libutil. | |||||
- 'status' output is generated by outputting fields from the structure | |||||
returned by the kern.proc.pid.<pid> sysctl. | |||||
- 'stat' is aliased to 'status'. | |||||
gdb/ChangeLog: | |||||
* configure.ac: Check for kinfo_getfile in libutil. | |||||
* configure: Regenerate. | |||||
* config.in: Regenerate. | |||||
* fbsd-nat.c: Include "fbsd-tdep.h". | |||||
(fbsd_fetch_cmdline): New. | |||||
(fbsd_fetch_kinfo_proc): Move earlier and change to return a bool | |||||
rather than calling error. | |||||
(fbsd_info_proc): New. | |||||
(fbsd_thread_name): Report error if fbsd_fetch_kinfo_proc fails. | |||||
(fbsd_wait): Report warning if fbsd_fetch_kinfo_proc fails. | |||||
(fbsd_nat_add_target): Set "to_info_proc" to "fbsd_info_proc". | |||||
diff --git gdb/config.in gdb/config.in | |||||
index 1d11a97080..ad2cc1754e 100644 | |||||
--- gdb/config.in | |||||
+++ gdb/config.in | |||||
@@ -219,6 +219,9 @@ | |||||
/* Define to 1 if you have the <inttypes.h> header file. */ | |||||
#undef HAVE_INTTYPES_H | |||||
+/* Define to 1 if your system has the kinfo_getfile function. */ | |||||
+#undef HAVE_KINFO_GETFILE | |||||
+ | |||||
/* Define to 1 if your system has the kinfo_getvmmap function. */ | |||||
#undef HAVE_KINFO_GETVMMAP | |||||
diff --git gdb/configure gdb/configure | |||||
index db610f32fc..68b9aad02d 100755 | |||||
--- gdb/configure | |||||
+++ gdb/configure | |||||
@@ -7927,6 +7927,66 @@ $as_echo "#define HAVE_KINFO_GETVMMAP 1" >>confdefs.h | |||||
fi | |||||
+# fbsd-nat.c can also use kinfo_getfile. | |||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kinfo_getfile" >&5 | |||||
+$as_echo_n "checking for library containing kinfo_getfile... " >&6; } | |||||
+if test "${ac_cv_search_kinfo_getfile+set}" = set; then : | |||||
+ $as_echo_n "(cached) " >&6 | |||||
+else | |||||
+ ac_func_search_save_LIBS=$LIBS | |||||
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |||||
+/* end confdefs.h. */ | |||||
+ | |||||
+/* Override any GCC internal prototype to avoid an error. | |||||
+ Use char because int might match the return type of a GCC | |||||
+ builtin and then its argument prototype would still apply. */ | |||||
+#ifdef __cplusplus | |||||
+extern "C" | |||||
+#endif | |||||
+char kinfo_getfile (); | |||||
+int | |||||
+main () | |||||
+{ | |||||
+return kinfo_getfile (); | |||||
+ ; | |||||
+ return 0; | |||||
+} | |||||
+_ACEOF | |||||
+for ac_lib in '' util util-freebsd; do | |||||
+ if test -z "$ac_lib"; then | |||||
+ ac_res="none required" | |||||
+ else | |||||
+ ac_res=-l$ac_lib | |||||
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS" | |||||
+ fi | |||||
+ if ac_fn_c_try_link "$LINENO"; then : | |||||
+ ac_cv_search_kinfo_getfile=$ac_res | |||||
+fi | |||||
+rm -f core conftest.err conftest.$ac_objext \ | |||||
+ conftest$ac_exeext | |||||
+ if test "${ac_cv_search_kinfo_getfile+set}" = set; then : | |||||
+ break | |||||
+fi | |||||
+done | |||||
+if test "${ac_cv_search_kinfo_getfile+set}" = set; then : | |||||
+ | |||||
+else | |||||
+ ac_cv_search_kinfo_getfile=no | |||||
+fi | |||||
+rm conftest.$ac_ext | |||||
+LIBS=$ac_func_search_save_LIBS | |||||
+fi | |||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_kinfo_getfile" >&5 | |||||
+$as_echo "$ac_cv_search_kinfo_getfile" >&6; } | |||||
+ac_res=$ac_cv_search_kinfo_getfile | |||||
+if test "$ac_res" != no; then : | |||||
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" | |||||
+ | |||||
+$as_echo "#define HAVE_KINFO_GETFILE 1" >>confdefs.h | |||||
+ | |||||
+fi | |||||
+ | |||||
+ | |||||
if test "X$prefix" = "XNONE"; then | |||||
acl_final_prefix="$ac_default_prefix" | |||||
diff --git gdb/configure.ac gdb/configure.ac | |||||
index 3db44ae758..551afc727e 100644 | |||||
--- gdb/configure.ac | |||||
+++ gdb/configure.ac | |||||
@@ -523,6 +523,11 @@ AC_SEARCH_LIBS(kinfo_getvmmap, util util-freebsd, | |||||
[AC_DEFINE(HAVE_KINFO_GETVMMAP, 1, | |||||
[Define to 1 if your system has the kinfo_getvmmap function. ])]) | |||||
+# fbsd-nat.c can also use kinfo_getfile. | |||||
+AC_SEARCH_LIBS(kinfo_getfile, util util-freebsd, | |||||
+ [AC_DEFINE(HAVE_KINFO_GETFILE, 1, | |||||
+ [Define to 1 if your system has the kinfo_getfile function. ])]) | |||||
+ | |||||
AM_ICONV | |||||
# GDB may fork/exec the iconv program to get the list of supported character | |||||
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c | |||||
index 81f8e27a2d..b352418813 100644 | |||||
--- gdb/fbsd-nat.c | |||||
+++ gdb/fbsd-nat.c | |||||
@@ -32,14 +32,16 @@ | |||||
#include <sys/signal.h> | |||||
#include <sys/sysctl.h> | |||||
#include <sys/user.h> | |||||
-#ifdef HAVE_KINFO_GETVMMAP | |||||
+#if defined(HAVE_KINFO_GETFILE) || defined(HAVE_KINFO_GETVMMAP) | |||||
#include <libutil.h> | |||||
-#else | |||||
+#endif | |||||
+#if !defined(HAVE_KINFO_GETVMMAP) | |||||
#include "filestuff.h" | |||||
#endif | |||||
#include "elf-bfd.h" | |||||
#include "fbsd-nat.h" | |||||
+#include "fbsd-tdep.h" | |||||
#include <list> | |||||
@@ -205,6 +207,331 @@ fbsd_find_memory_regions (struct target_ops *self, | |||||
} | |||||
#endif | |||||
+/* Fetch the command line for a running process. */ | |||||
+ | |||||
+static gdb::unique_xmalloc_ptr<char> | |||||
+fbsd_fetch_cmdline (pid_t pid) | |||||
+{ | |||||
+ size_t len; | |||||
+ int mib[4]; | |||||
+ | |||||
+ len = 0; | |||||
+ mib[0] = CTL_KERN; | |||||
+ mib[1] = KERN_PROC; | |||||
+ mib[2] = KERN_PROC_ARGS; | |||||
+ mib[3] = pid; | |||||
+ if (sysctl (mib, 4, NULL, &len, NULL, 0) == -1) | |||||
+ return nullptr; | |||||
+ | |||||
+ if (len == 0) | |||||
+ return nullptr; | |||||
+ | |||||
+ gdb::unique_xmalloc_ptr<char> cmdline ((char *) xmalloc (len)); | |||||
+ if (sysctl (mib, 4, cmdline.get (), &len, NULL, 0) == -1) | |||||
+ return nullptr; | |||||
+ | |||||
+ return cmdline; | |||||
+} | |||||
+ | |||||
+/* Fetch the external variant of the kernel's internal process | |||||
+ structure for the process PID into KP. */ | |||||
+ | |||||
+static bool | |||||
+fbsd_fetch_kinfo_proc (pid_t pid, struct kinfo_proc *kp) | |||||
+{ | |||||
+ size_t len; | |||||
+ int mib[4]; | |||||
+ | |||||
+ len = sizeof *kp; | |||||
+ mib[0] = CTL_KERN; | |||||
+ mib[1] = KERN_PROC; | |||||
+ mib[2] = KERN_PROC_PID; | |||||
+ mib[3] = pid; | |||||
+ return (sysctl (mib, 4, kp, &len, NULL, 0) == 0); | |||||
+} | |||||
+ | |||||
+/* Implement the "to_info_proc target_ops" method. */ | |||||
+ | |||||
+static void | |||||
+fbsd_info_proc (struct target_ops *ops, const char *args, | |||||
+ enum info_proc_what what) | |||||
+{ | |||||
+#ifdef HAVE_KINFO_GETFILE | |||||
+ gdb::unique_xmalloc_ptr<struct kinfo_file> fdtbl; | |||||
+ 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_GETVMMAP | |||||
+ bool do_mappings = false; | |||||
+#endif | |||||
+ bool do_status = false; | |||||
+ | |||||
+ switch (what) | |||||
+ { | |||||
+ case IP_MINIMAL: | |||||
+ do_cmdline = true; | |||||
+ do_cwd = true; | |||||
+ do_exe = true; | |||||
+ break; | |||||
+#ifdef HAVE_KINFO_GETVMMAP | |||||
+ case IP_MAPPINGS: | |||||
+ do_mappings = true; | |||||
+ break; | |||||
+#endif | |||||
+ case IP_STATUS: | |||||
+ case IP_STAT: | |||||
+ do_status = true; | |||||
+ break; | |||||
+ case IP_CMDLINE: | |||||
+ do_cmdline = true; | |||||
+ break; | |||||
+ case IP_EXE: | |||||
+ do_exe = true; | |||||
+ break; | |||||
+ case IP_CWD: | |||||
+ do_cwd = true; | |||||
+ break; | |||||
+ case IP_ALL: | |||||
+ do_cmdline = true; | |||||
+ do_cwd = true; | |||||
+ do_exe = true; | |||||
+#ifdef HAVE_KINFO_GETVMMAP | |||||
+ do_mappings = true; | |||||
+#endif | |||||
+ do_status = true; | |||||
+ break; | |||||
+ default: | |||||
+ error (_("Not supported on this target.")); | |||||
+ } | |||||
+ | |||||
+ gdb_argv built_argv (args); | |||||
+ if (built_argv.count () == 0) | |||||
+ { | |||||
+ pid = ptid_get_pid (inferior_ptid); | |||||
+ if (pid == 0) | |||||
+ error (_("No current process: you must name one.")); | |||||
+ } | |||||
+ else if (built_argv.count () == 1 && isdigit (built_argv[0][0])) | |||||
+ pid = strtol (built_argv[0], NULL, 10); | |||||
+ else | |||||
+ error (_("Invalid arguments.")); | |||||
+ | |||||
+ printf_filtered (_("process %d\n"), pid); | |||||
+#ifdef HAVE_KINFO_GETFILE | |||||
+ if (do_cwd || do_exe) | |||||
+ fdtbl.reset (kinfo_getfile (pid, &nfd)); | |||||
+#endif | |||||
+ | |||||
+ if (do_cmdline) | |||||
+ { | |||||
+ gdb::unique_xmalloc_ptr<char> cmdline = fbsd_fetch_cmdline (pid); | |||||
+ if (cmdline != nullptr) | |||||
+ printf_filtered ("cmdline = '%s'\n", cmdline.get ()); | |||||
+ else | |||||
+ warning (_("unable to fetch command line")); | |||||
+ } | |||||
+ if (do_cwd) | |||||
+ { | |||||
+ const char *cwd = NULL; | |||||
+#ifdef HAVE_KINFO_GETFILE | |||||
+ struct kinfo_file *kf = fdtbl.get (); | |||||
+ for (int i = 0; i < nfd; i++, kf++) | |||||
+ { | |||||
+ if (kf->kf_type == KF_TYPE_VNODE && kf->kf_fd == KF_FD_TYPE_CWD) | |||||
+ { | |||||
+ cwd = kf->kf_path; | |||||
+ break; | |||||
+ } | |||||
+ } | |||||
+#endif | |||||
+ if (cwd != NULL) | |||||
+ printf_filtered ("cwd = '%s'\n", cwd); | |||||
+ else | |||||
+ warning (_("unable to fetch current working directory")); | |||||
+ } | |||||
+ if (do_exe) | |||||
+ { | |||||
+ const char *exe = NULL; | |||||
+#ifdef HAVE_KINFO_GETFILE | |||||
+ struct kinfo_file *kf = fdtbl.get (); | |||||
+ for (int i = 0; i < nfd; i++, kf++) | |||||
+ { | |||||
+ if (kf->kf_type == KF_TYPE_VNODE && kf->kf_fd == KF_FD_TYPE_TEXT) | |||||
+ { | |||||
+ exe = kf->kf_path; | |||||
+ break; | |||||
+ } | |||||
+ } | |||||
+#endif | |||||
+ if (exe == NULL) | |||||
+ exe = fbsd_pid_to_exec_file (ops, pid); | |||||
+ if (exe != NULL) | |||||
+ printf_filtered ("exe = '%s'\n", exe); | |||||
+ else | |||||
+ warning (_("unable to fetch executable path name")); | |||||
+ } | |||||
+#ifdef HAVE_KINFO_GETVMMAP | |||||
+ if (do_mappings) | |||||
+ { | |||||
+ int nvment; | |||||
+ gdb::unique_xmalloc_ptr<struct kinfo_vmentry> | |||||
+ vmentl (kinfo_getvmmap (pid, &nvment)); | |||||
+ | |||||
+ 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 | |||||
+ | |||||
+ 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 | |||||
+ } | |||||
+ } | |||||
+ else | |||||
+ warning (_("unable to fetch virtual memory map")); | |||||
+ } | |||||
+#endif | |||||
+ if (do_status) | |||||
+ { | |||||
+ if (!fbsd_fetch_kinfo_proc (pid, &kp)) | |||||
+ warning (_("Failed to fetch process information")); | |||||
+ else | |||||
+ { | |||||
+ const char *state; | |||||
+ int pgtok; | |||||
+ | |||||
+ printf_filtered ("Name: %s\n", kp.ki_comm); | |||||
+ switch (kp.ki_stat) | |||||
+ { | |||||
+ case SIDL: | |||||
+ state = "I (idle)"; | |||||
+ break; | |||||
+ case SRUN: | |||||
+ state = "R (running)"; | |||||
+ break; | |||||
+ case SSTOP: | |||||
+ state = "T (stopped)"; | |||||
+ break; | |||||
+ case SZOMB: | |||||
+ state = "Z (zombie)"; | |||||
+ break; | |||||
+ case SSLEEP: | |||||
+ state = "S (sleeping)"; | |||||
+ break; | |||||
+ case SWAIT: | |||||
+ state = "W (interrupt wait)"; | |||||
+ break; | |||||
+ case SLOCK: | |||||
+ state = "L (blocked on lock)"; | |||||
+ break; | |||||
+ default: | |||||
+ state = "? (unknown)"; | |||||
+ break; | |||||
+ } | |||||
+ printf_filtered ("State: %s\n", state); | |||||
+ printf_filtered ("Parent process: %d\n", kp.ki_ppid); | |||||
+ printf_filtered ("Process group: %d\n", kp.ki_pgid); | |||||
+ printf_filtered ("Session id: %d\n", kp.ki_sid); | |||||
+ printf_filtered ("TTY: %ju\n", (uintmax_t) kp.ki_tdev); | |||||
+ printf_filtered ("TTY owner process group: %d\n", kp.ki_tpgid); | |||||
+ printf_filtered ("User IDs (real, effective, saved): %d %d %d\n", | |||||
+ kp.ki_ruid, kp.ki_uid, kp.ki_svuid); | |||||
+ printf_filtered ("Group IDs (real, effective, saved): %d %d %d\n", | |||||
+ kp.ki_rgid, kp.ki_groups[0], kp.ki_svgid); | |||||
+ printf_filtered ("Groups: "); | |||||
+ for (int i = 0; i < kp.ki_ngroups; i++) | |||||
+ printf_filtered ("%d ", kp.ki_groups[i]); | |||||
+ printf_filtered ("\n"); | |||||
+ printf_filtered ("Minor faults (no memory page): %ld\n", | |||||
+ kp.ki_rusage.ru_minflt); | |||||
+ printf_filtered ("Minor faults, children: %ld\n", | |||||
+ kp.ki_rusage_ch.ru_minflt); | |||||
+ printf_filtered ("Major faults (memory page faults): %ld\n", | |||||
+ kp.ki_rusage.ru_majflt); | |||||
+ printf_filtered ("Major faults, children: %ld\n", | |||||
+ kp.ki_rusage_ch.ru_majflt); | |||||
+ printf_filtered ("utime: %jd.%06ld\n", | |||||
+ (intmax_t) kp.ki_rusage.ru_utime.tv_sec, | |||||
+ kp.ki_rusage.ru_utime.tv_usec); | |||||
+ printf_filtered ("stime: %jd.%06ld\n", | |||||
+ (intmax_t) kp.ki_rusage.ru_stime.tv_sec, | |||||
+ kp.ki_rusage.ru_stime.tv_usec); | |||||
+ printf_filtered ("utime, children: %jd.%06ld\n", | |||||
+ (intmax_t) kp.ki_rusage_ch.ru_utime.tv_sec, | |||||
+ kp.ki_rusage_ch.ru_utime.tv_usec); | |||||
+ printf_filtered ("stime, children: %jd.%06ld\n", | |||||
+ (intmax_t) kp.ki_rusage_ch.ru_stime.tv_sec, | |||||
+ kp.ki_rusage_ch.ru_stime.tv_usec); | |||||
+ printf_filtered ("'nice' value: %d\n", kp.ki_nice); | |||||
+ printf_filtered ("Start time: %jd.%06ld\n", kp.ki_start.tv_sec, | |||||
+ kp.ki_start.tv_usec); | |||||
+ pgtok = getpagesize () / 1024; | |||||
+ printf_filtered ("Virtual memory size: %ju kB\n", | |||||
+ (uintmax_t) kp.ki_size / 1024); | |||||
+ printf_filtered ("Data size: %ju kB\n", | |||||
+ (uintmax_t) kp.ki_dsize * pgtok); | |||||
+ printf_filtered ("Stack size: %ju kB\n", | |||||
+ (uintmax_t) kp.ki_ssize * pgtok); | |||||
+ printf_filtered ("Text size: %ju kB\n", | |||||
+ (uintmax_t) kp.ki_tsize * pgtok); | |||||
+ printf_filtered ("Resident set size: %ju kB\n", | |||||
+ (uintmax_t) kp.ki_rssize * pgtok); | |||||
+ printf_filtered ("Maximum RSS: %ju kB\n", | |||||
+ (uintmax_t) kp.ki_rusage.ru_maxrss); | |||||
+ printf_filtered ("Pending Signals: "); | |||||
+ for (int i = 0; i < _SIG_WORDS; i++) | |||||
+ printf_filtered ("%08x ", kp.ki_siglist.__bits[i]); | |||||
+ printf_filtered ("\n"); | |||||
+ printf_filtered ("Ignored Signals: "); | |||||
+ for (int i = 0; i < _SIG_WORDS; i++) | |||||
+ printf_filtered ("%08x ", kp.ki_sigignore.__bits[i]); | |||||
+ printf_filtered ("\n"); | |||||
+ printf_filtered ("Caught Signals: "); | |||||
+ for (int i = 0; i < _SIG_WORDS; i++) | |||||
+ printf_filtered ("%08x ", kp.ki_sigcatch.__bits[i]); | |||||
+ printf_filtered ("\n"); | |||||
+ } | |||||
+ } | |||||
+} | |||||
+ | |||||
#ifdef KERN_PROC_AUXV | |||||
static enum target_xfer_status (*super_xfer_partial) (struct target_ops *ops, | |||||
enum target_object object, | |||||
@@ -455,26 +782,6 @@ show_fbsd_lwp_debug (struct ui_file *file, int from_tty, | |||||
fprintf_filtered (file, _("Debugging of FreeBSD lwp module is %s.\n"), value); | |||||
} | |||||
-#if defined(TDP_RFPPWAIT) || defined(HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME) | |||||
-/* Fetch the external variant of the kernel's internal process | |||||
- structure for the process PID into KP. */ | |||||
- | |||||
-static void | |||||
-fbsd_fetch_kinfo_proc (pid_t pid, struct kinfo_proc *kp) | |||||
-{ | |||||
- size_t len; | |||||
- int mib[4]; | |||||
- | |||||
- len = sizeof *kp; | |||||
- mib[0] = CTL_KERN; | |||||
- mib[1] = KERN_PROC; | |||||
- mib[2] = KERN_PROC_PID; | |||||
- mib[3] = pid; | |||||
- if (sysctl (mib, 4, kp, &len, NULL, 0) == -1) | |||||
- perror_with_name (("sysctl")); | |||||
-} | |||||
-#endif | |||||
- | |||||
/* | |||||
FreeBSD's first thread support was via a "reentrant" version of libc | |||||
(libc_r) that first shipped in 2.2.7. This library multiplexed all | |||||
@@ -560,7 +867,8 @@ fbsd_thread_name (struct target_ops *self, struct thread_info *thr) | |||||
/* Note that ptrace_lwpinfo returns the process command in pl_tdname | |||||
if a name has not been set explicitly. Return a NULL name in | |||||
that case. */ | |||||
- fbsd_fetch_kinfo_proc (pid, &kp); | |||||
+ if (!fbsd_fetch_kinfo_proc (pid, &kp)) | |||||
+ perror_with_name (_("Failed to fetch process information")); | |||||
if (ptrace (PT_LWPINFO, lwp, (caddr_t) &pl, sizeof pl) == -1) | |||||
perror_with_name (("ptrace")); | |||||
if (strcmp (kp.ki_comm, pl.pl_tdname) == 0) | |||||
@@ -970,9 +1278,13 @@ fbsd_wait (struct target_ops *ops, | |||||
#ifndef PTRACE_VFORK | |||||
/* For vfork, the child process will have the P_PPWAIT | |||||
flag set. */ | |||||
- fbsd_fetch_kinfo_proc (child, &kp); | |||||
- if (kp.ki_flag & P_PPWAIT) | |||||
- ourstatus->kind = TARGET_WAITKIND_VFORKED; | |||||
+ if (fbsd_fetch_kinfo_proc (child, &kp)) | |||||
+ { | |||||
+ if (kp.ki_flag & P_PPWAIT) | |||||
+ ourstatus->kind = TARGET_WAITKIND_VFORKED; | |||||
+ } | |||||
+ else | |||||
+ warning (_("Failed to fetch process information")); | |||||
#endif | |||||
ourstatus->value.related_pid = child_ptid; | |||||
@@ -1176,6 +1488,7 @@ fbsd_nat_add_target (struct target_ops *t) | |||||
{ | |||||
t->to_pid_to_exec_file = fbsd_pid_to_exec_file; | |||||
t->to_find_memory_regions = fbsd_find_memory_regions; | |||||
+ t->to_info_proc = fbsd_info_proc; | |||||
#ifdef KERN_PROC_AUXV | |||||
super_xfer_partial = t->to_xfer_partial; | |||||
t->to_xfer_partial = fbsd_xfer_partial; |