Use kinfo_getfile to implement fdwalk on FreeBSD.
authorJohn Baldwin <jhb@FreeBSD.org>
Fri, 30 Nov 2018 23:14:18 +0000 (15:14 -0800)
committerJohn Baldwin <jhb@FreeBSD.org>
Fri, 30 Nov 2018 23:14:18 +0000 (15:14 -0800)
kinfo_getfile() requires a couple of system calls to fetch the list of
open file descriptors.  This can be much cheaper than invoking fstat
on all of the values from 0 to the open file resource limit maximum.

gdb/ChangeLog:

* common/filestuff.c [HAVE_KINFO_GETFILE]: Include headers.
(fdwalk) [HAVE_KINFO_GETFILE]: Use kinfo_getfile.

gdb/ChangeLog
gdb/common/filestuff.c

index 778eebc1b10df9fcbceada42baa75770eaeeb4d2..83eabc43c566ffb0a0005862b9e56515a3fbb2bb 100644 (file)
@@ -1,3 +1,8 @@
+2018-11-30  John Baldwin  <jhb@FreeBSD.org>
+
+       * common/filestuff.c [HAVE_KINFO_GETFILE]: Include headers.
+       (fdwalk) [HAVE_KINFO_GETFILE]: Use kinfo_getfile.
+
 2018-11-30  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
             Simon Marchi  <simon.marchi@ericsson.com>
 
index 0db5c6936bc3431c40640d1c3bf53ba0f7fcd455..f4d5e38f07208a140b1edbc4f8cd4f97fc7f4fc1 100644 (file)
 #define HAVE_SOCKETS 1
 #endif
 
+#ifdef HAVE_KINFO_GETFILE
+#include <sys/user.h>
+#include <libutil.h>
+#endif
+
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
 #endif /* HAVE_SYS_RESOURCE_H */
@@ -108,6 +113,25 @@ fdwalk (int (*func) (void *, int), void *arg)
     }
   /* We may fall through to the next case.  */
 #endif
+#ifdef HAVE_KINFO_GETFILE
+  int nfd;
+  gdb::unique_xmalloc_ptr<struct kinfo_file[]> fdtbl
+    (kinfo_getfile (getpid (), &nfd));
+  if (fdtbl != NULL)
+    {
+      for (int i = 0; i < nfd; i++)
+       {
+         if (fdtbl[i].kf_fd >= 0)
+           {
+             int result = func (arg, fdtbl[i].kf_fd);
+             if (result != 0)
+               return result;
+           }
+       }
+      return 0;
+    }
+  /* We may fall through to the next case.  */
+#endif
 
   {
     int max, fd;