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.open_files fails if deleted files still visible #717

Closed
skundrik opened this issue Dec 11, 2015 · 14 comments
Closed

Process.open_files fails if deleted files still visible #717

skundrik opened this issue Dec 11, 2015 · 14 comments

Comments

@skundrik
Copy link

os.readlink(file) can sometimes return path looking like this (^@ is NULL)

/home/testaccount/.logstash-forwarder^@^@^@^@ (deleted)
/home/testaccount/.logstash-forwarder^@new (deleted)

resulting in

TypeError: must be encoded string without NULL bytes, not str

when call to isfile_strict(file) is made. It seems to be happening every time I try to use open_files(proc).

Environment
OS: 2.6.18-164.10.1.el5 #1 SMP Wed Dec 30 18:35:28 EST 2009 x86_64 x86_64 x86_64 GNU/Linux
Python 2.7.10 |Anaconda 2.3.0 (64-bit)| (default, May 28 2015, 17:02:03)
psutil 3.3.0

@giampaolo
Copy link
Owner

Can you paste the original traceback message?

@skundrik
Copy link
Author

Here you go

Traceback (most recent call last):
  File "/home/testaccount/testScript.py", line 97, in <module>
    openFiles = proc.open_files()
  File "/home/testaccount/Anaconda/current_Anaconda_dev_64/lib/python2.7/site-packages/psutil/__init__.py", line 962, in open_files
    return self._proc.open_files()
  File "/home/testaccount/Anaconda/current_Anaconda_dev_64/lib/python2.7/site-packages/psutil/_pslinux.py", line 645, in wrapper
    return fun(self, *args, **kwargs)
  File "/home/testaccount/Anaconda/current_Anaconda_dev_64/lib/python2.7/site-packages/psutil/_pslinux.py", line 1052, in open_files
    if file.startswith('/') and isfile_strict(file):
  File "/home/testaccount/Anaconda/current_Anaconda_dev_64/lib/python2.7/site-packages/psutil/_common.py", line 154, in isfile_strict
    st = os.stat(path)
TypeError: must be encoded string without NULL bytes, not str

@giampaolo
Copy link
Owner

Can you try doing isfile_strict(os.path.normpath(file)) and see if it fixes the issue?

@skundrik
Copy link
Author

Nope, doesn't seem to fix it as it doesn't remove the NULL characters.

@giampaolo
Copy link
Owner

Can you put a pdb in there and copy & paste the actual string?

@skundrik
Copy link
Author

Traceback (most recent call last):
  File "/home/testaccount/Anaconda/Anaconda-2.2.0-Linux-x86_64/envs/anaconda_2_3_0/lib/python2.7/pdb.py", line 1314, in main
    pdb._runscript(mainpyfile)
  File "/home/testaccount/Anaconda/Anaconda-2.2.0-Linux-x86_64/envs/anaconda_2_3_0/lib/python2.7/pdb.py", line 1233, in _runscript
    self.run(statement)
  File "/home/testaccount/Anaconda/Anaconda-2.2.0-Linux-x86_64/envs/anaconda_2_3_0/lib/python2.7/bdb.py", line 400, in run
    exec cmd in globals, locals
  File "<string>", line 1, in <module>
  File "/home/testaccount/runLogstashForwarder.py", line 1, in <module>
    import psutil
  File "/home/testaccount/Anaconda/Anaconda-2.2.0-Linux-x86_64/envs/anaconda_2_3_0/lib/python2.7/site-packages/psutil/__init__.py", line 962, in open_files
    return self._proc.open_files()
  File "/home/testaccount/Anaconda/Anaconda-2.2.0-Linux-x86_64/envs/anaconda_2_3_0/lib/python2.7/site-packages/psutil/_pslinux.py", line 645, in wrapper
    return fun(self, *args, **kwargs)
  File "/home/testaccount/Anaconda/Anaconda-2.2.0-Linux-x86_64/envs/anaconda_2_3_0/lib/python2.7/site-packages/psutil/_pslinux.py", line 1052, in open_files
    if file.startswith('/') and isfile_strict(file):
  File "/home/testaccount/Anaconda/Anaconda-2.2.0-Linux-x86_64/envs/anaconda_2_3_0/lib/python2.7/site-packages/psutil/_common.py", line 154, in isfile_strict
    st = os.stat(path)
TypeError: must be encoded string without NULL bytes, not str
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /home/testaccount/Anaconda/Anaconda-2.2.0-Linux-x86_64/envs/anaconda_2_3_0/lib/python2.7/site-packages/psutil/_common.py(154)isfile_strict()
-> st = os.stat(path)
(Pdb) p path
'/home/testhome/.logstash-forwarder\x00\x00\x00\x00 (deleted)'
(Pdb)

@giampaolo
Copy link
Owner

I should have fixed this (29334f1).

@skundrik
Copy link
Author

What about when the path is '/home/testhome/.logstash-forwarder\x00new (deleted)'? Maybe a better way would be to strip everything starting with first \x00 character. It looks to me like os.readlink() is copying more into the return string than it should.

@giampaolo
Copy link
Owner

What about when the path is '/home/testhome/.logstash-forwarder\x00new (deleted)'?

Apparently any string containing \x00 will result in a TypeError if passed to os.* functions so it seems the right way to go is to remove all null bytes.

@skundrik
Copy link
Author

I was referring to this part of the readlink() function in _pslinux.py

+    # Certain paths have ' (deleted)' appended. Usually this is
+    # bogus as the file actually exists.
+    if path.endswith(' (deleted)') and not path_exists_strict(path):
+        path = path[:-10]

@giampaolo
Copy link
Owner

What about it?

@skundrik
Copy link
Author

It only strips ' (deleted)' but the path can also end with 'new (deleted)'. Shouldn't that be stripped as well? Or everything after the first '\x00' is encountered?

giampaolo added a commit that referenced this issue Dec 15, 2015
@giampaolo
Copy link
Owner

Uhm... I've just verified that there can be paths with the (deleted) part appended but without any null byte, e.g.: /run/shm/.com.google.Chrome.58jAm8 (deleted). I think you are right though: we should split('\x00')[0] and discard everything after the null byte. Done in 9e3453c.

@skundrik
Copy link
Author

👍 Thank you.

mrjefftang added a commit to mrjefftang/psutil that referenced this issue Jan 5, 2016
* giampaolo/master: (148 commits)
  update doc
  add DEVNOTES.rst
  Add import-time tests for psutil
  one import per line
  use with lock:
  set global cpu vars to None if they can't be determined at import time
  add more tests
  giampaolo#717: ignore everything after the first occurrence of '\x00' instead of replacing '\x00' for the whole string
  fix giampaolo#717: [Linux] Process.open_files fails if deleted files still visible.
  giampaolo#715: don't crash at import time if cpu_times() fail for some reason.
  safety measure for ZombieProcess exc
  giampaolo#718: process_iter() thread safety
  giampaolo#708: use buffering for open() only on Python 2; on Python 3 this does not have any effect so it's better to let python decide what to do
  little speedup for system connections
  fix giampaolo#708 [Linux]: speedup psutil.net_connections() and psutil.Process.connections()
  linux refactoring: use a wrapper around open() for binary files
  update doc
  raise no memory err if malloc() fails
  giampaolo#714: [OpenBSD] return shared virtual mem
  add test for vmem total on freebsd
  ...
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

2 participants