@@ -4070,93 +4070,6 @@ def test_get_stats_disabled_raises(self):
40704070 client_socket .sendall (b"done" )
40714071
40724072
4073- @requires_remote_subprocess_debugging ()
4074- @skip_if_not_supported
4075- @unittest .skipIf (
4076- sys .platform == "linux" and not PROCESS_VM_READV_SUPPORTED ,
4077- "Test only runs on Linux with process_vm_readv support" ,
4078- )
4079- class TestMetadataDegradation (RemoteInspectionTestBase ):
4080- """Tests for graceful degradation of oversized code-object metadata."""
4081-
4082- def test_long_qualname_truncated_not_dropped (self ):
4083- """A qualname longer than 1024 chars is truncated instead of
4084- failing the whole sample."""
4085- name = "f" * 1100
4086- src = f"def { name } (sample):\n return sample()\n "
4087- ns = {}
4088- exec (src , ns )
4089-
4090- trace = ns [name ](RemoteUnwinder (os .getpid ()).get_stack_trace )
4091- frame = self ._find_frame_in_trace (
4092- trace , lambda f : f .funcname .startswith ("fff" )
4093- )
4094- self .assertIsNotNone (frame )
4095- self .assertEqual (frame .funcname , "f" * 1024 )
4096-
4097- def test_long_filename_truncated (self ):
4098- """A filename longer than 1024 chars is truncated instead of
4099- failing the whole sample."""
4100- src = "def g(sample):\n return sample()\n "
4101- ns = {}
4102- exec (compile (src , "x" * 1500 + ".py" , "exec" ), ns )
4103-
4104- trace = ns ["g" ](RemoteUnwinder (os .getpid ()).get_stack_trace )
4105- frame = self ._find_frame_in_trace (trace , lambda f : f .funcname == "g" )
4106- self .assertIsNotNone (frame )
4107- self .assertEqual (frame .filename , "x" * 1024 )
4108-
4109- def test_oversized_linetable_degrades_to_no_location (self ):
4110- """A linetable over MAX_LINETABLE_SIZE degrades to a frame without
4111- location instead of failing the whole sample."""
4112- src = (
4113- "def big(sample):\n "
4114- + " x = 1\n " * 20_000
4115- + " return sample()\n "
4116- )
4117- ns = {}
4118- exec (compile (src , "big_linetable.py" , "exec" ), ns )
4119- big = ns ["big" ]
4120- self .assertGreater (len (big .__code__ .co_linetable ), 64 * 1024 )
4121-
4122- trace = big (RemoteUnwinder (os .getpid ()).get_stack_trace )
4123- frame = self ._find_frame_in_trace (
4124- trace , lambda f : f .funcname == "big"
4125- )
4126- self .assertIsNone (frame .location )
4127- self .assertEqual (frame .filename , "big_linetable.py" )
4128-
4129- @unittest .skipIf (
4130- sys .platform == "win32" ,
4131- "Process death maps to ProcessLookupError only on POSIX platforms" ,
4132- )
4133- def test_dead_process_raises_not_degrades (self ):
4134- """Death of the target raises ProcessLookupError instead of
4135- degrading to synthetic frames."""
4136- script_body = """\
4137- import time
4138- sock.sendall(b"ready")
4139- time.sleep(10_000)
4140- """
4141- with self ._target_process (script_body ) as (p , client_socket , make_unwinder ):
4142- _wait_for_signal (client_socket , b"ready" )
4143- unwinder = make_unwinder ()
4144- _get_stack_trace_with_retry (unwinder )
4145-
4146- p .kill ()
4147- p .wait ()
4148-
4149- for _ in busy_retry (SHORT_TIMEOUT , error = False ):
4150- try :
4151- unwinder .get_stack_trace ()
4152- except ProcessLookupError :
4153- break
4154- except RuntimeError :
4155- continue
4156- else :
4157- self .fail ("ProcessLookupError never raised for dead process" )
4158-
4159-
41604073@requires_remote_subprocess_debugging ()
41614074class TestFrameChainLimits (RemoteInspectionTestBase ):
41624075 """Frame chain walks abort instead of looping/overflowing on deep chains."""
0 commit comments