> **Источник:** https://python-all.ru/3/c-api/profiling.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# Профилирование и трассировка

Интерпретатор Python предоставляет низкоуровневую поддержку для подключения средств профилирования и трассировки выполнения. Они используются в инструментах профилирования, отладки и анализа покрытия.

Этот C-интерфейс позволяет коду профилирования или трассировки избежать накладных расходов на вызов через вызываемые объекты уровня Python, выполняя вместо этого прямой вызов C-функции. Основные характеристики механизма не изменились; интерфейс позволяет устанавливать функции трассировки для каждого потока, а базовые события, сообщаемые функции трассировки, такие же, как и в предыдущих версиях для функций трассировки уровня Python.

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

Тип функции трассировки, регистрируемой с помощью [`PyEval_SetProfile()`](https://python-all.ru/3/c-api/profiling.html#c.PyEval_SetProfile) и [`PyEval_SetTrace()`](https://python-all.ru/3/c-api/profiling.html#c.PyEval_SetTrace). Первый параметр – это объект, переданный функции регистрации как *obj*, *frame* – это объект фрейма, к которому относится событие, *what* – одна из констант [`PyTrace_CALL`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_CALL), [`PyTrace_EXCEPTION`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_EXCEPTION), [`PyTrace_LINE`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_LINE), [`PyTrace_RETURN`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_RETURN), [`PyTrace_C_CALL`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_C_CALL), [`PyTrace_C_EXCEPTION`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_C_EXCEPTION), [`PyTrace_C_RETURN`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_C_RETURN) или [`PyTrace_OPCODE`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_OPCODE), а *arg* зависит от значения *what*:

| Значение *what* | Смысл *arg* |
| --- | --- |
| [`PyTrace_CALL`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_CALL) | Всегда [`Py_None`](https://python-all.ru/3/c-api/none.html#c.Py_None). |
| [`PyTrace_EXCEPTION`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_EXCEPTION) | Информация об исключении, возвращаемая [`sys.exc_info()`](https://python-all.ru/3/library/sys.html#sys.exc_info). |
| [`PyTrace_LINE`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_LINE) | Всегда [`Py_None`](https://python-all.ru/3/c-api/none.html#c.Py_None). |
| [`PyTrace_RETURN`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_RETURN) | Значение, возвращаемое вызывающему коду, или `NULL`, если вызвано исключением. |
| [`PyTrace_C_CALL`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_C_CALL) | Вызываемый объект функции. |
| [`PyTrace_C_EXCEPTION`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_C_EXCEPTION) | Вызываемый объект функции. |
| [`PyTrace_C_RETURN`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_C_RETURN) | Вызываемый объект функции. |
| [`PyTrace_OPCODE`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_OPCODE) | Всегда [`Py_None`](https://python-all.ru/3/c-api/none.html#c.Py_None). |

#### `int PyTrace_CALL`

Значение параметра *what* для функции [`Py_tracefunc`](https://python-all.ru/3/c-api/profiling.html#c.Py_tracefunc), когда сообщается о новом вызове функции или метода, или о новом входе в генератор. Обратите внимание, что создание итератора для функции-генератора не сообщается, поскольку в соответствующем фрейме не происходит передачи управления байт-коду Python.

#### `int PyTrace_EXCEPTION`

Значение параметра *what* для функции [`Py_tracefunc`](https://python-all.ru/3/c-api/profiling.html#c.Py_tracefunc), когда возникло исключение. Функция обратного вызова вызывается с этим значением для *what* после обработки любого байт-кода, после которого исключение становится установленным в выполняемом фрейме. В результате, когда распространение исключения вызывает раскрутку стека Python, функция обратного вызова вызывается при возврате в каждый фрейм по мере распространения исключения. Только функции трассировки получают эти события; профилировщику они не нужны.

#### `int PyTrace_LINE`

Значение, передаваемое в качестве параметра *what* функции [`Py_tracefunc`](https://python-all.ru/3/c-api/profiling.html#c.Py_tracefunc) (но не функции профилирования), когда сообщается о событии номера строки. Его можно отключить для фрейма, установив [`f_trace_lines`](https://python-all.ru/3/reference/datamodel.html#frame.f_trace_lines) в *0* в этом фрейме.

#### `int PyTrace_RETURN`

Значение параметра *what* для функций [`Py_tracefunc`](https://python-all.ru/3/c-api/profiling.html#c.Py_tracefunc), когда вызов собирается вернуться.

#### `int PyTrace_C_CALL`

Значение параметра *what* для функций [`Py_tracefunc`](https://python-all.ru/3/c-api/profiling.html#c.Py_tracefunc), когда собирается быть вызвана C-функция.

#### `int PyTrace_C_EXCEPTION`

Значение параметра *what* для функций [`Py_tracefunc`](https://python-all.ru/3/c-api/profiling.html#c.Py_tracefunc), когда C-функция вызвала исключение.

#### `int PyTrace_C_RETURN`

Значение параметра *what* для функций [`Py_tracefunc`](https://python-all.ru/3/c-api/profiling.html#c.Py_tracefunc), когда C-функция вернулась.

#### `int PyTrace_OPCODE`

Значение параметра *what* для функций [`Py_tracefunc`](https://python-all.ru/3/c-api/profiling.html#c.Py_tracefunc) (но не функций профилирования), когда собирается быть выполнен новый опкод. Это событие не генерируется по умолчанию: его нужно явно запросить, установив [`f_trace_opcodes`](https://python-all.ru/3/reference/datamodel.html#frame.f_trace_opcodes) в *1* во фрейме.

#### `void PyEval_SetProfile(Py_tracefunc func, PyObject *obj)`

Устанавливает функцию профилирования в *func*. Параметр *obj* передаётся функции в качестве первого аргумента; это может быть любой объект Python или `NULL`. Если функции профилирования нужно поддерживать состояние, использование разных значений *obj* для каждого потока предоставляет удобное и потокобезопасное место для его хранения. Функция профилирования вызывается для всех отслеживаемых событий, кроме [`PyTrace_LINE`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_LINE), [`PyTrace_OPCODE`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_OPCODE) и [`PyTrace_EXCEPTION`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_EXCEPTION).

См. также функцию [`sys.setprofile()`](https://python-all.ru/3/library/sys.html#sys.setprofile).

Вызывающий должен иметь [прикреплённое состояние потока](https://python-all.ru/3/glossary.html#term-attached-thread-state).

#### `void PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *obj)`

Как [`PyEval_SetProfile()`](https://python-all.ru/3/c-api/profiling.html#c.PyEval_SetProfile), но устанавливает функцию профилирования во всех работающих потоках, принадлежащих текущему интерпретатору, а не только в текущем потоке.

Вызывающий должен иметь [прикреплённое состояние потока](https://python-all.ru/3/glossary.html#term-attached-thread-state).

Как и [`PyEval_SetProfile()`](https://python-all.ru/3/c-api/profiling.html#c.PyEval_SetProfile), эта функция игнорирует любые исключения, возникшие при установке функций профилирования во всех потоках.

Добавлено в версии 3.12.

#### `void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)`

Устанавливает функцию трассировки в *func*. Это похоже на [`PyEval_SetProfile()`](https://python-all.ru/3/c-api/profiling.html#c.PyEval_SetProfile), за исключением того, что функция трассировки получает события номеров строк и события на каждую операцию, но не получает событий, связанных с вызовом объектов функций C. Любая функция трассировки, зарегистрированная через [`PyEval_SetTrace()`](https://python-all.ru/3/c-api/profiling.html#c.PyEval_SetTrace), не будет получать [`PyTrace_C_CALL`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_C_CALL), [`PyTrace_C_EXCEPTION`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_C_EXCEPTION) или [`PyTrace_C_RETURN`](https://python-all.ru/3/c-api/profiling.html#c.PyTrace_C_RETURN) в качестве значения параметра *what*.

См. также функцию [`sys.settrace()`](https://python-all.ru/3/library/sys.html#sys.settrace).

Вызывающий должен иметь [прикреплённое состояние потока](https://python-all.ru/3/glossary.html#term-attached-thread-state).

#### `void PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *obj)`

Как [`PyEval_SetTrace()`](https://python-all.ru/3/c-api/profiling.html#c.PyEval_SetTrace), но устанавливает функцию трассировки во всех работающих потоках, принадлежащих текущему интерпретатору, а не только в текущем потоке.

Вызывающий должен иметь [прикреплённое состояние потока](https://python-all.ru/3/glossary.html#term-attached-thread-state).

Как и [`PyEval_SetTrace()`](https://python-all.ru/3/c-api/profiling.html#c.PyEval_SetTrace), эта функция игнорирует любые исключения, возникшие при установке функций трассировки во всех потоках.

Добавлено в версии 3.12.

# Трассировка ссылок

Добавлено в версии 3.13.

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

Тип функции трассировки, регистрируемой с помощью [`PyRefTracer_SetTracer()`](https://python-all.ru/3/c-api/profiling.html#c.PyRefTracer_SetTracer). Первый параметр – это объект Python, который только что был создан (когда **event** установлен в [`PyRefTracer_CREATE`](https://python-all.ru/3/c-api/profiling.html#c.PyRefTracer_CREATE)) или собирается быть уничтожен (когда **event** установлен в [`PyRefTracer_DESTROY`](https://python-all.ru/3/c-api/profiling.html#c.PyRefTracer_DESTROY)). Аргумент **data** – это непрозрачный указатель, который был предоставлен при вызове `PyRefTracer_SetTracer()`.

Если регистрируется новая функция трассировки, заменяющая текущую, будет выполнен вызов функции трассировки с объектом, установленным в **NULL**, и **event**, установленным в [`PyRefTracer_TRACKER_REMOVED`](https://python-all.ru/3/c-api/profiling.html#c.PyRefTracer_TRACKER_REMOVED). Это произойдет непосредственно перед регистрацией новой функции.

Добавлено в версии 3.13.

#### `int PyRefTracer_CREATE`

Значение параметра *event* для функций [`PyRefTracer`](https://python-all.ru/3/c-api/profiling.html#c.PyRefTracer), когда объект Python был создан.

#### `int PyRefTracer_DESTROY`

Значение параметра *event* для функций [`PyRefTracer`](https://python-all.ru/3/c-api/profiling.html#c.PyRefTracer), когда объект Python был уничтожен.

#### `int PyRefTracer_TRACKER_REMOVED`

Значение параметра *event* для функций [`PyRefTracer`](https://python-all.ru/3/c-api/profiling.html#c.PyRefTracer), когда текущий трассировщик собирается быть заменён новым.

Добавлено в версии 3.14.

#### `int PyRefTracer_SetTracer(PyRefTracer tracer, void *data)`

Регистрирует функцию трассировки ссылок. Функция будет вызываться при создании нового объекта Python или при уничтожении объекта. Если указан **data**, это должен быть непрозрачный указатель, который будет предоставлен при вызове функции трассировки. Возвращает `0` в случае успеха. Устанавливает исключение и возвращает `-1` при ошибке.

Обратите внимание, что функции трассировки **не должны** создавать объекты Python внутри, иначе вызов станет реентерабельным. Трассировщик также **не должен** очищать существующие исключения или устанавливать исключения. [Состояние потока](https://python-all.ru/3/glossary.html#term-thread-state) будет активно при каждом вызове функции трассировки.

При вызове этой функции должно быть [присоединённое состояние потока](https://python-all.ru/3/glossary.html#term-attached-thread-state).

Если другая функция трассировки уже была зарегистрирована, старая функция будет вызвана с **event**, установленным в [`PyRefTracer_TRACKER_REMOVED`](https://python-all.ru/3/c-api/profiling.html#c.PyRefTracer_TRACKER_REMOVED), непосредственно перед регистрацией новой функции.

Добавлено в версии 3.13.

#### `PyRefTracer PyRefTracer_GetTracer(void **data)`

Возвращает зарегистрированную функцию трассировки ссылок и значение непрозрачного указателя данных, который был зарегистрирован при вызове [`PyRefTracer_SetTracer()`](https://python-all.ru/3/c-api/profiling.html#c.PyRefTracer_SetTracer). Если трассировщик не был зарегистрирован, эта функция вернёт NULL и установит указатель **data** в NULL.

При вызове этой функции должно быть [присоединённое состояние потока](https://python-all.ru/3/glossary.html#term-attached-thread-state).

Добавлено в версии 3.13.
