summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_capi/test_misc.py
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2023-09-18 14:59:09 (GMT)
committerGitHub <noreply@github.com>2023-09-18 14:59:09 (GMT)
commit0bb0d88e2d4e300946e399e088e2ff60de2ccf8c (patch)
treee197a96bdf8c45937a2f839fd723a9bb58270c47 /Lib/test/test_capi/test_misc.py
parentef659b96169888e52b6ff03ce28fffaaa8f76818 (diff)
downloadcpython-0bb0d88e2d4e300946e399e088e2ff60de2ccf8c.zip
cpython-0bb0d88e2d4e300946e399e088e2ff60de2ccf8c.tar.gz
cpython-0bb0d88e2d4e300946e399e088e2ff60de2ccf8c.tar.bz2
gh-109496: Detect Py_DECREF() after dealloc in debug mode (#109539)
On a Python built in debug mode, Py_DECREF() now calls _Py_NegativeRefcount() if the object is a dangling pointer to deallocated memory: memory filled with 0xDD "dead byte" by the debug hook on memory allocators. The fix is to check the reference count *before* checking for _Py_IsImmortal(). Add test_decref_freed_object() to test_capi.test_misc.
Diffstat (limited to 'Lib/test/test_capi/test_misc.py')
-rw-r--r--Lib/test/test_capi/test_misc.py36
1 files changed, 26 insertions, 10 deletions
diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py
index c9cc76a..57edacb 100644
--- a/Lib/test/test_capi/test_misc.py
+++ b/Lib/test/test_capi/test_misc.py
@@ -301,24 +301,40 @@ class CAPITest(unittest.TestCase):
def test_buildvalue_N(self):
_testcapi.test_buildvalue_N()
- @unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'),
- 'need _testcapi.negative_refcount')
- def test_negative_refcount(self):
+ def check_negative_refcount(self, code):
# bpo-35059: Check that Py_DECREF() reports the correct filename
# when calling _Py_NegativeRefcount() to abort Python.
- code = textwrap.dedent("""
- import _testcapi
- from test import support
-
- with support.SuppressCrashReport():
- _testcapi.negative_refcount()
- """)
+ code = textwrap.dedent(code)
rc, out, err = assert_python_failure('-c', code)
self.assertRegex(err,
br'_testcapimodule\.c:[0-9]+: '
br'_Py_NegativeRefcount: Assertion failed: '
br'object has negative ref count')
+ @unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'),
+ 'need _testcapi.negative_refcount()')
+ def test_negative_refcount(self):
+ code = """
+ import _testcapi
+ from test import support
+
+ with support.SuppressCrashReport():
+ _testcapi.negative_refcount()
+ """
+ self.check_negative_refcount(code)
+
+ @unittest.skipUnless(hasattr(_testcapi, 'decref_freed_object'),
+ 'need _testcapi.decref_freed_object()')
+ def test_decref_freed_object(self):
+ code = """
+ import _testcapi
+ from test import support
+
+ with support.SuppressCrashReport():
+ _testcapi.decref_freed_object()
+ """
+ self.check_negative_refcount(code)
+
def test_trashcan_subclass(self):
# bpo-35983: Check that the trashcan mechanism for "list" is NOT
# activated when its tp_dealloc is being called by a subclass