Skip to content

Commit ba60c58

Browse files
committed
gh-160986: Sample popped frames only after leaf() is running
test_popping_python_frame_is_not_native attached as soon as the child process could be read, then took a fixed 10,000 samples. On a slow startup those samples all landed before leaf(), so the test observed zero frames.
1 parent 4a9b981 commit ba60c58

2 files changed

Lines changed: 26 additions & 6 deletions

File tree

‎Lib/test/test_external_inspection.py‎

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2033,14 +2033,31 @@ def leaf(depth):
20332033
leaf(300)
20342034
"""
20352035
with _managed_subprocess([sys.executable, "-c", script]) as process:
2036-
for _ in busy_retry(SHORT_TIMEOUT):
2036+
# RemoteUnwinder can attach during interpreter startup. Wait
2037+
# until leaf() is on the stack so the sample window observes it.
2038+
unwinder = None
2039+
for _ in busy_retry(
2040+
SHORT_TIMEOUT,
2041+
"child did not reach leaf() before sampling",
2042+
):
2043+
if unwinder is None:
2044+
try:
2045+
unwinder = RemoteUnwinder(
2046+
process.pid,
2047+
native=True,
2048+
gc=False,
2049+
cache_frames=False,
2050+
)
2051+
except RuntimeError:
2052+
continue
20372053
try:
2038-
unwinder = RemoteUnwinder(
2039-
process.pid, native=True, gc=False, cache_frames=False,
2040-
)
2041-
except RuntimeError:
2054+
threads = unwinder.get_stack_trace()[0].threads
2055+
except TRANSIENT_ERRORS:
20422056
continue
2043-
break
2057+
if threads and any(
2058+
frame.funcname == "leaf" for frame in threads[0].frame_info
2059+
):
2060+
break
20442061
samples = 0
20452062
for _ in range(10_000):
20462063
try:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a race in ``test_external_inspection`` where
2+
``test_popping_python_frame_is_not_native`` could spend its whole sample
3+
window during interpreter startup, before the child reached ``leaf()``.

0 commit comments

Comments
 (0)