Bug#935114: lsof: Some processes with modified name become invisible

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

Bug#935114: lsof: Some processes with modified name become invisible

Paul "LeoNerd" Evans-2
Package: lsof
Version: 4.91+dfsg-1
Severity: normal

Dear Maintainer,

By modifying the process name (e.g. by assigning to `$0` in perl as per
below), lsof sometimes fails to see the process even when their PID is
specified directly with `-p`.

Compare a working case:

  $ perl -E '$0 = "changed"; print "My PID is $$\n"; <STDIN>'
  My PID is 4200

  $ lsof -p 4200
  changed 4200  leo  cwd    DIR  254,3    20480 3293185 /home/leo
  changed 4200  leo  rtd    DIR  254,0     4096       2 /

With a non-working one:

  $ perl -E '$0 = "with-hyphen (and paren)"; print "My PID is $$\n"; <STDIN>'
  My PID is 4748

  $ lsof -p 4748

  $ lsof -p 4748 -V
  lsof: process ID not located: 4748

So far I don't have a conclusive pattern to which modifications are OK
and which cause it to fail. All of these work fine:

  $0 = "a really long name goes here with some stuff"
  $0 = "with(paren)"
  $0 = "with (paren) and spaces"
  $0 = "with-(paren)"
  $0 = "(a b)"
  $0 = "(a b c d e f g)"

This does not

  $0 = "(a b c d e f g h)"

It seems somehow to be related to what's inside the parentheses in the
process name, but I don't know if it's length, or word count, or what
set of characters are present. But then

  $0 = "(and paren)"

on its own *does* work, when it didn't work with the original example
when it suffixed longer text.

Hopefully, these test cases will help mean something to the lsof
developers who might be able to narrow down what is going on.

-- System Information:
Debian Release: 10.0
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable-debug'), (500,
'testing-debug'), (500, 'unstable') Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.19.0-5-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8),
LANGUAGE=en_GB:en (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages lsof depends on:
ii  libc6        2.28-10
ii  libselinux1  2.8-1+b1

lsof recommends no packages.

Versions of packages lsof suggests:
ii  perl  5.28.1-6

-- no debconf information

Paul "LeoNerd" Evans

[hidden email]      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/

Reply | Threaded
Open this post in threaded view

Bug#935114: lsof: Some processes with modified name become invisible

Bernhard Übelacker-3
Control: tags -1 + upstream
Control: fixed -1 4.89+dfsg-0.1

Dear Maintainer,
I just tried to find some more informations about this issue.

The lsof version 4.89+dfsg-0.1 did not show this issue, therefore
Stretch is not affected. It started with version 4.91+dfsg-1 which
is already contained in Buster.

As far as I see, the issue is /proc/[pid]/stat contains
usually a single line with all process informations.
Therefore lsof needs to parse that line.

It looks like linux delivers the process name parenthesised and
cropped to the first 16 characters.

Then lsof 4.91 got a change to handle process names with parenthesises
better, therefore counts them in the process name.

Therefore there is an issue with process names where parenthesises are
beyond the 16 character limit or the number of left parenthesises is
higher than the right parenthesises.

The minimal example to demonstrate the issue would be:

    root@debian:~# perl -E '$0 = "("; print "My PID is $$\n"; <STDIN>'
    My PID is 13957

    root@debian:~# lsof -p 13957
    root@debian:~# hexdump -C /proc/13957/stat
    00000000  31 33 39 35 37 20 28 28  29 20 53 20 34 39 32 36  |13957 (() S 4926|

The source location is around lsof-4.91+dfsg/dialects/linux/dproc.c,
lines 1568 to 1602.

Looking at 'ps aux', a different approach is used there:
The file /proc/[pid]/stat gets read as a whole and then
searched for the first '(' and then in reverse direction
from the end for the ')'.
In procps-3.3.15/proc/readproc.c, lines 597 and 600.
Maybe lsof could also use libprocps7 for that, too?

Kind regards,

PS.: It looks like the value set by perl is even when terminated a
lot longer than '('. Therefore 'ps aux' prints a lot of spaces
for the process name. Would that justify to open an bug there too?

root@debian:~# hexdump -C /proc/13957/cmdline
00000000  28 00 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |(.              |
00000010  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
00000100  00                                                |.|

debugging.txt (8K) Download Attachment