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.

9 comments

  1. This is super sexy swinging code.

    ntresch, December 17, 2008
  2. 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.

    dape, August 17, 2009
  3. Great! I hope it’s working for you. I’ve found it to be valuable on more than one occasion.

    bzimmer, August 25, 2009
  4. 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, September 30, 2009
  5. @rtmie, Thanks!

    bzimmer, October 1, 2009
  6. 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)

    Hari, April 2, 2010
  7. Could this be implemented in Python 2.4.4?

    Ajay, May 24, 2010
  8. I don’t that it can’t be but I haven’t tried it.

    bzimmer, May 25, 2010
  9. 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?

    Ajay, May 25, 2010

Leave a comment