diff options
author | Victor Stinner <vstinner@python.org> | 2023-09-18 14:59:09 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-18 14:59:09 (GMT) |
commit | 0bb0d88e2d4e300946e399e088e2ff60de2ccf8c (patch) | |
tree | e197a96bdf8c45937a2f839fd723a9bb58270c47 /Lib/test/test_capi/test_misc.py | |
parent | ef659b96169888e52b6ff03ce28fffaaa8f76818 (diff) | |
download | cpython-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.py | 36 |
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 |