An i386 binary calling procstat_getfiles() on amd64 always gets NULL returned and errno==0, even though libutil's kinfo_getfile() works. The same code built as an amd64 binary works with both. I don't like procstat_getfiles() anyway, and won't be using it, at almost 1 millisecond per call it's ridiculously slow, and its linked list is less useful and costlier to build than kinfo_getfile()'s array. Just thought it would be good to document this issue for others that run into it. cc -m32 file.c -o proctest -lprocstat #include <sys/types.h> #include <sys/param.h> #include <sys/queue.h> #include <sys/sysctl.h> #include <sys/socket.h> #include <sys/user.h> #include <libprocstat.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { struct procstat *procstat = NULL; unsigned int count; struct kinfo_proc *kp = NULL; struct filestat_list *files = NULL; struct filestat *fs = NULL; char *ret = NULL; printf("starting...\n"); procstat = procstat_open_sysctl(); if (!procstat) { fprintf(stderr, "couldn't open procstat\n"); goto end; } printf("opened procstat\n"); kp = procstat_getprocs( procstat, KERN_PROC_PID, getpid(), &count ); if (!kp || count != 1) { fprintf(stderr, "getprocs failed\n"); goto end; } printf("got proc, now looking up files...\n"); files = procstat_getfiles( procstat, kp, 0 ); if (!files) { fprintf(stderr, "getfiles failed, errno %d\n", errno); goto end; } STAILQ_FOREACH( fs, files, next ) { printf("%d -> %s\n", fs->fs_fd, fs->fs_path); } end: return 0; }
The following should fix it, I did not checked: diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c index b754bc568e99..850d37598423 100644 --- a/lib/libprocstat/libprocstat.c +++ b/lib/libprocstat/libprocstat.c @@ -865,9 +865,7 @@ procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp, cap_rights_t cap_rights; assert(kp); - if (kp->ki_fd == NULL) - return (NULL); - switch(procstat->type) { + switch (procstat->type) { case PROCSTAT_SYSCTL: files = kinfo_getfile(kp->ki_pid, &cnt); break;
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=7a9423d6f360e3758ca67fbb25d309140ea93670 commit 7a9423d6f360e3758ca67fbb25d309140ea93670 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-12-02 18:03:01 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-12-02 22:52:49 +0000 procstat_getfiles_sysctl: do not require non-null ki_fd ki_fd is legitimately NULL when 32bit process requests process data from 64bit host kernel. The field is not used by the code for sysctl case; procstat_getfiles_kvm() checks ki_fd. PR: 260174 Reported by: Damjan Jovanovic <damjan.jov@gmail.com> Sponsored by: The FreeBSD Foundation MFC after: 1 week lib/libprocstat/libprocstat.c | 2 -- 1 file changed, 2 deletions(-)
Thank you. That was quick.
A commit in branch stable/13 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=ed43c7ac0a8c29510a42b56f79a7db32855e9821 commit ed43c7ac0a8c29510a42b56f79a7db32855e9821 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-12-02 18:03:01 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-12-09 00:23:29 +0000 procstat_getfiles_sysctl: do not require non-null ki_fd PR: 260174 (cherry picked from commit 7a9423d6f360e3758ca67fbb25d309140ea93670) lib/libprocstat/libprocstat.c | 2 -- 1 file changed, 2 deletions(-)
A commit in branch stable/12 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=deb027e9ed66d2cc4aa1cb55b7e0c1847b370c83 commit deb027e9ed66d2cc4aa1cb55b7e0c1847b370c83 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-12-02 18:03:01 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-12-09 00:32:47 +0000 procstat_getfiles_sysctl: do not require non-null ki_fd PR: 260174 (cherry picked from commit 7a9423d6f360e3758ca67fbb25d309140ea93670) lib/libprocstat/libprocstat.c | 2 -- 1 file changed, 2 deletions(-)