Skip to content

Commit 61bb57f

Browse files
[3.15] gh-152434: Block --async-aware with --binary (GH-152444) (#152446)
gh-152434: Block --async-aware with --binary (GH-152444) The binary writer does not currently handle AwaitedInfo samples and crashes when running in --async-aware mode. (cherry picked from commit 876c06c) Co-authored-by: László Kiss Kollár <kiss.kollar.laszlo@gmail.com>
1 parent e88d416 commit 61bb57f

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

Lib/profiling/sampling/cli.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -875,13 +875,15 @@ def _validate_args(args, parser):
875875
if hasattr(args, 'live') and args.live:
876876
parser.error("--subprocesses is incompatible with --live mode.")
877877

878-
# Async-aware mode is incompatible with --native, --no-gc, --mode, and --all-threads
878+
# Async-aware mode is incompatible with options that need thread data.
879879
if getattr(args, 'async_aware', False):
880880
issues = []
881881
if getattr(args, 'native', False):
882882
issues.append("--native")
883883
if not getattr(args, 'gc', True):
884884
issues.append("--no-gc")
885+
if getattr(args, 'format', None) == "binary":
886+
issues.append("--binary")
885887
if hasattr(args, 'mode') and args.mode != "wall":
886888
issues.append(f"--mode={args.mode}")
887889
if hasattr(args, 'all_threads') and args.all_threads:

Lib/test/test_profiling/test_sampling_profiler/test_cli.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,23 @@ def test_async_aware_incompatible_with_all_threads(self):
866866
self.assertIn("--all-threads", error_msg)
867867
self.assertIn("incompatible with --async-aware", error_msg)
868868

869+
def test_async_aware_incompatible_with_binary(self):
870+
"""Test --async-aware is incompatible with --binary."""
871+
test_args = ["profiling.sampling.cli", "attach", "12345",
872+
"--async-aware", "--binary"]
873+
874+
with (
875+
mock.patch("sys.argv", test_args),
876+
mock.patch("sys.stderr", io.StringIO()) as mock_stderr,
877+
self.assertRaises(SystemExit) as cm,
878+
):
879+
main()
880+
881+
self.assertEqual(cm.exception.code, 2) # argparse error
882+
error_msg = mock_stderr.getvalue()
883+
self.assertIn("--binary", error_msg)
884+
self.assertIn("incompatible with --async-aware", error_msg)
885+
869886
@unittest.skipIf(is_emscripten, "subprocess not available")
870887
def test_run_nonexistent_script_exits_cleanly(self):
871888
"""Test that running a non-existent script exits with a clean error."""

0 commit comments

Comments
 (0)