@@ -153,6 +153,10 @@ Attach to a running process by PID::
153153
154154 python -m profiling.sampling attach 12345
155155
156+ Print a single snapshot of a running process's stack::
157+
158+ python -m profiling.sampling dump 12345
159+
156160Use live mode for real-time monitoring (press ``q `` to quit)::
157161
158162 python -m profiling.sampling run --live script.py
@@ -173,8 +177,9 @@ Enable opcode-level profiling to see which bytecode instructions are executing::
173177Commands
174178========
175179
176- Tachyon operates through two subcommands that determine how to obtain the
177- target process.
180+ Tachyon operates through several subcommands. ``run `` and ``attach `` collect
181+ samples over time; ``dump `` captures a single snapshot; ``replay `` converts
182+ binary profiles to other formats.
178183
179184
180185The ``run `` command
@@ -217,6 +222,81 @@ On most systems, attaching to another process requires appropriate permissions.
217222See :ref: `profiling-permissions ` for platform-specific requirements.
218223
219224
225+ .. _dump-command :
226+
227+ The ``dump `` command
228+ --------------------
229+
230+ The ``dump `` command prints a single snapshot of a running process's Python
231+ stack and exits, similar to a traceback::
232+
233+ python -m profiling.sampling dump 12345
234+
235+ Unlike ``attach ``, ``dump `` does not run a sampling loop: it reads the
236+ stack once. This is useful for investigating hung or unresponsive
237+ processes, or for answering "what is this process doing right now?".
238+
239+ The output mirrors a traceback (most recent call last) and annotates each
240+ thread with its current state (main thread, has GIL, on CPU, waiting for
241+ GIL, has exception, or idle):
242+
243+ .. code-block :: text
244+
245+ Stack dump for PID 12345, thread 140735 (main thread, has GIL, on CPU; most recent call last):
246+ File "server.py", line 28, in serve
247+ await handle_request(req)
248+ File "handler.py", line 91, in handle_request
249+ result = expensive_call(req)
250+
251+ When the target's source files are readable, ``dump `` prints the source
252+ line for each frame and highlights the executing expression. If a source
253+ file's modification time is newer than the target process's start time,
254+ ``dump `` replaces the line with ``[source file changed after process
255+ started] `` to avoid showing misleading code.
256+
257+ Like ``attach ``, ``dump `` requires permission to read the target process's
258+ memory. See :ref: `profiling-permissions `.
259+
260+ The ``dump `` command supports the following options:
261+
262+ ``-a ``, ``--all-threads ``
263+ Dump every thread in the target process. Without this flag only the main
264+ thread is shown.
265+
266+ ``--native ``
267+ Include synthetic ``<native> `` frames marking transitions into C
268+ extensions or other non-Python code.
269+
270+ ``--no-gc ``
271+ Hide the synthetic ``<GC> `` frames that mark active garbage collection.
272+
273+ ``--opcodes ``
274+ Annotate each frame with the bytecode opcode the thread is currently
275+ executing (for example, ``opcode=CALL_KW ``). Useful for
276+ instruction-level investigation, including identifying specializations
277+ chosen by the adaptive interpreter.
278+
279+ ``--async-aware ``
280+ Reconstruct stacks across ``await `` boundaries. ``dump `` walks the task
281+ graph and emits one section per task, with ``<task> `` markers separating
282+ coroutines awaiting each other.
283+
284+ ``--async-mode {running,all} ``
285+ Controls which tasks are included when ``--async-aware `` is enabled.
286+ ``running `` shows only the task currently executing on each thread;
287+ ``all `` (the default for ``dump ``) also includes tasks suspended on a
288+ wait. ``attach ``'s default for this flag is ``running ``; ``dump ``
289+ defaults to ``all `` because a single snapshot is most useful when it
290+ shows the full task graph.
291+
292+ ``--blocking ``
293+ Pause every thread in the target while reading its stack and resume
294+ them after. Guarantees a fully consistent snapshot at the cost of
295+ briefly stopping the target. Without it, ``dump `` reads memory while
296+ the target keeps running, which is faster but can occasionally produce
297+ a torn stack.
298+
299+
220300.. _replay-command :
221301
222302The ``replay `` command
@@ -1441,11 +1521,52 @@ Global options
14411521
14421522 Attach to and profile a running process by PID.
14431523
1524+ .. option :: dump
1525+
1526+ Print a single one-shot snapshot of a running process's Python stack.
1527+
14441528.. option :: replay
14451529
14461530 Convert a binary profile file to another output format.
14471531
14481532
1533+ Dump options
1534+ ------------
1535+
1536+ The following options apply to the ``dump `` subcommand:
1537+
1538+ .. option :: -a , --all-threads
1539+
1540+ Dump all threads in the target process instead of just the main thread.
1541+
1542+ .. option :: --native
1543+
1544+ Include ``<native> `` frames for non-Python code.
1545+
1546+ .. option :: --no-gc
1547+
1548+ Exclude ``<GC> `` frames for active garbage collection.
1549+
1550+ .. option :: --opcodes
1551+
1552+ Show bytecode opcode names when available.
1553+
1554+ .. option :: --async-aware
1555+
1556+ Reconstruct the stack across ``await `` boundaries for asyncio
1557+ applications.
1558+
1559+ .. option :: --async-mode <mode >
1560+
1561+ Async stack mode: ``running `` (only the running task) or ``all ``
1562+ (all tasks including waiting). Defaults to ``all `` for ``dump ``.
1563+ Requires :option: `--async-aware `.
1564+
1565+ .. option :: --blocking
1566+
1567+ Pause all threads in the target process while reading the stack.
1568+
1569+
14491570Sampling options
14501571----------------
14511572
0 commit comments