Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 1 Jun 2018 14:44:34 +0300
From:      Gleb Popov <arrowd@freebsd.org>
To:        John Baldwin <jhb@freebsd.org>
Cc:        freebsd-arch@freebsd.org
Subject:   Re: Rationale for setting COMMLEN to 19 in struct kinfo_proc
Message-ID:  <CALH631mvictRqAp1LfTsdzKe9O68MnZN1Wx4nFcZq8Y%2BKRwc7g@mail.gmail.com>
In-Reply-To: <6cdb7530-b689-7666-7ce4-9b91acfc6255@FreeBSD.org>
References:  <CALH631=XtWUMZnrz8%2BOH57GgY07pDY2du9OEOna6Pcd-zF=S8Q@mail.gmail.com> <20180530001638.GN99063@spindle.one-eyed-alien.net> <6cdb7530-b689-7666-7ce4-9b91acfc6255@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, May 30, 2018 at 5:10 AM, John Baldwin <jhb@freebsd.org> wrote:

>
> --
> John Baldwin
> On 5/29/18 8:16 PM, Brooks Davis wrote:
> > On Tue, May 29, 2018 at 11:42:47PM +0300, Gleb Popov wrote:
> >> Hello.
> >>
> >> I've been debugging a failing Qt (KDE, to be precise) test and found
> that
> >> process name returned in kinfo_proc structure gets truncated to 19
> symbols.
> >> This causes other errors in the application. I'm wondering why is this
> >> field so small and is there possibility to increase it? I think, having
> >> applications with names longer than 19 characters is not that rare.
> >>
> >> Relevant header: /usr/include/sys/user.h
> >>
> >> Simple testcase to feature the problem:
> >>
> >> # cat k.cpp
> >> #include <sys/types.h>
> >> #include <signal.h>
> >> #include <unistd.h>
> >> #include <stdio.h>
> >>
> >> #include <sys/cdefs.h>
> >> #include <sys/param.h>
> >> #include <sys/sysctl.h>
> >> #include <sys/user.h>
> >>
> >> int main()
> >> {
> >>     auto pid = getpid();
> >>     struct kinfo_proc kp;
> >>     int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid };
> >>
> >>     size_t len = sizeof(kp);
> >>     u_int mib_len = sizeof(mib)/sizeof(u_int);
> >>
> >>     if (sysctl(mib, mib_len, &kp, &len, NULL, 0) < 0)
> >>         return -1;
> >>
> >>     puts(kp.ki_tdname);
> >>     puts(kp.ki_comm);
> >>
> >>     return 0;
> >> }
> >> # c++ -o abcdefghijklmnopqrstuvwxyz
> >> # ./abcdefghijklmnopqrstuvwxyz
> >> abcdefghijklmnop
> >> abcdefghijklmnopqrs
> >
> > Changing the size of fields in kinfo_proc would be enormously
> > disruptive.  Take a look at all the source that uses KERN_PROC_PID for a
> > subset of things that would break.
> >
> > Sometimes we can break these interfaces, but I think this one would
> > require new sysctl mibs.  If we did that we should come up with an
> > interface that is identical between 32-bit and 32-bit systems and
> > doesn't export pointers.
>
> p_comm[] in struct proc is only 20 bytes long (19 chars + nul), so you
> can't make it bigger in kinfo_proc anyway as we only store 19 chars
> in the kernel.  (Note that we do have room to grow char arrays if
> needed without having to completely rototill though; we use a hack to
> store the "rest" of the thread name in a separate array to export the
> full 19 chars of the thread name now.)
>
> If you want the raw command line you can't get that via kinfo_proc.
> You can use the kern.proc.args sysctl or wrapper functions like
> kvm_getargv() or procstat_getargv().  You can then use argv[0] as the
> command name instead.
>

Thanks for your suggestion. I've tried that out and it does seem to work.
However, I'm slightly confused by the fact that procstat_getargv() returns
only command name and not the whole argv line, as function's name suggests.
Here is my code:

int main(int argc, char* argv[])
{
    kvm_t * kvm = kvm_open(nullptr, "/dev/null", nullptr, O_RDONLY, "");

    int cnt;
    struct kinfo_proc * kp = kvm_getprocs(kvm, KERN_PROC_PID, getpid(),
&cnt);

    struct procstat * ps = procstat_open_sysctl();

    char ** argv0 = procstat_getargv(ps, kp, 0);

    puts(*argv0);

    procstat_close(ps);
    kvm_close(kvm);

    return 0;
}

Running "veryveryverylongcommandname" correctly produces
"veryveryverylongcommandname" line on stdout, but
"veryveryverylongcommandname args args args" also gives only
"veryveryverylongcommandname". Is this correct behavior or am I missing
something?


> --
> John Baldwin
> _______________________________________________
> freebsd-arch@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-arch
> To unsubscribe, send any mail to "freebsd-arch-unsubscribe@freebsd.org"
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CALH631mvictRqAp1LfTsdzKe9O68MnZN1Wx4nFcZq8Y%2BKRwc7g>