dis --- Python bytecode 的反組譯器

原始碼:Lib/dis.py


dis 模組支援反組譯分析 CPython bytecode。CPython bytecode 作為輸入的模組被定義於 Include/opcode.h 並且被編譯器和直譯器所使用。

CPython 實作細節: Bytecode is an implementation detail of the CPython interpreter. No guarantees are made that bytecode will not be added, removed, or changed between versions of Python. Use of this module should not be considered to work across Python VMs or Python releases.

在 3.6 版的變更: Use 2 bytes for each instruction. Previously the number of bytes varied by instruction.

在 3.10 版的變更: The argument of jump, exception handling and loop instructions is now the instruction offset rather than the byte offset.

在 3.11 版的變更: Some instructions are accompanied by one or more inline cache entries, which take the form of CACHE instructions. These instructions are hidden by default, but can be shown by passing show_caches=True to any dis utility. Furthermore, the interpreter now adapts the bytecode to specialize it for different runtime conditions. The adaptive bytecode can be shown by passing adaptive=True.

在 3.12 版的變更: The argument of a jump is the offset of the target instruction relative to the instruction that appears immediately after the jump instruction's CACHE entries.

As a consequence, the presence of the CACHE instructions is transparent for forward jumps but needs to be taken into account when reasoning about backward jumps.

在 3.13 版的變更: The output shows logical labels rather than instruction offsets for jump targets and exception handlers. The -O command line option and the show_offsets argument were added.

在 3.14 版的變更: The -P command-line option and the show_positions argument were added.

The -S command-line option is added.

Example: Given the function myfunc():

def myfunc(alist):
    return len(alist)

可以使用以下指令來顯示 myfunc() 的反組譯:

>>> dis.dis(myfunc)
  2           RESUME                   0

  3           LOAD_GLOBAL              1 (len + NULL)
              LOAD_FAST_BORROW         0 (alist)
              CALL                     1
              RETURN_VALUE

(The "2" is a line number).

命令列介面

The dis module can be invoked as a script from the command line:

python -m dis [-h] [-C] [-O] [-P] [-S] [infile]

可接受以下選項:

-h, --help

Display usage and exit.

-C, --show-caches

Show inline caches.

在 3.13 版被加入.

-O, --show-offsets

Show offsets of instructions.

在 3.13 版被加入.

-P, --show-positions

Show positions of instructions in the source code.

在 3.14 版被加入.

-S, --specialized

Show specialized bytecode.

在 3.14 版被加入.

If infile is specified, its disassembled code will be written to stdout. Otherwise, disassembly is performed on compiled source code received from stdin.

Bytecode analysis

在 3.4 版被加入.

The bytecode analysis API allows pieces of Python code to be wrapped in a Bytecode object that provides easy access to details of the compiled code.

class dis.Bytecode(x, *, first_line=None, current_offset=None, show_caches=False, adaptive=False, show_offsets=False, show_positions=False)

Analyse the bytecode corresponding to a function, generator, asynchronous generator, coroutine, method, string of source code, or a code object (as returned by compile()).

This is a convenience wrapper around many of the functions listed below, most notably get_instructions(), as iterating over a Bytecode instance yields the bytecode operations as Instruction instances.

If first_line is not None, it indicates the line number that should be reported for the first source line in the disassembled code. Otherwise, the source line information (if any) is taken directly from the disassembled code object.

If current_offset is not None, it refers to an instruction offset in the disassembled code. Setting this means dis() will display a "current instruction" marker against the specified opcode.

If show_caches is True, dis() will display inline cache entries used by the interpreter to specialize the bytecode.

If adaptive is True, dis() will display specialized bytecode that may be different from the original bytecode.

If show_offsets is True, dis() will include instruction offsets in the output.

If show_positions is True, dis() will include instruction source code positions in the output.

classmethod from_traceback(tb, *, show_caches=False)

Construct a Bytecode instance from the given traceback, setting current_offset to the instruction responsible for the exception.

codeobj

The compiled code object.

first_line

The first source line of the code object (if available)

dis()

Return a formatted view of the bytecode operations (the same as printed by dis.dis(), but returned as a multi-line string).

info()

Return a formatted multi-line string with detailed information about the code object, like code_info().

在 3.7 版的變更: This can now handle coroutine and asynchronous generator objects.

在 3.11 版的變更: 新增 show_cachesadaptive 參數。

在 3.13 版的變更: 新增 show_offsets 參數。

在 3.14 版的變更: 新增 show_positions 參數。

範例: