Profiling and tracing
*********************

Python 解释器为附加的性能分析和执行跟踪工具提供了一些低层级的支持。它
们可被用于性能分析、调试和覆盖分析工具。

这个 C 接口允许性能分析或跟踪代码避免调用 Python 层级的可调用对象带来
的开销，它能直接执行 C 函数调用。 此工具的基本属性没有变化；这个接口允
许针对每个线程安装跟踪函数，并且向跟踪函数报告的基本事件与之前版本中向
Python 层级跟踪函数报告的事件相同。

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

   使用 "PyEval_SetProfile()" 和 "PyEval_SetTrace()" 注册的跟踪函数的
   类型。 第一个形参是作为 *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* 形参将作为第一个形参传给该函数
   ，它可以是任意 Python 对象或为 "NULL"。 如果性能分析函数需要维护状
   态，则为每个线程的 *obj* 使用不同的值将提供一个方便而线程安全的存储
   位置。这个性能分析函数将针对除 "PyTrace_LINE" "PyTrace_OPCODE" 和
   "PyTrace_EXCEPTION" 以外的所有被监控事件进行调用。

   另请参阅 "sys.setprofile()" 函数。

   调用方必须有已附加的线程状态 *attached thread state*。

void PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *obj)

   类似于 "PyEval_SetProfile()" 但会在属于当前解释器的所有在运行线程中
   设置性能分析函数而不是仅在当前线程上设置。

   调用方必须有已附加的线程状态 *attached thread state*。

   与 "PyEval_SetProfile()" 一样，该函数会忽略任何被引发的异常同时在所
   有线程中设置性能分析函数。

Added in version 3.12.

void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)

   将跟踪函数设为 *func*。这类似于 "PyEval_SetProfile()"，区别在于跟踪
   函数会接收行编号事件和操作码级事件，但不会接收与被调用的 C 函数对象
   相关的任何事件。使用 "PyEval_SetTrace()" 注册的任何跟踪函数将不会接
   收 "PyTrace_C_CALL"、"PyTrace_C_EXCEPTION" 或 "PyTrace_C_RETURN" 作
   为 *what* 形参的值。

   另请参阅 "sys.settrace()" 函数。

   调用方必须有已附加的线程状态 *attached thread state*。

void PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *obj)

   类似于 "PyEval_SetTrace()" 但会在属于当前解释器的所有在运行线程中设
   置跟踪函数而不是仅在当前线程上设置。

   调用方必须有已附加的线程状态 *attached thread state*。

   与 "PyEval_SetTrace()" 一样，该函数会忽略任何被引发的异常同时在所有
   线程中设置跟踪函数。

Added in version 3.12.


引用追踪
********

Added in version 3.13.

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

   使用 "PyRefTracer_SetTracer()" 注册的追踪函数的类型。第一个形参是刚
   创建（当 **event** 被设为 "PyRefTracer_CREATE" 时）或将销毁（当
   **event** 被设为 "PyRefTracer_DESTROY" 时）的 Python 对象。
   **data** 参数是当 "PyRefTracer_SetTracer()" 被调用时所提供的不透明
   指针。

   If a new tracing function is registered replacing the current one,
   a call to the trace function will be made with the object set to
   **NULL** and **event** set to "PyRefTracer_TRACKER_REMOVED". This
   will happen just before the new function is registered.

Added in version 3.13.

int PyRefTracer_CREATE

   当一个 Python 对象被创建时传给 "PyRefTracer" 函数的 *event* 形参。

int PyRefTracer_DESTROY

   当一个 Python 对象被销毁时传给 "PyRefTracer" 函数的 *event* 形参。

int PyRefTracer_TRACKER_REMOVED

   The value for the *event* parameter to "PyRefTracer" functions when
   the current tracer is about to be replaced by a new one.

   Added in version 3.14.

int PyRefTracer_SetTracer(PyRefTracer tracer, void *data)

   Register a reference tracer function. The function will be called
   when a new Python object has been created or when an object is
   going to be destroyed. If **data** is provided it must be an opaque
   pointer that will be provided when the tracer function is called.
   Return "0" on success. Set an exception and return "-1" on error.

   Note that tracer functions **must not** create Python objects
   inside or otherwise the call will be re-entrant. The tracer also
   **must not** clear any existing exception or set an exception.  A
   *thread state* will be active every time the tracer function is
   called.

   当调用此函数时必须有一个 *attached thread state*。

   If another tracer function was already registered, the old function
   will be called with **event** set to "PyRefTracer_TRACKER_REMOVED"
   just before the new function is registered.

Added in version 3.13.

PyRefTracer PyRefTracer_GetTracer(void **data)

   获取已注册的引用追踪函数以及当 "PyRefTracer_SetTracer()" 被调用时所
   注册的不透明数据指针的值。 如果未注册任何追踪器则此函数将返回 NULL
   并将 **data** 指针设为 NULL。

   当调用此函数时必须有一个 *attached thread state*。

Added in version 3.13.


Performance statistics
**********************

PYSTATS_MAX_UOP_ID

   Largest micro-operation identifier for which CPython allocates
   performance statistics counters. Available only in builds
   configured with "--enable-pystats".

   This constant is intended for internal use only and is not useful
   to extension modules.

   自 3.15.2 版起已处于 Soft deprecated 状态.
