Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process.name() is incorrect with Chromium process on Linux #742

Open
desbma opened this issue Jan 26, 2016 · 13 comments
Open

Process.name() is incorrect with Chromium process on Linux #742

desbma opened this issue Jan 26, 2016 · 13 comments

Comments

@desbma
Copy link

desbma commented Jan 26, 2016

On Linux, starting the Chromium browser starts several child processes with various command line parameters.

For these processes I get for example:

process.name() => chromium-browser --enable-pinch
process.cmdline() => chromium-browser --enable-pinch                          
process.exe() => /usr/lib/chromium-browser/chromium-browser

I expect:

process.name() => chromium-browser
process.cmdline() => chromium-browser --enable-pinch                          
process.exe() => /usr/lib/chromium-browser/chromium-browser

Thanks

@giampaolo
Copy link
Owner

That is not a bug, that's the original information as it appears in /proc/pid/stat and I see no reason to truncate it. AFAIU this is a "frontend" / presentation end-user issue. If you (or glances in this case) want to truncate the process name for visualization purposes then just do it: p.name().split(' ')[0] ...and you're done.

@desbma
Copy link
Author

desbma commented Jan 27, 2016

Mhh /proc/[pid]/stat contains chromium-browse, and htop reports the correct name, so I still think this is a psutil bug.
I see in the code there is a test to conditionally extend the name from the command line string, I think that might be the cause.

@desbma
Copy link
Author

desbma commented Jan 28, 2016

I did a bit of digging and it appears the root cause is that command line parameters are not always NUL separated in /proc/[PID]/cmdline, so that code incorrectly interprets the whole command line as the process name.

In my case on Ubuntu, the /proc/[PID]/cmdline file contains the whole command line on the first line and then a few dozens NUL bytes.

@giampaolo giampaolo reopened this Jan 28, 2016
@giampaolo
Copy link
Owner

Can you please paste the content "/proc/{pid}/cmdline" and "/proc/{pid}/stat" and do that in python, like this?

with open("/proc/{pid}/...", 'rb') as f:
    print repr(f.read())

@desbma
Copy link
Author

desbma commented Jan 29, 2016

$ python3 -c "print(repr(open('/proc/3443/cmdline', 'rb').read()))"
b'chromium-browser --type=zygote\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

$ python3 -c "print(repr(open('/proc/3443/stat', 'rb').read()))"
b'3443 (chromium-browse) S 3430 2561 2561 0 -1 4210944 5167 0 29 0 28 2 0 0 20 0 1 0 48047 671727616 17152 18446744073709551615 94107726028800 94107768654348 140724168145904 140724168143720 140366420741179 0 0 4098 66792 18446744071579341426 0 0 17 0 0 0 2 0 0 94107770755168 94107772711596 94107792920576 140724168148865 140724168148922 140724168148922 140724168150989 0\n'

@fbenkstein
Copy link
Collaborator

IMHO this shouldn't be fixed. I think the user expectation is that cmdline contains the argv the program was started with. If a program modifies that memory so the information is lost, psutil shouldn't guess but return the data as acurately as possible. Chromium modifies argv[0] on purpose to make something else show up there: https://code.google.com/p/chromium/codesearch#chromium/src/content/common/set_process_title.cc&l=39

@fbenkstein
Copy link
Collaborator

As an example for another tools that does that look at readproctitle from DJB's daemontools: https://cr.yp.to/daemontools/readproctitle.html

>>> import psutil, subprocess
>>> p = psutil.Popen(["readproctitle", "." * 80], stdin=subprocess.PIPE)
>>> p.cmdline()
['readproctitle',
 '................................................................................']
>>> p.write("hello\n")
>>> p.cmdline()
['readproctitle',
 '...........................................................................hello']

Admittedly, it doesn't change argv[0] but it's the same principle.

@giampaolo
Copy link
Owner

@fbenkstein I think @desbma is complaining about name(), not cmdline().
...but still, I'm not sure whether this should be fixed (or how exactly) because it seems the only reason /proc/pid/cmdline contains spaces in this case is because chrome (erroneously, I suppose) overwrites the cmdline afterwards. According to "man proc" the separator is supposed to be "\x00". Personally I'm not sure what's best to do if this rule is not respected, and the problem with name() in this case originates exactly because of that.

@desbma
Copy link
Author

desbma commented Feb 2, 2016

Here is what I propose:

  • don't touch cmdline, psutil can't and shouldn't work around every program that changes argv
  • in name, detect if cmdline contains crap (ie. more than one NUL byte at the end), and if that's the case, disable the code that try to extend name from cmdline

@renyuneyun
Copy link

renyuneyun commented May 27, 2017

(Not sure if this is already mentioned in other issues or documents, but I don't find any in my brief search.)

The name property of a Process object is truncated to 15 characters (my observation is powerline-daemon is truncated to powerline-daemo) as the Name entry of /proc/PID/status does.

I originally expected psutil could report the full name of a process (not the truncated version), but it seems I was wrong.
Is this the desired behaviour for psutil or is it a temporary (though maybe long-lasting) issue?

I think this is a similar issue to the chromium one (because solving this requires the same method to solve the chromium issue) so post it here.

@giampaolo
Copy link
Owner

psutil already tries to get the full name() from the cmdline() but it doesn't work all the time. Unfortunately the 15 chars thing is a kernel limitation so there really isn't much we can do except to guess it.

@giampaolo
Copy link
Owner

psutil/psutil/__init__.py

Lines 653 to 666 in 65cc00e

if POSIX and len(name) >= 15:
# On UNIX the name gets truncated to the first 15 characters.
# If it matches the first part of the cmdline we return that
# one instead because it's usually more explicative.
# Examples are "gnome-keyring-d" vs. "gnome-keyring-daemon".
try:
cmdline = self.cmdline()
except AccessDenied:
pass
else:
if cmdline:
extended_name = os.path.basename(cmdline[0])
if extended_name.startswith(name):
name = extended_name

@billwanjohi
Copy link

FWIW, my htop does not recognize the chromium basename, which I can tell because I configure it to highlight the basename, and it gets that wrong for chromium and seemingly nothing else.

@giampaolo giampaolo added the bug label Nov 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants