bpo-38644: Add _PySys_Audit() which takes tstate (GH-19180)
Add _PySys_Audit() function to the internal C API: similar to PySys_Audit(), but requires a mandatory tstate parameter. Cleanup sys_audit_tstate() code: remove code path for NULL tstate, since the function exits at entry if tstate is NULL. Remove also code path for NULL tstate->interp: should_audit() now ensures that it is not NULL (even if tstate->interp cannot be NULL in practice). PySys_AddAuditHook() now checks if tstate is not NULL to decide if tstate can be used or not, and tstate is set to NULL if the runtime is not initialized yet. Use _PySys_Audit() in sysmodule.c.
This commit is contained in:
parent
e0b8101492
commit
08faf0016e
|
@ -13,7 +13,10 @@ PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *);
|
||||||
|
|
||||||
typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *);
|
typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *);
|
||||||
|
|
||||||
PyAPI_FUNC(int) PySys_Audit(const char*, const char *, ...);
|
PyAPI_FUNC(int) PySys_Audit(
|
||||||
|
const char *event,
|
||||||
|
const char *argFormat,
|
||||||
|
...);
|
||||||
PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*);
|
PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef Py_INTERNAL_SYSMODULE_H
|
||||||
|
#define Py_INTERNAL_SYSMODULE_H
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Py_BUILD_CORE
|
||||||
|
# error "this header requires Py_BUILD_CORE define"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PyAPI_FUNC(int) _PySys_Audit(
|
||||||
|
PyThreadState *tstate,
|
||||||
|
const char *event,
|
||||||
|
const char *argFormat,
|
||||||
|
...);
|
||||||
|
|
||||||
|
/* We want minimal exposure of this function, so use extern rather than
|
||||||
|
PyAPI_FUNC() to not export the symbol. */
|
||||||
|
extern void _PySys_ClearAuditHooks(PyThreadState *tstate);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* !Py_INTERNAL_SYSMODULE_H */
|
|
@ -1101,6 +1101,7 @@ PYTHON_HEADERS= \
|
||||||
$(srcdir)/Include/internal/pycore_pylifecycle.h \
|
$(srcdir)/Include/internal/pycore_pylifecycle.h \
|
||||||
$(srcdir)/Include/internal/pycore_pymem.h \
|
$(srcdir)/Include/internal/pycore_pymem.h \
|
||||||
$(srcdir)/Include/internal/pycore_pystate.h \
|
$(srcdir)/Include/internal/pycore_pystate.h \
|
||||||
|
$(srcdir)/Include/internal/pycore_sysmodule.h \
|
||||||
$(srcdir)/Include/internal/pycore_traceback.h \
|
$(srcdir)/Include/internal/pycore_traceback.h \
|
||||||
$(srcdir)/Include/internal/pycore_tupleobject.h \
|
$(srcdir)/Include/internal/pycore_tupleobject.h \
|
||||||
$(srcdir)/Include/internal/pycore_warnings.h \
|
$(srcdir)/Include/internal/pycore_warnings.h \
|
||||||
|
|
|
@ -183,6 +183,7 @@
|
||||||
<ClInclude Include="..\Include\internal\pycore_pylifecycle.h" />
|
<ClInclude Include="..\Include\internal\pycore_pylifecycle.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_pymem.h" />
|
<ClInclude Include="..\Include\internal\pycore_pymem.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_pystate.h" />
|
<ClInclude Include="..\Include\internal\pycore_pystate.h" />
|
||||||
|
<ClInclude Include="..\Include\internal\pycore_sysmodule.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_traceback.h" />
|
<ClInclude Include="..\Include\internal\pycore_traceback.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_tupleobject.h" />
|
<ClInclude Include="..\Include\internal\pycore_tupleobject.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_warnings.h" />
|
<ClInclude Include="..\Include\internal\pycore_warnings.h" />
|
||||||
|
|
|
@ -252,6 +252,9 @@
|
||||||
<ClInclude Include="..\Include\internal\pycore_pystate.h">
|
<ClInclude Include="..\Include\internal\pycore_pystate.h">
|
||||||
<Filter>Include</Filter>
|
<Filter>Include</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Include\internal\pycore_sysmodule.h">
|
||||||
|
<Filter>Include</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\Include\internal\pycore_traceback.h">
|
<ClInclude Include="..\Include\internal\pycore_traceback.h">
|
||||||
<Filter>Include</Filter>
|
<Filter>Include</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "pycore_pylifecycle.h"
|
#include "pycore_pylifecycle.h"
|
||||||
#include "pycore_pymem.h"
|
#include "pycore_pymem.h"
|
||||||
#include "pycore_pystate.h"
|
#include "pycore_pystate.h"
|
||||||
|
#include "pycore_sysmodule.h"
|
||||||
#include "pycore_traceback.h"
|
#include "pycore_traceback.h"
|
||||||
#include "grammar.h"
|
#include "grammar.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
@ -1409,11 +1410,7 @@ Py_FinalizeEx(void)
|
||||||
_PyGC_CollectIfEnabled();
|
_PyGC_CollectIfEnabled();
|
||||||
|
|
||||||
/* Clear all loghooks */
|
/* Clear all loghooks */
|
||||||
/* We want minimal exposure of this function, so define the extern
|
_PySys_ClearAuditHooks(tstate);
|
||||||
* here. The linker should discover the correct function without
|
|
||||||
* exporting a symbol. */
|
|
||||||
extern void _PySys_ClearAuditHooks(void);
|
|
||||||
_PySys_ClearAuditHooks();
|
|
||||||
|
|
||||||
/* Destroy all modules */
|
/* Destroy all modules */
|
||||||
_PyImport_Cleanup(tstate);
|
_PyImport_Cleanup(tstate);
|
||||||
|
|
|
@ -137,58 +137,67 @@ PySys_SetObject(const char *name, PyObject *v)
|
||||||
return sys_set_object(tstate, name, v);
|
return sys_set_object(tstate, name, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
should_audit(PyThreadState *ts)
|
should_audit(PyInterpreterState *is)
|
||||||
{
|
{
|
||||||
if (!ts) {
|
/* tstate->interp cannot be NULL, but test it just in case
|
||||||
|
for extra safety */
|
||||||
|
assert(is != NULL);
|
||||||
|
if (!is) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
PyInterpreterState *is = ts ? ts->interp : NULL;
|
return (is->runtime->audit_hook_head
|
||||||
return _PyRuntime.audit_hook_head
|
|| is->audit_hooks
|
||||||
|| (is && is->audit_hooks)
|
|| PyDTrace_AUDIT_ENABLED());
|
||||||
|| PyDTrace_AUDIT_ENABLED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
PySys_Audit(const char *event, const char *argFormat, ...)
|
|
||||||
{
|
|
||||||
PyObject *eventName = NULL;
|
|
||||||
PyObject *eventArgs = NULL;
|
|
||||||
PyObject *hooks = NULL;
|
|
||||||
PyObject *hook = NULL;
|
|
||||||
int res = -1;
|
|
||||||
PyThreadState *ts = _PyThreadState_GET();
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
sys_audit_tstate(PyThreadState *ts, const char *event,
|
||||||
|
const char *argFormat, va_list vargs)
|
||||||
|
{
|
||||||
/* N format is inappropriate, because you do not know
|
/* N format is inappropriate, because you do not know
|
||||||
whether the reference is consumed by the call.
|
whether the reference is consumed by the call.
|
||||||
Assert rather than exception for perf reasons */
|
Assert rather than exception for perf reasons */
|
||||||
assert(!argFormat || !strchr(argFormat, 'N'));
|
assert(!argFormat || !strchr(argFormat, 'N'));
|
||||||
|
|
||||||
/* Early exit when no hooks are registered */
|
if (!ts) {
|
||||||
if (!should_audit(ts)) {
|
/* Audit hooks cannot be called with a NULL thread state */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_Py_AuditHookEntry *e = _PyRuntime.audit_hook_head;
|
/* The current implementation cannot be called if tstate is not
|
||||||
|
the current Python thread state. */
|
||||||
|
assert(ts == _PyThreadState_GET());
|
||||||
|
|
||||||
|
/* Early exit when no hooks are registered */
|
||||||
|
PyInterpreterState *is = ts->interp;
|
||||||
|
if (!should_audit(is)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *eventName = NULL;
|
||||||
|
PyObject *eventArgs = NULL;
|
||||||
|
PyObject *hooks = NULL;
|
||||||
|
PyObject *hook = NULL;
|
||||||
|
int res = -1;
|
||||||
|
|
||||||
int dtrace = PyDTrace_AUDIT_ENABLED();
|
int dtrace = PyDTrace_AUDIT_ENABLED();
|
||||||
|
|
||||||
PyObject *exc_type, *exc_value, *exc_tb;
|
PyObject *exc_type, *exc_value, *exc_tb;
|
||||||
if (ts) {
|
_PyErr_Fetch(ts, &exc_type, &exc_value, &exc_tb);
|
||||||
_PyErr_Fetch(ts, &exc_type, &exc_value, &exc_tb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize event args now */
|
/* Initialize event args now */
|
||||||
if (argFormat && argFormat[0]) {
|
if (argFormat && argFormat[0]) {
|
||||||
va_list args;
|
eventArgs = _Py_VaBuildValue_SizeT(argFormat, vargs);
|
||||||
va_start(args, argFormat);
|
|
||||||
eventArgs = _Py_VaBuildValue_SizeT(argFormat, args);
|
|
||||||
va_end(args);
|
|
||||||
if (eventArgs && !PyTuple_Check(eventArgs)) {
|
if (eventArgs && !PyTuple_Check(eventArgs)) {
|
||||||
PyObject *argTuple = PyTuple_Pack(1, eventArgs);
|
PyObject *argTuple = PyTuple_Pack(1, eventArgs);
|
||||||
Py_DECREF(eventArgs);
|
Py_DECREF(eventArgs);
|
||||||
eventArgs = argTuple;
|
eventArgs = argTuple;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
eventArgs = PyTuple_New(0);
|
eventArgs = PyTuple_New(0);
|
||||||
}
|
}
|
||||||
if (!eventArgs) {
|
if (!eventArgs) {
|
||||||
|
@ -196,6 +205,7 @@ PySys_Audit(const char *event, const char *argFormat, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call global hooks */
|
/* Call global hooks */
|
||||||
|
_Py_AuditHookEntry *e = is->runtime->audit_hook_head;
|
||||||
for (; e; e = e->next) {
|
for (; e; e = e->next) {
|
||||||
if (e->hookCFunction(event, eventArgs, e->userData) < 0) {
|
if (e->hookCFunction(event, eventArgs, e->userData) < 0) {
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -208,8 +218,7 @@ PySys_Audit(const char *event, const char *argFormat, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call interpreter hooks */
|
/* Call interpreter hooks */
|
||||||
PyInterpreterState *is = ts ? ts->interp : NULL;
|
if (is->audit_hooks) {
|
||||||
if (is && is->audit_hooks) {
|
|
||||||
eventName = PyUnicode_FromString(event);
|
eventName = PyUnicode_FromString(event);
|
||||||
if (!eventName) {
|
if (!eventName) {
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -238,8 +247,8 @@ PySys_Audit(const char *event, const char *argFormat, ...)
|
||||||
ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc);
|
ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc);
|
||||||
ts->tracing--;
|
ts->tracing--;
|
||||||
}
|
}
|
||||||
o = PyObject_CallFunctionObjArgs(hook, eventName,
|
PyObject* args[2] = {eventName, eventArgs};
|
||||||
eventArgs, NULL);
|
o = _PyObject_FastCallTstate(ts, hook, args, 2);
|
||||||
if (canTrace) {
|
if (canTrace) {
|
||||||
ts->tracing++;
|
ts->tracing++;
|
||||||
ts->use_tracing = 0;
|
ts->use_tracing = 0;
|
||||||
|
@ -265,33 +274,66 @@ exit:
|
||||||
Py_XDECREF(eventName);
|
Py_XDECREF(eventName);
|
||||||
Py_XDECREF(eventArgs);
|
Py_XDECREF(eventArgs);
|
||||||
|
|
||||||
if (ts) {
|
if (!res) {
|
||||||
if (!res) {
|
_PyErr_Restore(ts, exc_type, exc_value, exc_tb);
|
||||||
_PyErr_Restore(ts, exc_type, exc_value, exc_tb);
|
}
|
||||||
} else {
|
else {
|
||||||
assert(_PyErr_Occurred(ts));
|
assert(_PyErr_Occurred(ts));
|
||||||
Py_XDECREF(exc_type);
|
Py_XDECREF(exc_type);
|
||||||
Py_XDECREF(exc_value);
|
Py_XDECREF(exc_value);
|
||||||
Py_XDECREF(exc_tb);
|
Py_XDECREF(exc_tb);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_PySys_Audit(PyThreadState *tstate, const char *event,
|
||||||
|
const char *argFormat, ...)
|
||||||
|
{
|
||||||
|
va_list vargs;
|
||||||
|
#ifdef HAVE_STDARG_PROTOTYPES
|
||||||
|
va_start(vargs, argFormat);
|
||||||
|
#else
|
||||||
|
va_start(vargs);
|
||||||
|
#endif
|
||||||
|
int res = sys_audit_tstate(tstate, event, argFormat, vargs);
|
||||||
|
va_end(vargs);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
PySys_Audit(const char *event, const char *argFormat, ...)
|
||||||
|
{
|
||||||
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
|
va_list vargs;
|
||||||
|
#ifdef HAVE_STDARG_PROTOTYPES
|
||||||
|
va_start(vargs, argFormat);
|
||||||
|
#else
|
||||||
|
va_start(vargs);
|
||||||
|
#endif
|
||||||
|
int res = sys_audit_tstate(tstate, event, argFormat, vargs);
|
||||||
|
va_end(vargs);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/* We expose this function primarily for our own cleanup during
|
/* We expose this function primarily for our own cleanup during
|
||||||
* finalization. In general, it should not need to be called,
|
* finalization. In general, it should not need to be called,
|
||||||
* and as such it is not defined in any header files.
|
* and as such the function is not exported.
|
||||||
*/
|
*
|
||||||
|
* Must be finalizing to clear hooks */
|
||||||
void
|
void
|
||||||
_PySys_ClearAuditHooks(void)
|
_PySys_ClearAuditHooks(PyThreadState *ts)
|
||||||
{
|
{
|
||||||
/* Must be finalizing to clear hooks */
|
assert(ts != NULL);
|
||||||
_PyRuntimeState *runtime = &_PyRuntime;
|
if (!ts) {
|
||||||
PyThreadState *ts = _PyRuntimeState_GetThreadState(runtime);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_PyRuntimeState *runtime = ts->interp->runtime;
|
||||||
PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime);
|
PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime);
|
||||||
assert(!ts || finalizing == ts);
|
assert(finalizing == ts);
|
||||||
if (!ts || finalizing != ts) {
|
if (finalizing != ts) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,11 +344,11 @@ _PySys_ClearAuditHooks(void)
|
||||||
|
|
||||||
/* Hooks can abort later hooks for this event, but cannot
|
/* Hooks can abort later hooks for this event, but cannot
|
||||||
abort the clear operation itself. */
|
abort the clear operation itself. */
|
||||||
PySys_Audit("cpython._PySys_ClearAuditHooks", NULL);
|
_PySys_Audit(ts, "cpython._PySys_ClearAuditHooks", NULL);
|
||||||
_PyErr_Clear(ts);
|
_PyErr_Clear(ts);
|
||||||
|
|
||||||
_Py_AuditHookEntry *e = _PyRuntime.audit_hook_head, *n;
|
_Py_AuditHookEntry *e = runtime->audit_hook_head, *n;
|
||||||
_PyRuntime.audit_hook_head = NULL;
|
runtime->audit_hook_head = NULL;
|
||||||
while (e) {
|
while (e) {
|
||||||
n = e->next;
|
n = e->next;
|
||||||
PyMem_RawFree(e);
|
PyMem_RawFree(e);
|
||||||
|
@ -317,13 +359,21 @@ _PySys_ClearAuditHooks(void)
|
||||||
int
|
int
|
||||||
PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
|
PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
|
||||||
{
|
{
|
||||||
|
/* tstate can be NULL, so access directly _PyRuntime:
|
||||||
|
PySys_AddAuditHook() can be called before Python is initialized. */
|
||||||
_PyRuntimeState *runtime = &_PyRuntime;
|
_PyRuntimeState *runtime = &_PyRuntime;
|
||||||
PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
|
PyThreadState *tstate;
|
||||||
|
if (runtime->initialized) {
|
||||||
|
tstate = _PyRuntimeState_GetThreadState(runtime);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tstate = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Invoke existing audit hooks to allow them an opportunity to abort. */
|
/* Invoke existing audit hooks to allow them an opportunity to abort. */
|
||||||
/* Cannot invoke hooks until we are initialized */
|
/* Cannot invoke hooks until we are initialized */
|
||||||
if (runtime->initialized) {
|
if (tstate != NULL) {
|
||||||
if (PySys_Audit("sys.addaudithook", NULL) < 0) {
|
if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) {
|
||||||
if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) {
|
if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) {
|
||||||
/* We do not report errors derived from RuntimeError */
|
/* We do not report errors derived from RuntimeError */
|
||||||
_PyErr_Clear(tstate);
|
_PyErr_Clear(tstate);
|
||||||
|
@ -333,10 +383,10 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_Py_AuditHookEntry *e = _PyRuntime.audit_hook_head;
|
_Py_AuditHookEntry *e = runtime->audit_hook_head;
|
||||||
if (!e) {
|
if (!e) {
|
||||||
e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry));
|
e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry));
|
||||||
_PyRuntime.audit_hook_head = e;
|
runtime->audit_hook_head = e;
|
||||||
} else {
|
} else {
|
||||||
while (e->next) {
|
while (e->next) {
|
||||||
e = e->next;
|
e = e->next;
|
||||||
|
@ -346,7 +396,7 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!e) {
|
if (!e) {
|
||||||
if (runtime->initialized) {
|
if (tstate != NULL) {
|
||||||
_PyErr_NoMemory(tstate);
|
_PyErr_NoMemory(tstate);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -374,7 +424,7 @@ sys_addaudithook_impl(PyObject *module, PyObject *hook)
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
|
|
||||||
/* Invoke existing audit hooks to allow them an opportunity to abort. */
|
/* Invoke existing audit hooks to allow them an opportunity to abort. */
|
||||||
if (PySys_Audit("sys.addaudithook", NULL) < 0) {
|
if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) {
|
||||||
if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) {
|
if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) {
|
||||||
/* We do not report errors derived from Exception */
|
/* We do not report errors derived from Exception */
|
||||||
_PyErr_Clear(tstate);
|
_PyErr_Clear(tstate);
|
||||||
|
@ -384,7 +434,6 @@ sys_addaudithook_impl(PyObject *module, PyObject *hook)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyInterpreterState *is = tstate->interp;
|
PyInterpreterState *is = tstate->interp;
|
||||||
|
|
||||||
if (is->audit_hooks == NULL) {
|
if (is->audit_hooks == NULL) {
|
||||||
is->audit_hooks = PyList_New(0);
|
is->audit_hooks = PyList_New(0);
|
||||||
if (is->audit_hooks == NULL) {
|
if (is->audit_hooks == NULL) {
|
||||||
|
@ -408,6 +457,7 @@ static PyObject *
|
||||||
sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc)
|
sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc)
|
||||||
{
|
{
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
|
assert(tstate != NULL);
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
_PyErr_SetString(tstate, PyExc_TypeError,
|
_PyErr_SetString(tstate, PyExc_TypeError,
|
||||||
|
@ -416,7 +466,7 @@ sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!should_audit(tstate)) {
|
if (!should_audit(tstate->interp)) {
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +492,7 @@ sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = PySys_Audit(event, "O", auditArgs);
|
int res = _PySys_Audit(tstate, event, "O", auditArgs);
|
||||||
Py_DECREF(auditArgs);
|
Py_DECREF(auditArgs);
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
@ -1739,7 +1789,7 @@ sys__getframe_impl(PyObject *module, int depth)
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
PyFrameObject *f = tstate->frame;
|
PyFrameObject *f = tstate->frame;
|
||||||
|
|
||||||
if (PySys_Audit("sys._getframe", "O", f) < 0) {
|
if (_PySys_Audit(tstate, "sys._getframe", "O", f) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue