Skip to content

Commit daa0fe0

Browse files
authored
bpo-41162: Clear audit hooks later during finalization (GH-21222)
1 parent d160e0f commit daa0fe0

File tree

5 files changed

+16
-45
lines changed

5 files changed

+16
-45
lines changed

Lib/test/audit-tests.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,28 +44,6 @@ def __call__(self, event, args):
4444
raise self.exc_type("saw event " + event)
4545

4646

47-
class TestFinalizeHook:
48-
"""Used in the test_finalize_hooks function to ensure that hooks
49-
are correctly cleaned up, that they are notified about the cleanup,
50-
and are unable to prevent it.
51-
"""
52-
53-
def __init__(self):
54-
print("Created", id(self), file=sys.stdout, flush=True)
55-
56-
def __call__(self, event, args):
57-
# Avoid recursion when we call id() below
58-
if event == "builtins.id":
59-
return
60-
61-
print(event, id(self), file=sys.stdout, flush=True)
62-
63-
if event == "cpython._PySys_ClearAuditHooks":
64-
raise RuntimeError("Should be ignored")
65-
elif event == "cpython.PyInterpreterState_Clear":
66-
raise RuntimeError("Should be ignored")
67-
68-
6947
# Simple helpers, since we are not in unittest here
7048
def assertEqual(x, y):
7149
if x != y:
@@ -128,10 +106,6 @@ def test_block_add_hook_baseexception():
128106
pass
129107

130108

131-
def test_finalize_hooks():
132-
sys.addaudithook(TestFinalizeHook())
133-
134-
135109
def test_pickle():
136110
import pickle
137111

Lib/test/test_audit.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,6 @@ def test_block_add_hook(self):
5151
def test_block_add_hook_baseexception(self):
5252
self.do_test("test_block_add_hook_baseexception")
5353

54-
def test_finalize_hooks(self):
55-
returncode, events, stderr = self.run_python("test_finalize_hooks")
56-
if stderr:
57-
print(stderr, file=sys.stderr)
58-
if returncode:
59-
self.fail(stderr)
60-
61-
firstId = events[0][2]
62-
self.assertSequenceEqual(
63-
[
64-
("Created", " ", firstId),
65-
("cpython._PySys_ClearAuditHooks", " ", firstId),
66-
],
67-
events,
68-
)
69-
7054
def test_pickle(self):
7155
support.import_module("pickle")
7256

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Audit hooks are now cleared later during finalization to avoid missing events.

Programs/_testembed.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,8 +1112,11 @@ static int test_open_code_hook(void)
11121112
return result;
11131113
}
11141114

1115+
static int _audit_hook_clear_count = 0;
1116+
11151117
static int _audit_hook(const char *event, PyObject *args, void *userdata)
11161118
{
1119+
assert(args && PyTuple_CheckExact(args));
11171120
if (strcmp(event, "_testembed.raise") == 0) {
11181121
PyErr_SetString(PyExc_RuntimeError, "Intentional error");
11191122
return -1;
@@ -1122,6 +1125,8 @@ static int _audit_hook(const char *event, PyObject *args, void *userdata)
11221125
return -1;
11231126
}
11241127
return 0;
1128+
} else if (strcmp(event, "cpython._PySys_ClearAuditHooks") == 0) {
1129+
_audit_hook_clear_count += 1;
11251130
}
11261131
return 0;
11271132
}
@@ -1167,6 +1172,9 @@ static int test_audit(void)
11671172
{
11681173
int result = _test_audit(42);
11691174
Py_Finalize();
1175+
if (_audit_hook_clear_count != 1) {
1176+
return 0x1000 | _audit_hook_clear_count;
1177+
}
11701178
return result;
11711179
}
11721180

Python/pylifecycle.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,13 @@ finalize_interp_clear(PyThreadState *tstate)
12911291
_PyGC_CollectNoFail();
12921292
}
12931293

1294+
/* Clear all loghooks */
1295+
/* Both _PySys_Audit function and users still need PyObject, such as tuple.
1296+
Call _PySys_ClearAuditHooks when PyObject available. */
1297+
if (is_main_interp) {
1298+
_PySys_ClearAuditHooks(tstate);
1299+
}
1300+
12941301
_PyGC_Fini(tstate);
12951302

12961303
if (is_main_interp) {
@@ -1405,9 +1412,6 @@ Py_FinalizeEx(void)
14051412
*/
14061413
_PyGC_CollectIfEnabled();
14071414

1408-
/* Clear all loghooks */
1409-
_PySys_ClearAuditHooks(tstate);
1410-
14111415
/* Destroy all modules */
14121416
_PyImport_Cleanup(tstate);
14131417

0 commit comments

Comments
 (0)