Python thread dumps.
2008-12-17
For some time I’ve wanted the equivalent of Java’s ability to dump the stack trace of all currently running threads in Python as a means for debugging some hung processes. I finally found a solution and wired it up to the services’ http console:
import sys import traceback from pygments import highlight from pygments.lexers import PythonLexer from pygments.formatters import HtmlFormatter def stacktraces(): code = [] for threadId, stack in sys._current_frames().items(): code.append("\n# ThreadID: %s" % threadId) for filename, lineno, name, line in traceback.extract_stack(stack): code.append('File: "%s", line %d, in %s' % (filename, lineno, name)) if line: code.append(" %s" % (line.strip())) return highlight("\n".join(code), PythonLexer(), HtmlFormatter( full=False, # style="native", noclasses=True, ))
The magic happens with sys._current_frames() which returns exactly what I wanted. The only outstanding issue is how to get the thread’s name to display in addition to the ident.
I’ll probably hook this up as a signal handler as well so headless applications can have the same functionality.
This is super sexy swinging code.
thanks,this is what I want,I google it a lot of times.
just like you ,I used to use stacktrace in java to peek what is going wrong with thread, so I want to do it in Python,and finally, I get you answer.
thanks!
this article save me a lot of time and energy.
Great! I hope it’s working for you. I’ve found it to be valuable on more than one occasion.
I just want to +1 the praise for this. It is so neat (in the old sense of the word :-) ). I have just added it to a signal.SIGQUIT handler in my server, so I have java like kill -3 functionality.
@rtmie, Thanks!
Beautiful, I have been dying to find this information out. You can find the name of the thread using threading.enumerate(). Here is a simple implementation that doesn’t need any external packages.
def stacktraces():
id2name = {}
for th in threading.enumerate():
id2name[th.ident] = th.name
code = []
for threadId, stack in sys._current_frames().items():
code.append(”\n# Thread: %s(%d)” % (id2name[threadId], threadId))
for filename, lineno, name, line in traceback.extract_stack(stack):
code.append(’File: “%s”, line %d, in %s’ % (filename, lineno, name))
if line:
code.append(” %s” % (line.strip()))
return “\n”.join(code)
Could this be implemented in Python 2.4.4?
I don’t that it can’t be but I haven’t tried it.
Theres no concept of thread ids in 2.4.4 … only thread name. Also, sys does not have the “_current_frames” method either :( any alternatives?