Bug report
Bug description:
In the non-free-threaded code path, SampleProfiler passes only_active_thread=bool(all_threads) to RemoteUnwinder, which inverts the intended semantics.
all_threads=True should disable the restriction (i.e. only_active_thread=False), and all_threads=False should restrict sampling to the active thread (only_active_thread=True).
A minimal repro script that prints the kwargs passed to RemoteUnwinder shows the inversion on Windows and other non-free-threaded builds.
Minimal Repro
import profiling.sampling.sample as sp
class FakeRemoteUnwinder:
def __init__(self, pid, **kw):
for k in sorted(kw):
print(f" {k}={kw[k]!r}")
def run(all_threads: bool):
old_ru = sp._remote_debugging.RemoteUnwinder
old_ft = sp._FREE_THREADED_BUILD
sp._remote_debugging.RemoteUnwinder = FakeRemoteUnwinder
sp._FREE_THREADED_BUILD = False # force only_active_thread code path
try:
print(f"\n=== SampleProfiler(all_threads={all_threads}) ===")
sp.SampleProfiler(pid=123, sample_interval_usec=1000, all_threads=all_threads)
finally:
sp._remote_debugging.RemoteUnwinder = old_ru
sp._FREE_THREADED_BUILD = old_ft
if __name__ == "__main__":
print("Expected:")
print(" all_threads=False -> only_active_thread=True")
print(" all_threads=True -> only_active_thread=False")
run(False)
run(True)
Confusing result
d:\MyCode\cpython\PCbuild\amd64>python_d.exe py_thread.py
Expected:
all_threads=False -> only_active_thread=True
all_threads=True -> only_active_thread=False
=== SampleProfiler(all_threads=False) === <-------- !!! pay attention
cache_frames=True
gc=True
mode=0
native=False
only_active_thread=False <-------- !!! pay attention
opcodes=False
skip_non_matching_threads=True
stats=False
=== SampleProfiler(all_threads=True) === <-------- !!! pay attention
cache_frames=True
gc=True
mode=0
native=False
only_active_thread=True <-------- !!! pay attention
opcodes=False
skip_non_matching_threads=True
stats=False
CPython versions tested on:
CPython main branch
Operating systems tested on:
Windows
Linked PRs
Bug report
Bug description:
In the non-free-threaded code path, SampleProfiler passes
only_active_thread=bool(all_threads)to RemoteUnwinder, which inverts the intended semantics.all_threads=Trueshould disable the restriction (i.e.only_active_thread=False), andall_threads=Falseshould restrict sampling to the active thread (only_active_thread=True).A minimal repro script that prints the kwargs passed to RemoteUnwinder shows the inversion on Windows and other non-free-threaded builds.
Minimal Repro
Confusing result
CPython versions tested on:
CPython main branch
Operating systems tested on:
Windows
Linked PRs