Skip to content

Commit 1d8afbb

Browse files
committed
gh-158574: Stabilize TLBC cache refresh tests
1 parent 9d22a53 commit 1d8afbb

1 file changed

Lines changed: 53 additions & 15 deletions

File tree

‎Lib/test/test_external_inspection.py‎

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2336,21 +2336,39 @@ def get_trace_with_opcodes(pid):
23362336
def test_tlbc_cache_refresh_after_growth(self):
23372337
# Reproducer from gh-157660.
23382338
script = textwrap.dedent("""\
2339-
import os, threading
2339+
import os, sys, threading
23402340
from _remote_debugging import RemoteUnwinder
23412341
from test import support
23422342
2343-
go = threading.Event()
2344-
stop = threading.Event()
2343+
go = threading.Lock()
2344+
stop = threading.Lock()
2345+
go.acquire()
2346+
stop.acquire()
23452347
23462348
def leaf():
2347-
stop.wait()
2349+
stop.acquire()
23482350
23492351
def wait_for_leaf_frames(u, expected_count):
23502352
for _ in support.sleeping_retry(
23512353
support.SHORT_TIMEOUT,
23522354
f"Expected {expected_count} leaf frames",
23532355
):
2356+
# Wait until the workers have entered their native lock
2357+
# calls, so sampling cannot race with Python frame changes.
2358+
frames = sys._current_frames()
2359+
frames.pop(threading.get_ident())
2360+
if len(frames) != 18:
2361+
continue
2362+
leaves = [f for f in frames.values()
2363+
if f.f_code is leaf.__code__]
2364+
if (len(leaves) != expected_count or
2365+
any(f.f_lineno != leaf.__code__.co_firstlineno + 1
2366+
for f in leaves)):
2367+
continue
2368+
if any(f.f_code not in (leaf.__code__, start_leaf.__code__,
2369+
threading.Thread.run.__code__)
2370+
for f in frames.values()):
2371+
continue
23542372
try:
23552373
traces = u.get_stack_trace()
23562374
except RuntimeError as exc:
@@ -2367,12 +2385,13 @@ def wait_for_leaf_frames(u, expected_count):
23672385
23682386
threading.Thread(target=leaf, daemon=True).start()
23692387
for _ in range(16):
2370-
threading.Thread(target=stop.wait, daemon=True).start()
2371-
threading.Thread(target=lambda: (go.wait(), leaf()), daemon=True).start()
2388+
threading.Thread(target=stop.acquire, daemon=True).start()
2389+
start_leaf = lambda: (go.acquire(), leaf())
2390+
threading.Thread(target=start_leaf, daemon=True).start()
23722391
23732392
u = RemoteUnwinder(os.getpid(), all_threads=True, cache_frames=False)
23742393
wait_for_leaf_frames(u, 1)
2375-
go.set()
2394+
go.release()
23762395
wait_for_leaf_frames(u, 2)
23772396
""")
23782397
result = subprocess.run(
@@ -2395,14 +2414,16 @@ def wait_for_leaf_frames(u, expected_count):
23952414
def test_tlbc_cache_refresh_after_slot_fill(self):
23962415
# Reproducer from gh-157660.
23972416
script = textwrap.dedent("""\
2398-
import os, threading
2417+
import os, sys, threading
23992418
from _remote_debugging import RemoteUnwinder
24002419
2401-
go = threading.Event()
2402-
stop = threading.Event()
2420+
go = threading.Lock()
2421+
stop = threading.Lock()
2422+
go.acquire()
2423+
stop.acquire()
24032424
24042425
def leaf():
2405-
stop.wait()
2426+
stop.acquire()
24062427
24072428
from test import support
24082429
@@ -2411,6 +2432,22 @@ def lines(u, expected_count):
24112432
support.SHORT_TIMEOUT,
24122433
f"Expected {expected_count} leaf frames",
24132434
):
2435+
# Wait until the workers have entered their native lock
2436+
# calls, so sampling cannot race with Python frame changes.
2437+
frames = sys._current_frames()
2438+
frames.pop(threading.get_ident())
2439+
if len(frames) != 2:
2440+
continue
2441+
leaves = [f for f in frames.values()
2442+
if f.f_code is leaf.__code__]
2443+
if (len(leaves) != expected_count or
2444+
any(f.f_lineno != leaf.__code__.co_firstlineno + 1
2445+
for f in leaves)):
2446+
continue
2447+
if any(f.f_code not in (leaf.__code__, start_leaf.__code__,
2448+
threading.Thread.run.__code__)
2449+
for f in frames.values()):
2450+
continue
24142451
try:
24152452
traces = u.get_stack_trace()
24162453
except RuntimeError as exc:
@@ -2429,13 +2466,14 @@ def lines(u, expected_count):
24292466
return result
24302467
24312468
threading.Thread(target=leaf, daemon=True).start()
2432-
threading.Thread(target=lambda: (go.wait(), leaf()), daemon=True).start()
2469+
start_leaf = lambda: (go.acquire(), leaf())
2470+
threading.Thread(target=start_leaf, daemon=True).start()
24332471
u = RemoteUnwinder(os.getpid(), all_threads=True, cache_frames=False)
24342472
before = lines(u, 1)
2435-
assert before == [8], before
2436-
go.set()
2473+
assert before == [10], before
2474+
go.release()
24372475
cached = lines(u, 2)
2438-
assert cached == [8, 8], cached
2476+
assert cached == [10, 10], cached
24392477
""")
24402478
result = subprocess.run(
24412479
[sys.executable, "-X", "gil=0", "-X", "tlbc=1", "-c", script],

0 commit comments

Comments
 (0)