Skip to content

Commit b4f9089

Browse files
authored
bpo-43439: Add audit hooks for gc functions (GH-24794)
1 parent 62a03cd commit b4f9089

File tree

6 files changed

+56
-0
lines changed

6 files changed

+56
-0
lines changed

Doc/library/gc.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ The :mod:`gc` module provides the following functions:
7272
.. versionchanged:: 3.8
7373
New *generation* parameter.
7474

75+
.. audit-event:: gc.get_objects generation gc.get_objects
76+
7577
.. function:: get_stats()
7678

7779
Return a list of three per-generation dictionaries containing collection
@@ -141,6 +143,8 @@ The :mod:`gc` module provides the following functions:
141143
invalid state. Avoid using :func:`get_referrers` for any purpose other than
142144
debugging.
143145

146+
.. audit-event:: gc.get_referrers objs gc.get_referrers
147+
144148

145149
.. function:: get_referents(*objs)
146150

@@ -152,6 +156,7 @@ The :mod:`gc` module provides the following functions:
152156
be involved in a cycle. So, for example, if an integer is directly reachable
153157
from an argument, that integer object may or may not appear in the result list.
154158

159+
.. audit-event:: gc.get_referents objs gc.get_referents
155160

156161
.. function:: is_tracked(obj)
157162

Doc/whatsnew/3.10.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,9 +673,16 @@ When a module does not define ``__loader__``, fall back to ``__spec__.loader``.
673673
674674
encodings
675675
---------
676+
676677
:func:`encodings.normalize_encoding` now ignores non-ASCII characters.
677678
(Contributed by Hai Shi in :issue:`39337`.)
678679
680+
gc
681+
--
682+
683+
Added audit hooks for :func:`gc.get_objects`, :func:`gc.get_referrers` and
684+
:func:`gc.get_referents`. (Contributed by Pablo Galindo in :issue:`43439`.)
685+
679686
glob
680687
----
681688

Lib/test/audit-tests.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,24 @@ def hook(event, args):
323323
sock.close()
324324

325325

326+
def test_gc():
327+
import gc
328+
329+
def hook(event, args):
330+
if event.startswith("gc."):
331+
print(event, *args)
332+
333+
sys.addaudithook(hook)
334+
335+
gc.get_objects(generation=1)
336+
337+
x = object()
338+
y = [x]
339+
340+
gc.get_referrers(x)
341+
gc.get_referents(y)
342+
343+
326344
if __name__ == "__main__":
327345
from test.support import suppress_msvcrt_asserts
328346

Lib/test/test_audit.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,5 +118,18 @@ def test_socket(self):
118118
self.assertEqual(events[2][0], "socket.bind")
119119
self.assertTrue(events[2][2].endswith("('127.0.0.1', 8080)"))
120120

121+
def test_gc(self):
122+
returncode, events, stderr = self.run_python("test_gc")
123+
if returncode:
124+
self.fail(stderr)
125+
126+
if support.verbose:
127+
print(*events, sep='\n')
128+
self.assertEqual(
129+
[event[0] for event in events],
130+
["gc.get_objects", "gc.get_referrers", "gc.get_referents"]
131+
)
132+
133+
121134
if __name__ == "__main__":
122135
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add audit hooks for :func:`gc.get_objects`, :func:`gc.get_referrers` and
2+
:func:`gc.get_referents`. Patch by Pablo Galindo.

Modules/gcmodule.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,10 @@ Return the list of objects that directly refer to any of objs.");
16901690
static PyObject *
16911691
gc_get_referrers(PyObject *self, PyObject *args)
16921692
{
1693+
if (PySys_Audit("gc.get_referrers", "O", args) < 0) {
1694+
return NULL;
1695+
}
1696+
16931697
PyObject *result = PyList_New(0);
16941698
if (!result) {
16951699
return NULL;
@@ -1720,6 +1724,9 @@ static PyObject *
17201724
gc_get_referents(PyObject *self, PyObject *args)
17211725
{
17221726
Py_ssize_t i;
1727+
if (PySys_Audit("gc.get_referents", "O", args) < 0) {
1728+
return NULL;
1729+
}
17231730
PyObject *result = PyList_New(0);
17241731

17251732
if (result == NULL)
@@ -1762,6 +1769,10 @@ gc_get_objects_impl(PyObject *module, Py_ssize_t generation)
17621769
PyObject* result;
17631770
GCState *gcstate = &tstate->interp->gc;
17641771

1772+
if (PySys_Audit("gc.get_objects", "n", generation) < 0) {
1773+
return NULL;
1774+
}
1775+
17651776
result = PyList_New(0);
17661777
if (result == NULL) {
17671778
return NULL;

0 commit comments

Comments
 (0)