Rationale for setting COMMLEN to 19 in struct kinfo_proc

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Rationale for setting COMMLEN to 19 in struct kinfo_proc

Gleb Popov-2
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
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: Rationale for setting COMMLEN to 19 in struct kinfo_proc

Brooks Davis-2
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.

-- Brooks

signature.asc (465 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Rationale for setting COMMLEN to 19 in struct kinfo_proc

John Baldwin

--
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.

--
John Baldwin
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: Rationale for setting COMMLEN to 19 in struct kinfo_proc

Gleb Popov-2
On Wed, May 30, 2018 at 5:10 AM, John Baldwin <[hidden email]> 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
> _______________________________________________
> [hidden email] mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-arch
> To unsubscribe, send any mail to "[hidden email]"
>
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: Rationale for setting COMMLEN to 19 in struct kinfo_proc

Konstantin Belousov
On Fri, Jun 01, 2018 at 02:44:34PM +0300, Gleb Popov wrote:

> On Wed, May 30, 2018 at 5:10 AM, John Baldwin <[hidden email]> 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?
You do not print argv[1] etc, so they are not printed.
Note that availabitily of the argv and env is optional, the data can
be missed for many reasons.  Kernel is guaranteed to see it only
during execve(2), not between.

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