Skip to content

Commit e1d4fdc

Browse files
zoobazkonge
andauthored
bpo-41162: Clear audit hooks later during finalization (GH-21222)
Co-authored-by: Konge <zkonge@outlook.com>
1 parent 1c77654 commit e1d4fdc

5 files changed

Lines changed: 16 additions & 45 deletions

File tree

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
@@ -1116,8 +1116,11 @@ static int test_open_code_hook(void)
11161116
return result;
11171117
}
11181118

1119+
static int _audit_hook_clear_count = 0;
1120+
11191121
static int _audit_hook(const char *event, PyObject *args, void *userdata)
11201122
{
1123+
assert(args && PyTuple_CheckExact(args));
11211124
if (strcmp(event, "_testembed.raise") == 0) {
11221125
PyErr_SetString(PyExc_RuntimeError, "Intentional error");
11231126
return -1;
@@ -1126,6 +1129,8 @@ static int _audit_hook(const char *event, PyObject *args, void *userdata)
11261129
return -1;
11271130
}
11281131
return 0;
1132+
} else if (strcmp(event, "cpython._PySys_ClearAuditHooks") == 0) {
1133+
_audit_hook_clear_count += 1;
11291134
}
11301135
return 0;
11311136
}
@@ -1171,6 +1176,9 @@ static int test_audit(void)
11711176
{
11721177
int result = _test_audit(42);
11731178
Py_Finalize();
1179+
if (_audit_hook_clear_count != 1) {
1180+
return 0x1000 | _audit_hook_clear_count;
1181+
}
11741182
return result;
11751183
}
11761184

Python/pylifecycle.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,13 @@ finalize_interp_clear(PyThreadState *tstate)
13031303

13041304
finalize_interp_types(tstate, is_main_interp);
13051305

1306+
/* Clear all loghooks */
1307+
/* Both _PySys_Audit function and users still need PyObject, such as tuple.
1308+
Call _PySys_ClearAuditHooks when PyObject available. */
1309+
if (is_main_interp) {
1310+
_PySys_ClearAuditHooks(tstate);
1311+
}
1312+
13061313
if (is_main_interp) {
13071314
/* XXX Still allocated:
13081315
- various static ad-hoc pointers to interned strings
@@ -1419,9 +1426,6 @@ Py_FinalizeEx(void)
14191426
*/
14201427
_PyGC_CollectIfEnabled();
14211428

1422-
/* Clear all loghooks */
1423-
_PySys_ClearAuditHooks(tstate);
1424-
14251429
/* Destroy all modules */
14261430
_PyImport_Cleanup(tstate);
14271431

0 commit comments

Comments
 (0)