(self)
| 1387 | @unittest.skipIf(BUILD_WITH_NDEBUG, |
| 1388 | 'built with -NDEBUG') |
| 1389 | def test_refcount_errors(self): |
| 1390 | self.preclean() |
| 1391 | # Verify the "handling" of objects with broken refcounts |
| 1392 | |
| 1393 | # Skip the test if ctypes is not available |
| 1394 | import_module("ctypes") |
| 1395 | |
| 1396 | import subprocess |
| 1397 | code = textwrap.dedent(''' |
| 1398 | from test.support import gc_collect, SuppressCrashReport |
| 1399 | |
| 1400 | a = [1, 2, 3] |
| 1401 | b = [a, a] |
| 1402 | a.append(b) |
| 1403 | |
| 1404 | # Avoid coredump when Py_FatalError() calls abort() |
| 1405 | SuppressCrashReport().__enter__() |
| 1406 | |
| 1407 | # Simulate the refcount of "a" being too low (compared to the |
| 1408 | # references held on it by live data), but keeping it above zero |
| 1409 | # (to avoid deallocating it): |
| 1410 | import ctypes |
| 1411 | ctypes.pythonapi.Py_DecRef(ctypes.py_object(a)) |
| 1412 | del a |
| 1413 | del b |
| 1414 | |
| 1415 | # The garbage collector should now have a fatal error |
| 1416 | # when it reaches the broken object |
| 1417 | gc_collect() |
| 1418 | ''') |
| 1419 | p = subprocess.Popen([sys.executable, "-c", code], |
| 1420 | stdout=subprocess.PIPE, |
| 1421 | stderr=subprocess.PIPE) |
| 1422 | stdout, stderr = p.communicate() |
| 1423 | p.stdout.close() |
| 1424 | p.stderr.close() |
| 1425 | # Verify that stderr has a useful error message: |
| 1426 | self.assertRegex(stderr, |
| 1427 | br'gc.*\.c:[0-9]+: .*: Assertion "gc_get_refs\(.+\) .*" failed.') |
| 1428 | self.assertRegex(stderr, |
| 1429 | br'refcount is too small') |
| 1430 | # "address : 0x7fb5062efc18" |
| 1431 | # "address : 7FB5062EFC18" |
| 1432 | address_regex = br'[0-9a-fA-Fx]+' |
| 1433 | self.assertRegex(stderr, |
| 1434 | br'object address : ' + address_regex) |
| 1435 | self.assertRegex(stderr, |
| 1436 | br'object refcount : 1') |
| 1437 | self.assertRegex(stderr, |
| 1438 | br'object type : ' + address_regex) |
| 1439 | self.assertRegex(stderr, |
| 1440 | br'object type name: list') |
| 1441 | self.assertRegex(stderr, |
| 1442 | br'object repr : \[1, 2, 3, \[\[...\], \[...\]\]\]') |
| 1443 | |
| 1444 | |
| 1445 | class GCTogglingTests(unittest.TestCase): |
nothing calls this directly
no test coverage detected