Dump Process Stack with profiling.sampling in Python 3.15

Dump Process Stack with profiling.sampling in Python 3.15

A process that stops producing output gives no sign of what it is doing. It may be waiting on a network call, blocked on a lock, or stuck in a loop, and from the outside all three look the same. Since Python 3.15, the profiling package provides the profiling.sampling module, which can print the current call stack of a running process. It takes a single snapshot and exits, so it answers where the process stands right now rather than how it spends its time.

The following script waits inside a nested call:

import time


def fetch_rows():
    time.sleep(300)
    return []


def process_batch():
    rows = fetch_rows()
    return len(rows)


process_batch()

Start it and leave it running:

python main.py

Open a second terminal and find the process ID:

pgrep -f main.py
2514

The dump command takes that process ID and prints the stack:

sudo python -m profiling.sampling dump 2514
Stack dump for PID 2514, thread 2514 (main thread, idle; most recent call last):
  File "main.py", line 14, in <module>
    process_batch()
  File "main.py", line 10, in process_batch
    rows = fetch_rows()
  File "main.py", line 5, in fetch_rows
    time.sleep(300)

The output reads like a traceback, with the source line printed under each frame, except that nothing failed. The frames appear with the most recent call last, so the bottom one is where the process currently sits. Line 5 is time.sleep(300), which means the process is waiting rather than computing.

The idle status in the header means the thread is not running Python code. A process that is working reports has GIL, on CPU instead.

The command needs sudo because reading the memory of another process requires the CAP_SYS_PTRACE capability. On Ubuntu, the kernel.yama.ptrace_scope setting defaults to 1, which allows a process to trace only its own children. The profiler is not the parent of the script, so it needs the capability instead.

Leave a Comment

Cancel reply

Your email address will not be published.