diff options
author | Victor Stinner <vstinner@python.org> | 2025-01-23 12:07:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-23 12:07:34 +0100 |
commit | 46c7e13c055c218e18b0424efc60965e6a5fe6ea (patch) | |
tree | 1233606a473a8c9b5c6d0bf2b6d80b10c784e12c /Lib/test/test_tracemalloc.py | |
parent | 225296cd5b505c180d3f45c355b43d7e1d99d3d5 (diff) | |
download | cpython-46c7e13c055c218e18b0424efc60965e6a5fe6ea.tar.gz cpython-46c7e13c055c218e18b0424efc60965e6a5fe6ea.zip |
gh-129185: Fix PyTraceMalloc_Untrack() at Python exit (#129191)
Support calling PyTraceMalloc_Track() and PyTraceMalloc_Untrack()
during late Python finalization.
* Call _PyTraceMalloc_Fini() later in Python finalization.
* Test also PyTraceMalloc_Untrack() without the GIL
* PyTraceMalloc_Untrack() now gets the GIL.
* Test also PyTraceMalloc_Untrack() in test_tracemalloc_track_race().
Diffstat (limited to 'Lib/test/test_tracemalloc.py')
-rw-r--r-- | Lib/test/test_tracemalloc.py | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index 238ae14b388..0220a83d24b 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -1,6 +1,7 @@ import contextlib import os import sys +import textwrap import tracemalloc import unittest from unittest.mock import patch @@ -19,6 +20,7 @@ except ImportError: _testinternalcapi = None +DEFAULT_DOMAIN = 0 EMPTY_STRING_SIZE = sys.getsizeof(b'') INVALID_NFRAME = (-1, 2**30) @@ -1027,8 +1029,8 @@ class TestCAPI(unittest.TestCase): release_gil) return frames - def untrack(self): - _testcapi.tracemalloc_untrack(self.domain, self.ptr) + def untrack(self, release_gil=False): + _testcapi.tracemalloc_untrack(self.domain, self.ptr, release_gil) def get_traced_memory(self): # Get the traced size in the domain @@ -1070,7 +1072,7 @@ class TestCAPI(unittest.TestCase): self.assertEqual(self.get_traceback(), tracemalloc.Traceback(frames)) - def test_untrack(self): + def check_untrack(self, release_gil): tracemalloc.start() self.track() @@ -1078,13 +1080,19 @@ class TestCAPI(unittest.TestCase): self.assertEqual(self.get_traced_memory(), self.size) # untrack must remove the trace - self.untrack() + self.untrack(release_gil) self.assertIsNone(self.get_traceback()) self.assertEqual(self.get_traced_memory(), 0) # calling _PyTraceMalloc_Untrack() multiple times must not crash - self.untrack() - self.untrack() + self.untrack(release_gil) + self.untrack(release_gil) + + def test_untrack(self): + self.check_untrack(False) + + def test_untrack_without_gil(self): + self.check_untrack(True) def test_stop_track(self): tracemalloc.start() @@ -1110,6 +1118,29 @@ class TestCAPI(unittest.TestCase): # gh-128679: Test fix for tracemalloc.stop() race condition _testcapi.tracemalloc_track_race() + def test_late_untrack(self): + code = textwrap.dedent(f""" + from test import support + import tracemalloc + import _testcapi + + class Tracked: + def __init__(self, domain, size): + self.domain = domain + self.ptr = id(self) + self.size = size + _testcapi.tracemalloc_track(self.domain, self.ptr, self.size) + + def __del__(self, untrack=_testcapi.tracemalloc_untrack): + untrack(self.domain, self.ptr, 1) + + domain = {DEFAULT_DOMAIN} + tracemalloc.start() + obj = Tracked(domain, 1024 * 1024) + support.late_deletion(obj) + """) + assert_python_ok("-c", code) + if __name__ == "__main__": unittest.main() |