Showing the Stack Trace from a Running Python Application

Showing the stack trace from a running Python application

I have module I use for situations like this - where a process will be running for a long time but gets stuck sometimes for unknown and irreproducible reasons. Its a bit hacky, and only works on unix (requires signals):

import code, traceback, signal

def debug(sig, frame):
"""Interrupt running process, and provide a python prompt for
interactive debugging."""
d={'_frame':frame} # Allow access to frame object.
d.update(frame.f_globals) # Unless shadowed by global
d.update(frame.f_locals)

i = code.InteractiveConsole(d)
message = "Signal received : entering python shell.\nTraceback:\n"
message += ''.join(traceback.format_stack(frame))
i.interact(message)

def listen():
signal.signal(signal.SIGUSR1, debug) # Register handler

To use, just call the listen() function at some point when your program starts up (You could even stick it in site.py to have all python programs use it), and let it run. At any point, send the process a SIGUSR1 signal, using kill, or in python:

    os.kill(pid, signal.SIGUSR1)

This will cause the program to break to a python console at the point it is currently at, showing you the stack trace, and letting you manipulate the variables. Use control-d (EOF) to continue running (though note that you will probably interrupt any I/O etc at the point you signal, so it isn't fully non-intrusive.

I've another script that does the same thing, except it communicates with the running process through a pipe (to allow for debugging backgrounded processes etc). Its a bit large to post here, but I've added it as a python cookbook recipe.

Get stacktrace from stuck python process that does not accept signals

If the process is stuck in a way that no other signal gets through, you might want to consider running it from a debugger, instead of trying to attach to it at runtime.

Also, it might be useful to other debugging tactics, like turning off certain parts of the code to find out the minimal case in which it is still reproducible in order to see what causes it better.

Method to peek at a Python program running right now

If you have a running Python, which wasn't built with any sort of trace or logging mechanism, and you want to see what it's doing internally, then two options are:

  • On a Solaris or Mac, if you are using the system-provided Python then use dtrace

  • use gdb to attach to a running Python process,

Print current call stack from a method in code

Here's an example of getting the stack via the traceback module, and printing it:

import traceback

def f():
g()

def g():
for line in traceback.format_stack():
print(line.strip())

f()

# Prints:
# File "so-stack.py", line 10, in <module>
# f()
# File "so-stack.py", line 4, in f
# g()
# File "so-stack.py", line 7, in g
# for line in traceback.format_stack():

If you really only want to print the stack to stderr, you can use:

traceback.print_stack()

Or to print to stdout (useful if want to keep redirected output together), use:

traceback.print_stack(file=sys.stdout)

But getting it via traceback.format_stack() lets you do whatever you like with it.

Why fastapi trace http method not working?

That's not a problem with your code but the browser. The TRACE HTTP method has little to no support on browsers according to MDN. And since the swagger UI page for FastAPI uses the browser to make these API calls, it may not work.

However your code is working as expected. You can check that by using curl:

(venv) ➜ curl -X TRACE http://127.0.0.1:8000
"test"% (venv) ➜

From the handler method:

@app.trace("/")
def test_trace():
return "test"


Related Topics



Leave a reply



Submit