[4/5] Support 'info proc files' on live FreeBSD processes.
Commit Message
This walks the list of struct kinfo_file objects returned by a call to
kinfo_getfile outputting a description of each open file descriptor.
gdb/ChangeLog:
* fbsd-nat.c (fbsd_nat_target::info_proc): List open file
descriptors for IP_FILES and IP_ALL.
---
gdb/ChangeLog | 5 +++++
gdb/fbsd-nat.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 48 insertions(+), 1 deletion(-)
Comments
On 2018-09-08 01:36 AM, John Baldwin wrote:
> This walks the list of struct kinfo_file objects returned by a call to
> kinfo_getfile outputting a description of each open file descriptor.
LGTM.
It would be nice to share the printing of the information between core
and live process, so that we can't forget to change one if we change the
other. But if there are some subtle differences between both loops that
would make sharing more annoying than anything, I don't mind.
Simon
On 9/8/18 4:00 PM, Simon Marchi wrote:
> On 2018-09-08 01:36 AM, John Baldwin wrote:
>> This walks the list of struct kinfo_file objects returned by a call to
>> kinfo_getfile outputting a description of each open file descriptor.
>
> LGTM.
>
> It would be nice to share the printing of the information between core
> and live process, so that we can't forget to change one if we change the
> other. But if there are some subtle differences between both loops that
> would make sharing more annoying than anything, I don't mind.
I've followed the same approach I used for 'info proc mappings' which is
to use shared helper routines as much as possible.
What I could perhaps do to share code is add new TARGET_FREEBSD_<foo>
target objects, but this would entail reworking the code quite a bit I
think. It would mean that I would need a way to let a gdbarch hook into
the core target's xfer_partial method more generically (right now there is
a hook just for siginfo, but I think we'd want a hook for arbitrary
objects). I would then rewrite the info proc bits in fbsd-tdep.c in terms
of fetching target objects and always parsing them in the core dump
format. I think there were a few things in some of the other 'info proc'
methods that weren't quite as straightforward as for the 'files' and
'mappings' case though.
On 2018-09-10 19:30, John Baldwin wrote:
> On 9/8/18 4:00 PM, Simon Marchi wrote:
>> On 2018-09-08 01:36 AM, John Baldwin wrote:
>>> This walks the list of struct kinfo_file objects returned by a call
>>> to
>>> kinfo_getfile outputting a description of each open file descriptor.
>>
>> LGTM.
>>
>> It would be nice to share the printing of the information between core
>> and live process, so that we can't forget to change one if we change
>> the
>> other. But if there are some subtle differences between both loops
>> that
>> would make sharing more annoying than anything, I don't mind.
>
> I've followed the same approach I used for 'info proc mappings' which
> is
> to use shared helper routines as much as possible.
>
> What I could perhaps do to share code is add new TARGET_FREEBSD_<foo>
> target objects, but this would entail reworking the code quite a bit I
> think. It would mean that I would need a way to let a gdbarch hook
> into
> the core target's xfer_partial method more generically (right now there
> is
> a hook just for siginfo, but I think we'd want a hook for arbitrary
> objects). I would then rewrite the info proc bits in fbsd-tdep.c in
> terms
> of fetching target objects and always parsing them in the core dump
> format. I think there were a few things in some of the other 'info
> proc'
> methods that weren't quite as straightforward as for the 'files' and
> 'mappings' case though.
I was thinking more about how to share the code that formats and print
one entry. Let's say you realize later that a column needs to be wider,
you have to remember to update both the live and core versions. Not
really a big deal though.
Simon
On 9/10/18 12:03 PM, Simon Marchi wrote:
> I was thinking more about how to share the code that formats and print
> one entry. Let's say you realize later that a column needs to be wider,
> you have to remember to update both the live and core versions. Not
> really a big deal though.
Hmm, ok. I think I've managed to do this in the V2 I will post in a bit.
I've made the helper routines fbsd-tdep.c exports more abstract ("print
header" and "print entry" rather than for individual fields).
@@ -1,3 +1,8 @@
+2018-09-07 John Baldwin <jhb@FreeBSD.org>
+
+ * fbsd-nat.c (fbsd_nat_target::info_proc): List open file
+ descriptors for IP_FILES and IP_ALL.
+
2018-09-07 John Baldwin <jhb@FreeBSD.org>
* fbsd-tdep.c (KF_FLAGS, KF_OFFSET, KF_VNODE_TYPE, KF_SOCK_DOMAIN)
@@ -266,6 +266,9 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
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 +299,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
@@ -323,7 +334,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 +386,37 @@ 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)
+ {
+ printf_filtered (_("Open files:\n\n"));
+ printf_filtered (" %6s %6s %10s %9s %s\n",
+ "FD", "Type", "Offset", "Flags ", "Name");
+ for (int i = 0; i < nfd; i++, kf++)
+ {
+ printf_filtered (" %6s %6s %10s %8s ",
+ fbsd_file_fd (kf->kf_fd),
+ fbsd_file_type (kf->kf_type, kf->kf_vnode_type),
+ kf->kf_offset > -1 ? hex_string (kf->kf_offset)
+ : "-",
+ fbsd_file_flags (kf->kf_flags));
+ if (kf->kf_type == KF_TYPE_SOCKET)
+ fbsd_print_socket (kf->kf_sock_domain, kf->kf_sock_type,
+ kf->kf_sock_protocol, &kf->kf_sa_local,
+ &kf->kf_sa_peer);
+ else
+ printf_filtered ("%s", kf->kf_path);
+ printf_filtered ("\n");
+ }
+ }
+ else
+ warning (_("unable to fetch list of open files"));
+ }
+#endif
#ifdef HAVE_KINFO_GETVMMAP
if (do_mappings)
{