Don't return stale data from fbsd_pid_to_exec_file for kernel processes.
[deliverable/binutils-gdb.git] / gdb / fbsd-nat.c
index 721e72b85c4775021a1e88438bb96add906cb9f8..d0aaf8914568be09515633c81e89a57a86f262d2 100644 (file)
@@ -1,6 +1,6 @@
 /* Native-dependent code for FreeBSD.
 
-   Copyright (C) 2002-2017 Free Software Foundation, Inc.
+   Copyright (C) 2002-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -41,6 +41,8 @@
 #include "elf-bfd.h"
 #include "fbsd-nat.h"
 
+#include <list>
+
 /* Return the name of a file that can be opened to get the symbols for
    the child process identified by PID.  */
 
@@ -61,7 +63,10 @@ fbsd_pid_to_exec_file (struct target_ops *self, int pid)
   mib[3] = pid;
   buflen = sizeof buf;
   if (sysctl (mib, 4, buf, &buflen, NULL, 0) == 0)
-    return buf;
+    /* The kern.proc.pathname.<pid> sysctl returns a length of zero
+       for processes without an associated executable such as kernel
+       processes.  */
+    return buflen == 0 ? NULL : buf;
 #endif
 
   xsnprintf (name, PATH_MAX, "/proc/%d/exe", pid);
@@ -277,7 +282,7 @@ fbsd_siginfo_size ()
   struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
 
   /* Is the inferior 32-bit?  If so, use the 32-bit siginfo size.  */
-  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+  if (gdbarch_long_bit (gdbarch) == 32)
     return sizeof (struct siginfo32);
 #endif
   return sizeof (siginfo_t);
@@ -294,7 +299,7 @@ fbsd_convert_siginfo (siginfo_t *si)
   struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
 
   /* Is the inferior 32-bit?  If not, nothing to do.  */
-  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word != 32)
+  if (gdbarch_long_bit (gdbarch) != 32)
     return;
 
   struct siginfo32 si32;
@@ -312,7 +317,7 @@ fbsd_convert_siginfo (siginfo_t *si)
      32-bits of the pointer value.  */
 #if _BYTE_ORDER == _BIG_ENDIAN
   if (si->si_value.sival_int == 0)
-    si32->si_value.sival_ptr = (uintptr_t) si->si_value.sival_ptr;
+    si32.si_value.sival_ptr = (uintptr_t) si->si_value.sival_ptr;
   else
     si32.si_value.sival_int = si->si_value.sival_int;
 #else
@@ -630,7 +635,7 @@ fbsd_add_threads (pid_t pid)
   if (nlwps == -1)
     perror_with_name (("ptrace"));
 
-  gdb::unique_xmalloc_ptr<lwpid_t> lwps (XCNEWVEC (lwpid_t, nlwps));
+  gdb::unique_xmalloc_ptr<lwpid_t[]> lwps (XCNEWVEC (lwpid_t, nlwps));
 
   nlwps = ptrace (PT_GETLWPLIST, pid, (caddr_t) lwps.get (), nlwps);
   if (nlwps == -1)
@@ -638,8 +643,7 @@ fbsd_add_threads (pid_t pid)
 
   for (i = 0; i < nlwps; i++)
     {
-      lwpid_t lwp = lwps.get ()[i];
-      ptid_t ptid = ptid_build (pid, lwp, 0);
+      ptid_t ptid = ptid_build (pid, lwps[i], 0);
 
       if (!in_thread_list (ptid))
        {
@@ -648,7 +652,7 @@ fbsd_add_threads (pid_t pid)
 
          /* Don't add exited threads.  Note that this is only called
             when attaching to a multi-threaded process.  */
-         if (ptrace (PT_LWPINFO, lwp, (caddr_t) &pl, sizeof pl) == -1)
+         if (ptrace (PT_LWPINFO, lwps[i], (caddr_t) &pl, sizeof pl) == -1)
            perror_with_name (("ptrace"));
          if (pl.pl_flags & PL_FLAG_EXITED)
            continue;
@@ -656,7 +660,7 @@ fbsd_add_threads (pid_t pid)
          if (debug_fbsd_lwp)
            fprintf_unfiltered (gdb_stdlog,
                                "FLWP: adding thread for LWP %u\n",
-                               lwp);
+                               lwps[i]);
          add_thread (ptid);
        }
     }
@@ -712,13 +716,7 @@ fbsd_update_thread_list (struct target_ops *ops)
   sake.  FreeBSD versions newer than 9.1 contain both fixes.
 */
 
-struct fbsd_fork_info
-{
-  struct fbsd_fork_info *next;
-  ptid_t ptid;
-};
-
-static struct fbsd_fork_info *fbsd_pending_children;
+static std::list<ptid_t> fbsd_pending_children;
 
 /* Record a new child process event that is reported before the
    corresponding fork event in the parent.  */
@@ -726,11 +724,7 @@ static struct fbsd_fork_info *fbsd_pending_children;
 static void
 fbsd_remember_child (ptid_t pid)
 {
-  struct fbsd_fork_info *info = XCNEW (struct fbsd_fork_info);
-
-  info->ptid = pid;
-  info->next = fbsd_pending_children;
-  fbsd_pending_children = info;
+  fbsd_pending_children.push_front (pid);
 }
 
 /* Check for a previously-recorded new child process event for PID.
@@ -739,39 +733,26 @@ fbsd_remember_child (ptid_t pid)
 static ptid_t
 fbsd_is_child_pending (pid_t pid)
 {
-  struct fbsd_fork_info *info, *prev;
-  ptid_t ptid;
-
-  prev = NULL;
-  for (info = fbsd_pending_children; info; prev = info, info = info->next)
-    {
-      if (ptid_get_pid (info->ptid) == pid)
-       {
-         if (prev == NULL)
-           fbsd_pending_children = info->next;
-         else
-           prev->next = info->next;
-         ptid = info->ptid;
-         xfree (info);
-         return ptid;
-       }
-    }
+  for (auto it = fbsd_pending_children.begin ();
+       it != fbsd_pending_children.end (); it++)
+    if (it->pid () == pid)
+      {
+       ptid_t ptid = *it;
+       fbsd_pending_children.erase (it);
+       return ptid;
+      }
   return null_ptid;
 }
 
 #ifndef PTRACE_VFORK
-static struct fbsd_fork_info *fbsd_pending_vfork_done;
+static std::forward_list<ptid_t> fbsd_pending_vfork_done;
 
 /* Record a pending vfork done event.  */
 
 static void
 fbsd_add_vfork_done (ptid_t pid)
 {
-  struct fbsd_fork_info *info = XCNEW (struct fbsd_fork_info);
-
-  info->ptid = pid;
-  info->next = fbsd_pending_vfork_done;
-  fbsd_pending_vfork_done = info;
+  fbsd_pending_vfork_done.push_front (pid);
 }
 
 /* Check for a pending vfork done event for a specific PID.  */
@@ -779,13 +760,10 @@ fbsd_add_vfork_done (ptid_t pid)
 static int
 fbsd_is_vfork_done_pending (pid_t pid)
 {
-  struct fbsd_fork_info *info;
-
-  for (info = fbsd_pending_vfork_done; info != NULL; info = info->next)
-    {
-      if (ptid_get_pid (info->ptid) == pid)
-       return 1;
-    }
+  for (auto it = fbsd_pending_vfork_done.begin ();
+       it != fbsd_pending_vfork_done.end (); it++)
+    if (it->pid () == pid)
+      return 1;
   return 0;
 }
 
@@ -795,15 +773,10 @@ fbsd_is_vfork_done_pending (pid_t pid)
 static ptid_t
 fbsd_next_vfork_done (void)
 {
-  struct fbsd_fork_info *info;
-  ptid_t ptid;
-
-  if (fbsd_pending_vfork_done != NULL)
+  if (!fbsd_pending_vfork_done.empty ())
     {
-      info = fbsd_pending_vfork_done;
-      fbsd_pending_vfork_done = info->next;
-      ptid = info->ptid;
-      xfree (info);
+      ptid_t ptid = fbsd_pending_vfork_done.front ();
+      fbsd_pending_vfork_done.pop_front ();
       return ptid;
     }
   return null_ptid;
@@ -1193,8 +1166,9 @@ fbsd_remove_exec_catchpoint (struct target_ops *self, int pid)
 
 #ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE
 static int
-fbsd_set_syscall_catchpoint (struct target_ops *self, int pid, int needed,
-                            int any_count, int table_size, int *table)
+fbsd_set_syscall_catchpoint (struct target_ops *self, int pid, bool needed,
+                            int any_count,
+                            gdb::array_view<const int> syscall_counts)
 {
 
   /* Ignore the arguments.  inf-ptrace.c will use PT_SYSCALL which
@@ -1246,9 +1220,6 @@ fbsd_nat_add_target (struct target_ops *t)
   add_target (t);
 }
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern initialize_file_ftype _initialize_fbsd_nat;
-
 void
 _initialize_fbsd_nat (void)
 {
This page took 0.030342 seconds and 4 git commands to generate.