On Wed, Aug 25, 2021 at 7:20 PM Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> wrote: > [...] > Extend the functionality added there to also log full parent chain on > Linux. In 2f732bf15e6 it was claimed that "further ancestry info can > be gathered with procfs, but it's unwieldy to do so.". > [...] > Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> > --- > diff --git a/compat/linux/procinfo.c b/compat/linux/procinfo.c > @@ -4,27 +4,129 @@ > +/* > + * We need more complex parsing instat_parent_pid() and s/instat_parent_pid/in stat_parent_pid/ > + * parse_proc_stat() below than a dumb fscanf(). That's because while > + * the statcomm field is surrounded by parentheses, the process itself > + * is free to insert any arbitrary byte sequence its its name. That > + * can include newlines, spaces, closing parentheses etc. See > + * do_task_stat() in fs/proc/array.c in linux.git, this is in contrast > + * with the escaped version of the name found in /proc/%d/status. > + * > + * So instead of using fscanf() we'll read N bytes from it, look for > + * the first "(", and then the last ")", anything in-between is our > + * process name. > + * > + * How much N do we need? On Linux /proc/sys/kernel/pid_max is 2^15 by > + * default, but it can be raised set to values of up to 2^22. So > + * that's 7 digits for a PID. We have 2 PIDs in the first four fields > + * we're interested in, so 2 * 7 = 14. > + * > + * We then have 4 spaces between those four values, which brings us up > + * to 18. Add the two parentheses and it's 20. The "state" is then one > + * character (now at 21). > + * > + * Finally the maximum length of the "comm" name itself is 15 > + * characters, e.g. a setting of "123456789abcdefg" will be truncated > + * to "123456789abcdef". See PR_SET_NAME in prctl(2). So all in all > + * we'd need to read 21 + 15 = 36 bytes. > + * > + * Let's just read 2^6 (64) instead for good measure. If PID_MAX ever > + * grows past 2^22 we'll be future-proof. We'll then anchor at the > + * last ")" we find to locate the parent PID. > + */