Closed GoogleCodeExporter closed 9 years ago
Can you try running this without catching all the exceptions, or at least print
a stack trace for a few of them? The code as written is swallowing all types of
exceptions and falling through to the same error case so it's pretty much
impossible to tell what may be going wrong.
Thanks,
-Jay
Original comment by jlo...@gmail.com
on 9 May 2011 at 2:02
Also, the process.get_cpu_percent() in there causes a big slowdown since by
default it has a timeout of 0.1 seconds (hence, say you have 100 processes
you'll wait 10 seconds before that code block returns).
If you want to get an accurate CPU percent usage you'll have to iterate over
all processes twice, by setting an interval of 0:
>>> p.cpu_percent(interval=0) # this returns immediately
0.0
>>> # wait some time (e.g. by iterating over other processes)
>>> p.cpu_percent(interval=0)
11.3 # this is meaningful
Original comment by g.rodola
on 9 May 2011 at 2:20
thanks for the speedy response. i have changed the code to
def get_current_processes(self):
processes = []
for process in psutil.process_iter():
try:
p_cpu_perc = str(process.get_cpu_percent(interval=0))
p_mem_vms = str(process.get_memory_info().vms)
p_mem_rss = str(process.get_memory_info().rss)
p_num_threads = str(process.get_num_threads())
p = {'pid': process.pid,
'name': process.name,
'status': str(process.status),
'cpu_perc': p_cpu_perc,
'memory_vms': p_mem_vms,
'memory_rss': p_mem_rss,
'num_threads': p_num_threads,
'err': ''}
p_cpu_perc = str(process.get_cpu_percent(interval=0))
p['cpu_perc'] = p_cpu_perc
processes.append(p)
except Exception as ex:
print type(ex)
processes.append({'pid': process.pid,
'name': process.name,
'status': str(process.status),
'cpu_perc': '-1',
'memory_vms': '-1',
'memory_rss': '-1',
'num_threads': '-1',
'err': '1'})
return processes
1. it now calls cpu_percent() twice as suggested.
2. it now prints out the exception. the problem now, is if i do not use the
type(ex) function, it will just print out
(pid=<pid>)
When I use type(ex), it prints out
<class 'psutil.error.AccessDenied'>
This is the same error when calling p.get_cpu_percent() without being an
administrator.
The only processes that is throwing this exception are
{'status': 'running', 'num_threads': '-1', 'name': 'System Idle Process',
'err': '1', 'memory_vms': '-1', 'memory_rss': '-1', 'pid': 0,
'cpu_perc': '-1'}
{'status': 'running', 'num_threads': '-1', 'name': 'System', 'err': '1',
'memory_vms': '-1', 'memory_rss': '-1', 'pid': 4, 'cpu_perc':
'-1'}
Original comment by pamal...@gmail.com
on 10 May 2011 at 2:50
One problem is you're catching all exceptions during retrieval of the entire
process information. For example, if get_num_threads() fails, then you're
throwing away ALL the process information, even if memory, cpu, etc. are all
collected successfully.
I would really recommend re-tooling your code so that it only replaces the
functions that actually throw an AccessDenied exception with a -1 value. I
suspect you're running into AccessDenied for only one or two of the process
functions for the two System-owned processes, but the way your code is designed
it causes you to be unable to get any info for the process at all. It would
also be helpful to know which function(s) specifically are throwing
AccessDenied even as an Administrator user for the System processes.
-Jay
Original comment by jlo...@gmail.com
on 10 May 2011 at 1:57
I am a newbie in Python. So, I am not sure how to re-tool for it show more
details.
Anyway, I have excerpt the code and place it as a single script:
===
import psutil
import time
for process in psutil.process_iter():
try:
print 'pid: ' + str(process.pid)
print 'name: ' + process.name
# error begins here
p_cpu_perc = process.get_cpu_percent(interval=0)
time.sleep(1)
p_cpu_perc = process.get_cpu_percent(interval=0)
print 'cpu percent: ' + str(p_cpu_perc)
print "===\n"
except Exception, err:
print "error"
print str(type(err))
print str(err)
break
===
Instead of calling everything, I have made it stop when an exception occurs.
When I run this script with the following steps:
1. click Start
2. type 'cmd' on the search bar.
3. press Ctrl + Shift + Enter to run as Administrator
4. Go to the directory where the Python file (psutil_test.py) is.
5. python psutil_test.py
And the following is printed on screen.
===
C:\Users\myaccount>python psutil_test.py
pid: 0
name: System Idle Process
cpu percent: 0.0
===
pid: 4
name: System
error
<class 'psutil.error.AccessDenied'>
(pid=4, name='System')
C:\Users\myaccount>
===
This is all I can get. This shows that the process 'System' has AccessDenied
problem.
I am not sure how to from here. If anyone here has an idea, please let me know.
The same code works on WinXP with no problems. However, when I change from
process.get_cpu_percent() to process.status, WinXP just crash with a crash
dialog box. I will avoid using process.status for now.
The same in Win7 also occurs when process.get_memory_info() is used.
However, this problem goes away when they are entered in the Python prompt. It
only happens on Win7 running from a Python scripted file.
PS Please do not mind the time.sleep() there. This is just to show the problem.
Performance is not a concern.
Original comment by pamal...@gmail.com
on 11 May 2011 at 3:53
> This is all I can get. This shows that the process 'System' has AccessDenied
> problem.
>
> I am not sure how to from here. If anyone here has an idea, please let me
> know.
What I mean is, you're trying to read PID, name, status, CPU, mem and threads
all at once, when creating the dictionary. Since any of these individual calls
can throw an exception (AccessDenied, NoSuchProcess etc) that means that if
one fails, the entire dictionary for that process is created with "-1" values.
I'm not sure what you're trying to do with your code, but you're better off
wrapping each of these calls in a try/except block so that you can set the
"-1" error values only for those calls that fail due to an exception. Make
sense?
Depending on what you're doing though, this may be an unncessary step. The
process objects returned from process_iter() already return the values as
properties so you don't gain much by just putting the process objects in a
dictionary. Again, I'm not sure what you're doing with the dictionary so maybe
you have a good reason for doing it this way.
> The same code works on WinXP with no problems. However, when I change from
> process.get_cpu_percent() to process.status, WinXP just crash with a crash
> dialog box. I will avoid using process.status for now.
>
> The same in Win7 also occurs when process.get_memory_info() is used.
This is the first I've heard of a crash in get_cpu_percent(), I'd like to see
if this is reproducible on XP here. Nothing should be crashing in psutil even
if it's an access issue, it should only throw an exception. A full on crash is
concerning if it's reproducible.
> However, this problem goes away when they are entered in the Python prompt. It
> only happens on Win7 running from a Python scripted file.
Are you talking about the crash, or the AccessDenied errors? I am not sure how
this would make a difference. If you run the script manually by invoking
python.exe with the script name does that make any difference, versus
double-clicking the .py file or however you're launching it now?
Original comment by jlo...@gmail.com
on 14 May 2011 at 2:31
Right. I have modified my codes. This time I do not use dictionary anymore. I
write the results out directly to an XML file. The initial thought was to send
the information to a database via POST. That's why I used dictionary to easily
place things up. I do not have extensive Python background, but I do have PHP
background. So, I thought a dictionary will make my life easier.
Anyway, the updated codes as below:
===
import psutil
import time
log_file = "C:/temp/ps.log.xml"
handle = open(log_file, "w")
handle.write("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n")
handle.write("<processes>\n")
for process in psutil.process_iter():
p_cpu_perc = "-1.00"
p_mem_vms = "-1"
p_mem_rss = "-1"
p_num_threads = "-1"
p_status = "unknown"
p_error = ""
# get CPU perc 1st time
try:
p_cpu_perc = str(process.get_cpu_percent(interval=0))
except Exception, err:
p_error = p_error + "get_cpu_percent() [1st time]: " + str(err) + " : " + str(type(err)) + "\n"
# get VMS
try:
p_mem_vms = str(process.get_memory_info().vms)
except Exception, err:
p_error = p_error + "get_memory_info().vms: " + str(err) + " : " + str(type(err)) + "\n"
# get RSS
try:
p_mem_rss = str(process.get_memory_info().rss)
except Exception, err:
p_error = p_error + "get_memory_info().rss: " + str(err) + " : " + str(type(err)) + "\n"
# get num of threads
try:
p_num_threads = str(process.get_num_threads())
except Exception, err:
p_error = p_error + "get_num_threads(): " + str(err) + " : " + str(type(err)) + "\n"
# get CPU perc 2nd time
try:
p_cpu_perc = str(process.get_cpu_percent(interval=0))
except Exception, err:
p_error = p_error + "get_cpu_percent() [2nd time]: " + str(err) + " : " + str(type(err)) + "\n"
# write to XML
handle.write("<process>\n")
handle.write("<pid>" + str(process.pid) + "</pid>\n")
handle.write("<name>" + process.name + "</name>\n")
handle.write("<cpu_perc>" + p_cpu_perc + "</cpu_perc>\n")
handle.write("<memory_vms>" + p_mem_vms + "</memory_vms>\n")
handle.write("<memory_rss>" + p_mem_rss + "</memory_rss>\n")
handle.write("<num_threads>" + p_num_threads + "</num_threads>\n")
if len(p_error.strip()) > 0:
p_error = p_error.replace("&", "&").replace('"', """).replace("<", "<").replace(">", ">").replace("'", "'").replace("\n", "<br/>")
handle.write("<error>" + p_error + "</error>\n")
handle.write("</process>\n")
handle.write("</processes>")
handle.close()
===
The attached file is the resulting XML when running as administrator.
If you run the script as normal user, all will have AccessDenied errors.
On another note, I will submit another ticket on the WinXP crash later. Let's
keep this as AccessDenied issue.
Original comment by pamal...@gmail.com
on 18 May 2011 at 1:22
Attachments:
If looks to me like the only AccessDenied errors are for System processes,
which are likely legitimate as those are on a different security level than
Administrator. I don't know that there's anything we can do about that. I don't
have a Win7 system to confirm - Gimapaolo may be able to help there.
Non-admin users cannot read process information for processes due to security
constraints; reading other process' memory space requires SE_DEBUG privileges
which in turn usually requires an Administrator account. It would be expected
behavior for things to work as an Administrator user but not as a regular end
user acct.
Original comment by jlo...@gmail.com
on 18 May 2011 at 12:12
I agree with Jay. There's nothing you can do about those AccessDenied
exceptions.
I'm going to close this out as invalid.
Original comment by g.rodola
on 4 Jun 2011 at 12:03
Original issue reported on code.google.com by
pamal...@gmail.com
on 9 May 2011 at 10:10