プロファイリングとトレース

Python インタプリタは、プロファイル: 分析 (profile) や実行のトレース: 追跡 (trace) といった機能を組み込むために低水準のサポートを提供しています。このサポートは、プロファイルやデバッグ、適用範囲分析 (coverage analysis) ツールなどに使われます。

この C インターフェースは、プロファイルやトレース作業時に、Python レベルの呼び出し可能オブジェクトが呼び出されることによるオーバヘッドを避け、直接 C 関数呼び出しが行えるようにしています。プロファイルやトレース機能の本質的な特性は変わっていません; インターフェースではトレース関数をスレッドごとにインストールでき、トレース関数に報告される基本イベント (basic event) は以前のバージョンにおいて Python レベルのトレース関数で報告されていたものと同じです。

typedef int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg)

PyEval_SetProfile() と PyEval_SetTrace() で登録するトレース関数の型です。 第 1 引数は登録関数に obj として渡したオブジェクト、frame はイベントの対象のフレームオブジェクトです。 what は定数 PyTrace_CALL、PyTrace_EXCEPTION、PyTrace_LINE、PyTrace_RETURN、PyTrace_C_CALL、PyTrace_C_EXCEPTION、PyTrace_C_RETURN、PyTrace_OPCODE のいずれかで、arg は what の値によって異なります。

what の値

arg の意味

PyTrace_CALL

常に Py_None 。

PyTrace_EXCEPTION

sys.exc_info() の返す例外情報です。

PyTrace_LINE

常に Py_None 。

PyTrace_RETURN

呼び出し側に返される予定の値か、例外によって関数を抜ける場合は NULL です。

PyTrace_C_CALL

呼び出される関数オブジェクト。

PyTrace_C_EXCEPTION

呼び出される関数オブジェクト。

PyTrace_C_RETURN

呼び出される関数オブジェクト。

PyTrace_OPCODE

常に Py_None 。

int PyTrace_CALL

関数やメソッドの新たな呼び出し、またはジェネレータへの新たな進入を報告するときに、Py_tracefunc 関数の what 引数に渡される値です。 ジェネレータ関数からイテレータを作成する時点では、対応するフレーム内の Python バイトコードに制御が移らないため、このイベントは報告されません。

int PyTrace_EXCEPTION

例外が送出されたときに Py_tracefunc 関数の what 引数に渡される値です。 バイトコードの処理後に実行中のフレーム内で例外が設定されると、この値を what に指定してコールバックが呼び出されます。 このため、例外の伝播によって Python のスタックが巻き戻される際には、伝播先の各フレームに戻るたびにコールバックが呼び出されます。 このイベントを受け取るのはトレース関数だけで、プロファイラには不要です。

int PyTrace_LINE

行番号のイベントを報告するときに、Py_tracefunc 関数 (プロファイリング関数を除く) の what 引数に渡される値です。 フレームの f_trace_lines を 0 に設定すると、そのフレームでは無効にできます。

int PyTrace_RETURN

呼び出しが返るときに Py_tracefunc 関数に what 引数として渡す値です。

int PyTrace_C_CALL

C関数を呼び出す直前に Py_tracefunc 関数の what 引数として渡す値です。

int PyTrace_C_EXCEPTION

C関数が例外を送出したときに Py_tracefunc 関数の what 引数として渡す値です。

int PyTrace_C_RETURN

C関数から戻るときに Py_tracefunc 関数の what 引数として渡す値です。

int PyTrace_OPCODE

新しいオペコードを実行しようとするときに、Py_tracefunc 関数 (プロファイリング関数を除く) の what 引数に渡される値です。 このイベントはデフォルトでは発生しません。 フレームの f_trace_opcodes を 1 に設定して明示的に要求する必要があります。

void PyEval_SetProfile(Py_tracefunc func, PyObject *obj)

プロファイラ関数を func に設定します。 obj はその関数の第 1 引数として渡され、任意の Python オブジェクトまたは NULL を指定できます。 プロファイラ関数が状態を保持する必要がある場合は、スレッドごとに異なる obj を使うと、便利でスレッドセーフな保存先になります。 プロファイラ関数は PyTrace_LINE、PyTrace_OPCODE、PyTrace_EXCEPTION を除くすべての監視対象イベントについて呼び出されます。

sys.setprofile() 関数も参照してください。

呼び出し元には アタッチされたスレッド状態 が必要です。

void PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *obj)

PyEval_SetProfile() と同様ですが、現在のスレッドだけでなく、現在のインタープリタに属する実行中のすべてのスレッドにプロファイラ関数を設定します。

呼び出し元には アタッチされたスレッド状態 が必要です。

PyEval_SetProfile() と同様に、すべてのスレッドにプロファイラ関数を設定する際に発生した例外を無視します。

Added in version 3.12.

void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)

トレース関数を func に設定します。 PyEval_SetProfile() と同様ですが、トレース関数は行番号のイベントとオペコードごとのイベントを受け取り、C 関数オブジェクトの呼び出しに関連するイベントは受け取りません。 PyEval_SetTrace() で登録したトレース関数には、what 引数として PyTrace_C_CALL、PyTrace_C_EXCEPTION、PyTrace_C_RETURN が渡されることはありません。

sys.settrace() 関数も参照してください。

呼び出し元には アタッチされたスレッド状態 が必要です。

void PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *obj)

PyEval_SetTrace() と同様ですが、現在のスレッドだけでなく、現在のインタープリタに属する実行中のすべてのスレッドにトレース関数を設定します。

呼び出し元には アタッチされたスレッド状態 が必要です。

PyEval_SetTrace() と同様に、すべてのスレッドにトレース関数を設定する際に発生した例外を無視します。

Added in version 3.12.

参照のトレース

Added in version 3.13.

typedef int (*PyRefTracer)(PyObject*, int event, void *data)

PyRefTracer_SetTracer() で登録するトレース関数の型です。 第 1 引数は、作成されたばかりの Python オブジェクト (event が PyRefTracer_CREATE の場合)、またはこれから破棄されるオブジェクト (event が PyRefTracer_DESTROY の場合) です。 data 引数は PyRefTracer_SetTracer() の呼び出し時に渡した不透明なポインタです。

現在のトレース関数を置き換える新しい関数が登録される場合、新しい関数の登録直前に、オブジェクトを NULL、event を PyRefTracer_TRACKER_REMOVED として現在のトレース関数が呼び出されます。

Added in version 3.13.

int PyRefTracer_CREATE

Python オブジェクトが作成されたときに、PyRefTracer 関数の event 引数に渡される値です。

int PyRefTracer_DESTROY

The value for the event parameter to PyRefTracer functions when a Python object has been destroyed.

int PyRefTracer_TRACKER_REMOVED

現在のトレーサが新しいトレーサに置き換えられる直前に、PyRefTracer 関数の event 引数に渡される値です。

Added in version 3.14.

int PyRefTracer_SetTracer(PyRefTracer tracer, void *data)

参照トレーサ関数を登録します。 この関数は、Python オブジェクトが新しく作成されたときと、これから破棄されるときに呼び出されます。 data を指定する場合は不透明なポインタでなければならず、トレーサ関数の呼び出し時に渡されます。 成功した場合は 0 を返します。 エラーの場合は例外を設定して -1 を返します。

トレーサ関数の内部では Python オブジェクトを作成しては いけません。 作成すると、トレーサ関数が再入されてしまいます。 また、既存の例外をクリアしたり、新しい例外を設定したりしては いけません。 トレーサ関数が呼び出されるときは、常に スレッド状態 が有効です。

この関数の呼び出し時には スレッド状態がアタッチされている 必要があります。

別のトレーサ関数がすでに登録されている場合、新しい関数の登録直前に、event を PyRefTracer_TRACKER_REMOVED として古い関数が呼び出されます。

Added in version 3.13.

PyRefTracer PyRefTracer_GetTracer(void **data)

登録された参照トレーサ関数と、PyRefTracer_SetTracer() の呼び出し時に登録された不透明なデータポインタの値を取得します。 トレーサが登録されていない場合は NULL を返し、data ポインタを NULL に設定します。

この関数の呼び出し時には スレッド状態がアタッチされている 必要があります。

Added in version 3.13.

パフォーマンス統計

PYSTATS_MAX_UOP_ID

CPython がパフォーマンス統計用カウンタを割り当てるマイクロ命令の識別子の最大値。 --enable-pystats で構成したビルドでのみ利用できます。

この定数は内部専用で、拡張モジュールには役立ちません。

バージョン 3.15.2 で ソフト非推奨 <Soft deprecated>.