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

   The value of the *what* parameter to a "Py_tracefunc" function when
   an exception has been raised.  The callback function is called with
   this value for *what* when after any bytecode is processed after
   which the exception becomes set within the frame being executed.
   The effect of this is that as exception propagation causes the
   Python stack to unwind, the callback is called upon return to each
   frame as the exception propagates.  Only trace functions receive
   these events; they are not needed by the profiler.

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.
