403Webshell
Server IP : 121.121.20.254  /  Your IP : 216.73.216.146
Web Server : Microsoft-IIS/10.0
System : Windows NT WEB-SERVER 10.0 build 20348 (Windows Server 2022) AMD64
User : IUSR ( 0)
PHP Version : 8.3.28
Disable Function : NONE
MySQL : ON  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  C:/Python315/Lib/test/__pycache__/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : C:/Python315/Lib/test/__pycache__/test_external_inspection.cpython-315.opt-1.pyc
R
>lqjOBc��]PHs]PHs]PHs]PHs]PHs]PHs]PHs]PHs]PH s]QHG	s	]QH(GsGsG
s
Gs]QH<Gs]QHDGsGsGsGsGs]QH\Gs]QHdGs]QHlGs]PHts]s]s]s ]s!]s"]s#]s$]s%]s&]
s'Qs(\)\*\+1s,]Q	H�G.s.P
s0]Q
H�G0s0]QH�G2s2]QH�G3s3G4s4G5s5Qs7Q,Qks8\1Qks9\1Qks:\	\1Qk2s;Qs<\Oz\O|Q6g9%c'\O|Q6g9%c\O|Q6gQ2s?Qs@QsAQsBQsC\P1QksDQQ\O�2sF\2QQ \F22sG\2Q!Q"\F22sHQ#Q$\O�2sI\2Q%Q&\F22sJ\2Q'Q(\F22sK\2Q)Q*\F22sL\MQ+6Xc\O�2P!P!\/cPs.CKWh9h\/c\OlQ
2gh9h)-�)�contextmanager)�	staggered�
taskgroups�base_events�tasks)�ANY)�	os_helper�
SHORT_TIMEOUT�
busy_retry�requires_gil_enabled�$requires_remote_subprocess_debugging)�
import_module)�make_script)�find_unused_portg�������?)�interpreters)�PROCESS_VM_READV_SUPPORTED)�RemoteUnwinder)�	FrameInfo�CoroInfo�TaskInfoz2Test only runs when _remote_debugging is availablec�J�[VU2o[O2U!�N)r�	importlib�invalidate_caches)�
script_dir�script_basename�source�	to_returns&&& �2C:\Python315\\Lib\test\test_external_inspection.py�_make_test_scriptrDs ���J��@�I�
���!���c�>�[O[O[O2oUO[O[O
]2UO
QU12UO[2UOU2U!)z<Create and configure a server socket for test communication.�	localhost)
�socket�AF_INET�SOCK_STREAM�
setsockopt�
SOL_SOCKET�SO_REUSEADDR�bind�
settimeoutr	�listen)�port�backlog�
server_sockets&& r�_create_server_socketr/Jso���M�M�&�.�.�&�2D�2D�E�M����V�.�.��0C�0C�Q�G�����T�*�+����]�+�����!��r c	�`�[U[2%cU,oUOU2Qn[9PIcU1QkU2D%cJP
L	P	LU1QkU22%cR!UO	Q2oU%f[QUQRQP802gRU*
nJ|[Oc[QSQRQP802gh9h)a�
Wait for expected signal(s) from a socket with proper timeout and EOF handling.

Args:
    sock: Connected socket to read from
    expected_signals: Single bytes object or list of bytes objects to wait for
    timeout: Socket timeout in seconds

Returns:
    bytes: Complete accumulated response buffer

Raises:
    RuntimeError: If connection closed before signal received or timeout
r c3�8:�SF �D
pR7w�	J	P!3hr�)�.0�sig�buffers& �r�	<genexpr>�#_wait_for_signal.<locals>.<genexpr>ks��(8���(8��f�}�(8�s��z?Connection closed before receiving expected signals. Expected: z, Got: z'Timeout waiting for signals. Expected: �8���)�
isinstance�bytesr*�all�recv�RuntimeErrorr#�timeout)�sock�expected_signalsr?�chunkr5s&&& @r�_wait_for_signalrCTs�����"�E�*�*�,�-���O�O�G��
�F�
��3�9�(8�9�3�3�3�9�(8�9�9�9��M�
	��I�I�d�O�E��"�!�!1� 2�'�&���-�9J�L���
�e�O�F���~�~�	���-�.�g�f�T�U�m�5F�H��
�	�s�2B+�B+�+C�?Cc�:�UOU2Qo]oVR6cNUOQ2oU%f[QUQUQUQ	P802gVF*
oUOU2oJSU![O
c[QSQSQSQ	P802gh9h)
a{
Wait for N occurrences of a signal pattern.

Args:
    sock: Connected socket to read from
    signal_pattern: bytes pattern to count (e.g., b"ready")
    count: Number of occurrences expected
    timeout: Socket timeout in seconds

Returns:
    bytes: Complete accumulated response buffer

Raises:
    RuntimeError: If connection closed or timeout before receiving all signals
r r8zConnection closed after �/z signals. Last 200 bytes: zTimeout waiting for z signals (found z). Last 200 bytes: r9)r*r=r>�countr#r?)r@�signal_patternrFr?r5�found_countrBs&&&&   r�_wait_for_n_signalsrI~s��� 	�O�O�G��
�F��K�
�
�	��I�I�d�O�E��"�.�{�m�1�U�G�D'�'-�d�e�}�&7�9���
�O�F� �,�,�~�6�K��M��
�~�~�	��&�u�g�-=�k�]�K#�#)�$�%�=�"3�5��
�	�s�A,�1A,�,B�Bc#� �[OU2oUw�UO2UOUQ5P![OcESO2SOSQ5P![OcP!h9hh9h[cP!h9hSO2SOSQ5h[OcCSO2SOSQ5h[Ochh9hh9h[chh9h9h3h)z�
Context manager for subprocess lifecycle management.

Ensures process is properly terminated and cleaned up even on exceptions.
Uses graceful termination first, then forceful kill if needed.
�r?)�
subprocess�Popen�	terminate�wait�TimeoutExpired�kill�OSError)�argsr?�ps&& r�_managed_subprocessrU�s���	�����A����	�
�K�K�M�
����w��'���,�,�
�������F�F�7�F�+��!�0�0�����	
���	��	��	�
�K�K�M�
����w��'���,�,�
�������F�F�7�F�+��!�0�0�����	
���	��	�s�E�B4�B"�A�E�B�B�,B�>B"�?E�B�B�B�B"�E�B�B�B"�"	B1�,B1�-E�0B1�1E�4E�6D4�C�E�D1�.D1�D�D4�E�D-	�(D-	�)D1�*D4�+E�,D-	�-D1�1D4�4	E�>E�?E�E�E�Ec�n�SFDoUeJ	UO2J	P![cJ.h9h)z/Safely close multiple sockets, ignoring errors.)�closerR)�socketsr@s* r�_cleanup_socketsrY�s4������
��
�
�����
��
�s�%�	4�4�4�darwin�linux�win32z*Test only runs on Linux, Windows and MacOSc�J�[O[PIQ2U2!)z>Decorator to skip a test if subinterpreters are not supported.zsubinterpreters required)�unittest�skipIfr)�meths&r�requires_subinterpretersra�s#���?�?�<�4�/�1K�L���r c��[[2FD#o[UP	P	Q5oUO2t!	[	Q2g[coPo=JCPo=hh9h)T)�all_threads�debugz'Failed to get stack trace after retries)r
r	r�get_stack_tracer>��pid�_�unwinder�es&   rrere�sV��
�
�
&��	�%�c�t�4�H�H��+�+�-�-�'��@�
A�A���	���	�s�A�	A�A�Ac��[[2FD"o[UP	Q5oUO2t!	[	Q2g[coPo=JBPo=hh9h)T�rdz-Failed to get async stack trace after retries)r
r	r�get_async_stack_tracer>rfs&   rrmrm�sT��
�
�
&��	�%�c��6�H��1�1�3�3�'��F�
G�G���	���	���A�	A�
A�Ac��[[2FD"o[UP	Q5oUO2t!	[	Q2g[coPo=JBPo=hh9h)Trlz*Failed to get all awaited_by after retries)r
r	r�get_all_awaited_byr>rfs&   rrprp�sT��
�
�
&��	�%�c��6�H��.�.�0�0�'��C�
D�D���	���	�rnc��Po[U2FD+oUO2oUdUU2%cUt!J-	U%c[QU02g[Q2g[coSoPo=JcPo=hh9h)apGet stack trace from an existing unwinder with retry for transient errors.

This handles the case where we want to reuse an existing RemoteUnwinder
instance but still handle transient failures like "Failed to parse initial
frame in chain" that can occur when sampling at an inopportune moment.
If condition is provided, keeps retrying until condition(traces) is True.
z)Failed to get stack trace after retries: z(Condition never satisfied within timeout)r
re�TRANSIENT_ERRORSr>)rir?�	condition�
last_errorrh�tracesrjs&&&    r�_get_stack_trace_with_retryrvs����J�
��
 ��	��-�-�/�F�� �I�f�$5�$5��
�%6�!���7�
�|�D�
�	
��A�
B�B�� �	��J���	�s'�A �
A �A � 	A8�*A8�+A3�3A8c�t`�\sQsQsnQsPsQQksQsQsQs	Qs
QsQ	sQ
s
\Q2sQsQ
sUsP!)�RemoteInspectionTestBase�z;Base class for remote inspection tests with common helpers.c	��Ue[2oQU7fQU7c#UOQQ2OUQ5o[O29^tt^2o[
OOUQ2o[
OU2[VE2o[UQU2o	Po
[[OU	,29^tt^2oUO2vq�UO2PoU%c[!V�2UUO"2o
V�1ttPPP2[%V�2ttPPP2!)%fhL9h[%X�2L[%X�2h9hPPP2P!)%fhP!9h)a�
Common pattern: run a script, wait for signals, get trace.

Args:
    script: Script content (will be formatted with port if {port} present)
    trace_func: Function to call with pid to get trace (e.g., get_stack_trace)
    wait_for_signals: Signal(s) to wait for before getting trace
    port: Port to use (auto-selected if None)
    backlog: Socket listen backlog

Returns:
    tuple: (trace_result, script_name)
z{port}z{{port}})r,�
script_pkg�script)r�replace�formatr�temp_dir�os�path�join�mkdirr/rrU�sys�
executable�acceptrWrCrgrY)�selfr|�
trace_func�wait_for_signalsr,r-�work_dirrr.�script_name�
client_socketrTrh�traces&&&&&&        r�_run_script_and_get_trace�2RemoteInspectionTestBase._run_script_and_get_trace$s8��*�<�#�%�D��v���v�!5��^�^�J��9�@�@�d�@�K�F�
�
�
�
!�
!�X������h��=�J��H�H�Z� �1�$�@�M�+�J��&�I�K� �M�
?�(�#�.�.�+�)F�G�G�1�'4�';�';�'=�$�M�!�'�'�)�$(�M�'�(��I�&�q�u�u�-�E� �-�H�G�!��>�)"�
!�H�G��G�!��>�� ��>��>�)"�
!�
!�
!�sU�AE9�/#E�,D>	�?D>	�
E�(E9�>E
�E
�	E�E9�
E+�+E9�9F
	�F
	c	��SFDDoUOFD0oUOFDoUU2%fJUttt!	J2	JF	P!)z�
Find a frame matching predicate in stack trace.

Args:
    stack_trace: List of InterpreterInfo objects
    predicate: Function(frame) -> bool

Returns:
    FrameInfo or None
��threads�
frame_info)r��stack_trace�	predicate�interpreter_info�thread_info�frames&&&   r�_find_frame_in_trace�-RemoteInspectionTestBase._find_frame_in_traceVsF��!,��/�7�7��(�3�3�E� ��'�'�$���4� 8�!,�
r c�v�SFD0oUOFDoUOU6XfJUtt!	J2	P!)z&Find a thread by its native thread ID.)r��	thread_id)r�r�r�r�r�s&&&  r�_find_thread_by_id�+RemoteInspectionTestBase._find_thread_by_idhs6�� +��/�7�7���(�(�I�5�&�&� 8�!,�r c	��SFDDoUOFD0oUOFDoUU2%fJUttt!	J2	JF	P!)z4Find a thread containing a frame matching predicate.r�)r�r��frame_predicater�r�r�s&&&   r�_find_thread_with_frame�0RemoteInspectionTestBase._find_thread_with_framepsF�� +��/�7�7��(�3�3�E�&�u�-�-�*�*�*�4� 8�!,�
r c�x�-oSFD/oUOFDoUOV$O$J	J1	U!)z5Extract thread_id -> status mapping from stack trace.)r��statusr�)r�r��statusesr�r�s&&   r�_get_thread_statuses�-RemoteInspectionTestBase._get_thread_statusesys=���� +��/�7�7��2=�2D�2D��.�.�/� 8�!,��r c�j�U]*OTt-tFDp"OUaJ	to!ttoh)z6Create task_id -> task mapping from async stack trace.)�
awaited_by�task_id�r�r��tasks&& r�_get_task_id_map�)RemoteInspectionTestBase._get_task_id_map�s-��/:�1�~�/H�/H�I�/H�t���d�"�/H�I�I��Is�0c	�`�UOU2nU]*OTt-tFDRoUO[9PIc .U1QkUO2DjJ	LU1QkUO22aJT	to!ttoh)z,Extract task name to awaited_by set mapping.c3�j:�SF �D#oRUO*Ow�	J%	P!3hr)�	task_name)r3�awaited�
id_to_tasks& �rr6�IRemoteInspectionTestBase._get_awaited_by_relationships.<locals>.<genexpr>�s'��.���.�G��7�,�,�-�7�7�.�s�+3)r�r�r��set)r�r�r�r�s&& @r�_get_awaited_by_relationships�6RemoteInspectionTestBase._get_awaited_by_relationships�s�����*�*�;�7�
�$�A��1�1�
�
2��	
�N�N�C�C� �#��� �C�C� �#��� ��
�2�
�	
��
s�B�=Bc	��U]*OTt-tFD)oUO[QUO22aJ+	to!ttoh)z/Extract and format coroutine stacks from tasks.c3��SF �DEo[9PIc,QUO2DMJ	3LQUO22w�	JG	P!3h)c3�D�SF �Do[U2w�	J	P!3hr)�tuple)r3r�s& rr6�ORemoteInspectionTestBase._extract_coroutine_stacks.<locals>.<genexpr>.<genexpr>�s������u�e�E�l�l��s� �r��
call_stack)r3�coros& rr6�ERemoteInspectionTestBase._extract_coroutine_stacks.<locals>.<genexpr>�s:��0���0�D���@����@���@����@�@�@�0�s
�A�=A�r�r��sorted�coroutine_stackr�s&& r�_extract_coroutine_stacks�2RemoteInspectionTestBase._extract_coroutine_stacks�sZ��$�A��1�1�
�
2��	
�N�N�F�#� �0�0�#��
�2�
�	
��
s�1A
c�*�Uvqq4VOV41!)aConvert frame to (filename, lineno, funcname, opcode) tuple.

This extracts just the line number from the location, ignoring column
offsets which can vary due to sampling timing (e.g., when two statements
are on the same line, the sample might catch either one).
)�lineno)r��filename�location�funcname�opcodes&    r�_frame_to_lineno_tuple�/RemoteInspectionTestBase._frame_to_lineno_tuple�s��05�,��H��/�/�8�<�<r c	�`�U]*OTt-tFD,oUO[U1QkUO22aJ.	to!ttoh)z�Extract coroutine stacks with line numbers only (no column offsets).

Use this for tests where sampling timing can cause column offset
variations (e.g., 'expr1; expr2' on the same line).
c3�:�SF �DKo[9PIc!,U1QkUO2DMJ	3LU1QkUO22w�	JM	P!3h)c3�R:�SF �DoROU2w�	J	P!3hr�r��r3r�r�s& �rr6�[RemoteInspectionTestBase._extract_coroutine_stacks_lineno_only.<locals>.<genexpr>.<genexpr>�s��o���o�U�d�1�1�%�8�8�o���'r��r3r�r�s& �rr6�QRemoteInspectionTestBase._extract_coroutine_stacks_lineno_only.<locals>.<genexpr>�s:��0���0�D���V�d�o�o�V���V�d�o�o�V�V�V�0���A�AAr�r�sf& r�%_extract_coroutine_stacks_lineno_only�>RemoteInspectionTestBase._extract_coroutine_stacks_lineno_only�s[���$�A��1�1�
�
2��	
�N�N�F�#� �0�0�#��
�2�
�	
��
s�4Ar2)NN�)�__name__�
__module__�__qualname__�__firstlineno__�__doc__�maxDiffr�r�r�r�r�r�r�r��staticmethodr�r��__static_attributes__�__classdictcell__��
__classdict__s@rrxrxsU����E��G�0?�d�$���J�	
�
��=��=�
�
r rxc�`�\sQsQsn\\O\OQ6H9%c\	%(Q2Q22s
QsUsP!)�TestSelfStackTrace�r[�5Test only runs on Linux with process_vm_readv supportc��[OQ2o[O[O
QU,P	P	[Q5oUOUO]QUOQUO02P!)a�            import os
            import _remote_debugging

            assignments = "\n".join(
                f"value_{i} = {i}" for i in range(1000)
            )
            expected_lineno = len(assignments.splitlines()) + 1
            source = (
                f"{assignments}\n"
                "stack_trace = "
                "_remote_debugging.RemoteUnwinder(os.getpid()).get_stack_trace()\n"
            )
            code = compile(source, "large_linetable.py", "exec")
            assert len(code.co_linetable) > 4096, len(code.co_linetable)
            namespace = {"os": os, "_remote_debugging": _remote_debugging}
            exec(code, namespace)
            large_linetable_frames = [
                frame
                for interpreter in namespace["stack_trace"]
                for thread in interpreter.threads
                for frame in thread.frame_info
                if frame.filename == "large_linetable.py"
            ]
            assert len(large_linetable_frames) == 1, large_linetable_frames
            assert large_linetable_frames[0].location.lineno == expected_lineno, (
                large_linetable_frames[0]
            )
            �-c��capture_output�textr?�stdout: �	
stderr: )�textwrap�dedentrL�runr�r�r	�assertEqual�
returncode�stdout�stderr�r�r|�results&  r�$test_self_trace_with_large_linetable�7TestSelfStackTrace.test_self_trace_with_large_linetable�sq�����"���<���
�^�^�T�6�*���!�	
��	
������q��v�}�}�o�Z��
�
��?�	
r r2)
r�r�r�r��skip_if_not_supportedr^r_r��platformrr�r�r�r�s@rr�r��sC�����
�_�_������B�B�(B�$B�?��(
�	��
(
r r�c�`�\sQsQsn\\O\OQ6H9%c\	%(Q2Q22s
\\O\OQ6H9%c\	%(Q2Q22s\\O\OQ6H9%c\	%(Q2Q22s\\O\OQ6H9%c\	%(Q2Q22s
\\O\OQ6H9%c\	%(Q2Q22s\\O\OQ6H9%c\	%(Q2Q	22s\\O\OQ6H9%c\	%(Q2Q
22s\\O\OQ6H9%c\	%(Q2Q22s\\O\OQ6H9%c\	%(Q2Q22s\\O\OQ6H9%c\	%(Q2Q
22s\\O\OQ6H9%c\	%(Q2Q22s\\O\OQ6H9%c\	%(Q2\Q222s\\O\OQ6H9%c\	%(Q2\Q222s\\O\OQ6H9%c\	%(Q2\Q2Q222s\\O\OQ6H9%c\	%(Q2Q22s\\O\OQ6H9%c\	%(Q2Q22s\\O\OQ6H9%c\	%(Q2Q22sQsUsP!)�TestGetStackTrace��r[r�c	���[2o[OQUQ02o[O29^tt^2o[
OOUQ2o[
OU2[U2o[UQU2oPo[[OU,29^tt^2oUO2vqyUO2Po[!UQQ,2[#UO$2o
UO'U
Q2oUO)UQ2UO*Tt,tFDp�O,MJ	o
oUO/U
Q*,QN2UO1U
Q	2oUO)UQ
2PPP2[3Vu2PPP2P!ttoh)%fhK+9h[3Xu2h9h)%fhP!9h)��            import time, sys, socket, threading

            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(('localhost', a�))

            def bar():
                for x in range(100):
                    if x == 50:
                        baz()

            def baz():
                foo()

            def foo():
                sock.sendall(b"ready:thread\n"); time.sleep(10_000)

            t = threading.Thread(target=bar)
            t.start()
            sock.sendall(b"ready:main\n"); t.join()
            r{r|�
ready:mainsready:threadc�d�UOQ6H9%cUOO]6H!��foo�r�r�r���fs&r�<lambda>�;TestGetStackTrace.test_remote_stack_trace.<locals>.<lambda>#s'��!�*�*��"5�"Q�"Q�!�*�*�:K�:K�r�:Q�"Qr z%Expected thread stack trace not found:N�Nc�d�UOQ6H9%cUOO]6H!)z<module>rrs&rr
r2s(��!�*�*�
�":�"V�"V�q�z�z�?P�?P�TV�?V�"Vr z!Main thread stack trace not found)r�baz�barz
Thread.runzThread._bootstrap_innerzThread._bootstrap)rr�r�rrr�r�r�r�r/rrUr�r�r�rWrCrergr��assertIsNotNoner�r�r�r�rY)r�r,r|r�rr.r�r�rTrhr��found_threadr	�	funcnames�
found_mains&              r�test_remote_stack_trace�)TestGetStackTrace.test_remote_stack_trace�s��� �!�����(�)-�v�.
�	
�
��0�
�
�
!�
!�X������h��=�J��H�H�Z� �1�$�7�M�+�J��&�I�K� �M�$
?�(�#�.�.�+�)F�G�G�1�'4�';�';�'=�$�M�!�'�'�)�$(�M�$�%�
��'G��#2�!�%�%�"8�K�$(�#?�#?�#�Q�$�L��(�(�$�&M��6B�5L�5L� M�5L����5L�I� M��$�$�!�"�
�k��"&�!:�!:�#�V�"�J��(�(�"�$G��?H�F!��>�Y"�
!��:!N�)H�G��F!��>��Y"�
!�
!�s]�AG�#G�8A:F-	�2F(�AF-	�
G�G�(F-	�-F=
�6F=
�8G�
G
�
G�G!	�G!	c��[Q2[OQ2o[O[
OQU,P	P	[Q5oUOUO]QUOQUO02P!)aJTest that RemoteUnwinder works on the same process after _ctypes import.

When _ctypes is imported, it may call dlopen on the libpython shared
library, creating a duplicate mapping in the process address space.
The remote debugging code must skip these uninitialized duplicate
mappings and find the real PyRuntime. See gh-144563.
�_ctypesa`            import os
            import _remote_debugging

            # Should work before _ctypes import
            unwinder = _remote_debugging.RemoteUnwinder(os.getpid())

            import _ctypes

            # Should still work after _ctypes import (gh-144563)
            unwinder = _remote_debugging.RemoteUnwinder(os.getpid())
            r�r�r�r�)r
r�r�rLr�r�r�r	r�r�r�r�r�s&  r�#test_self_trace_after_ctypes_import�5TestGetStackTrace.test_self_trace_after_ctypes_import:s{��	�i� ����"������
�^�^�T�6�*���!�	
��	
������q��v�}�}�o�Z��
�
��?�	
r c�(`�QoQoQoUQUQU0nQUQUQU0o[2o[OQUQRQRQ02o[O29^tt^2o[
OOUQ	2o[
OU2[V�U2o	[U2o
Po[O[OU	,2oU
O2vq�U
O!2[#UQ
2[%UO&2oUdUO!2WO-2UO/[0Q5WTTTt,tFD-oUO2FDoUO4FDoUMJ	J	J/	oooo[7U1Q
kU2P2oSO9SQR8QSTt,tFDoUO:UO<1MJ	to02UO?UO:U	2PPP2P![(cSO+Q2CKh9hSdSO!2WO-2SO/[0Q5h9httooohttoh)%fhP!9h)u
zażółćuλάμβδαu𐌀𐌁𐌂𐌃rh�mod_z�            import socket
            import time

            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(('localhost', z))

            def z[():
                sock.sendall(b"ready")
                time.sleep(10_000)

            z()
            r{�readyz0Insufficient permissions to read the stack tracerKc3�X:�SF �DpOR6XfJUw�	J	P!3hr�r�)r3r	�	func_names& �rr6�LTestGetStackTrace.test_remote_stack_trace_non_ascii_names.<locals>.<genexpr>�s��F���F�q�j�j�I�&=���F�s�*�*z
Frame for z missing; got ) rr�r�rrr�r�r�r�rr/rLrMr�r�r�rWrCrerg�PermissionError�skipTestrQrOr	r�r��nextrr�r�r�)r��latin1�bmp�astralrr,r|r�rr�r.r�rTrhr��interp�threadr��frames�targetr	rs&                    @r�'test_remote_stack_trace_non_ascii_names�9TestGetStackTrace.test_remote_stack_trace_non_ascii_namesdss�������#���h�a��u�A�f�X�.�	� ����#��a��x�8���!�����(�
)-�v�.���
��K�
�
�
���
�
�
!�
!�X������h��=�J��H�H�Z� �+�J��P�K�1�$�7�M� �M�

.��$�$�c�n�n�k�%B�C��#0�#7�#7�#9� �
��#�#�%� ���9�-�a�e�e�4��!�,�!�'�'�)��������}��-�*��)�F�$�n�n�F�#�.�.�E��/��,��)�
���>�F�>���F�
� � ���Y�M��6<�=�f��Q�Z�Z����,�f�=�>�@�
�

���V�_�_�k�:�I"�
!��#�
R��
�
�P�Q�
R��!�,�!�'�'�)��������}��-����>�E"�
!�
!�sn�%AJ�6A)H�J�#;J�5I4�-J�#I;�#%J�	H2�H2�.H5�1H2�2H5�5I1�:7I1�1J�J	�	J	c��``�[2o[OQUQ02oQFCDdoROUQ59^tt^2[O
29^tt^2o[OOUQ2o[OU2[U2o[UQUOUQ52oPo[[OU,29^tt^2o	UO!2vq�UO#2Po[%UQ2oRO'QU2[)U	O*2oU]*O,T
t,tFDo
U
O.MJ	oo
QFDoRO'V�2J	RO1U2oRO3UQ.QlQ
[52QQ
.Q	Q
.-2RO7U2oRO3UQ
[8O:[<QP1[8O:[<QP1U]Q
P11,QU]
QP1U]QP1U]QP1U]QP11,QU]QP11,Q	U]QP11,-2RO?U2nU]*O,T
t-tFD-o
U
O.[AUU1QkU
O,22aJ/	oo
RO3UQ
,QQ
[8O:[<QP1[8O:[<QP1U]Q
P111QU]QP111Q	U]QP111,QQ
[8O:[<QP1[8O:[<QP1U]Q
P111,Q	Q
[8O:[<QP1[8O:[<QP1U]Q
P111,-2PPP2[CV�2PPP2PPP2CJg	P!tto
htto
h)%fhK=9h[CX�2h9h)%fhKL9h)%fhCJ�9h)��            import asyncio
            import time
            import sys
            import socket

            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(('localhost', a�))

            def c5():
                sock.sendall(b"ready"); time.sleep(10_000)

            async def c4():
                await asyncio.sleep(0)
                c5()

            async def c3():
                await c4()

            async def c2():
                await c3()

            async def c1(task):
                await task

            async def main():
                async with asyncio.TaskGroup() as tg:
                    task = tg.create_task(c2(), name="c2_root")
                    tg.create_task(c1(task), name="sub_main_1")
                    tg.create_task(c1(task), name="sub_main_2")

            def new_eager_loop():
                loop = asyncio.new_event_loop()
                eager_task_factory = asyncio.create_eager_task_factory(
                    asyncio.Task)
                loop.set_task_factory(eager_task_factory)
                return loop

            asyncio.run(main(), loop_factory={TASK_FACTORY})
            )�task_factory_variantr{r|)�TASK_FACTORYr�c2_root�
sub_main_1�
sub_main_2�Task-1�TaskGroup._aexit�TaskGroup.__aexit__�main�c5�c4�c3�c2�c1c3��:�SF �DhoRUO*O[9PIc!,U1QkUO2DMJ	3LU1QkUO221w�	Jj	P!3h)c3�R:�SF �DoROU2w�	J	P!3hrr�r�s& �rr6�LTestGetStackTrace.test_async_remote_stack_trace.<locals>.<genexpr>.<genexpr>=s$��5D���5D�E�)-�(C�(C�E�(J�(J�5D�r��r�r�r��r3r�r�r�s& ��rr6�BTestGetStackTrace.test_async_remote_stack_trace.<locals>.<genexpr>:s`��-<���-<�D�
%/�t�~�~�$>�$H�$H�$)�E�*&�59�_�_�*&�E�E�*&�59�_�_�*&�%&�!"�-<���+A8�AA8)zasyncio.new_event_loop�new_eager_loop)r1r2r3>r2r3r4)"rr�r��subTestrrr�r�r�r�r/rr~rUr�r�r�rWrC�assertInrmrgr�r�r�r�r�r�r�__file__rr�r�rY)r�r,r|r/r�rr.r�r�rTrh�responser�r��tasks_namesr��
relationships�coroutine_stacks�awaited_by_coroutine_stacksr�sf                  @r�test_async_remote_stack_trace�/TestGetStackTrace.test_async_remote_stack_trace�s���� �!�����(�)-�v� .
�'
�)
��V%O� ����2F��G�G��"�"�$�$���W�W�\�\�(�L�A�
�����$� 5�d� ;�
�/����M�M�/C�M�D���
!%�
�HC�,�����5����+8�+?�+?�+A�(�
�%�+�+�-�(,�
�#3�M�8�#L���
�
�h��9�&;�A�E�E�&B��
)4�A��(A�(A�'�(A��!�N�N�(A�$�'�*�I�
!�M�M�)�A�*�)-�(J�(J�'�)�
��(�(�)� )�,"�
!)�#�%� ,�x�j� ,�x�j�	��",0�+U�+U�'�,�(��(�(�,� (�)3�)<�)<�c�CU�W[�(\�)3�)<�)<�c�CX�Z^�(_�)4�b�&�$�(G�%&�+"�!*�)4�b�$��(E�)4�b�$��(E�)4�b�$��(E�)4�b�$��(E�	%&�,"�!-�&1�2�t�T�%B�$D�/"�!-�&1�2�t�T�%B�$D�/"�'��8&*�%:�%:�;�%G�
�)4�A��(A�(A�7�)B��!�N�N�F�	3�-1�O�O�	3�	-�	�)B�4�7��(�(�7� (�"� )�(0�-7�-@�-@�#�GY�[_�,`�-7�-@�-@�#�G\�^b�,c�-8�"�f�d�,K�)*�%&�)5�*5�r�4��)F�(H�%&�
)5�*5�r�4��)F�(H�%&�,"�$!-�(0�-7�-@�-@�#�GY�[_�,`�-7�-@�-@�#�G\�^b�,c�-8�"�f�d�,K�)*�%&�	/"�!-�(0�-7�-@�-@�#�GY�[_�,`�-7�-@�-@�#�G\�^b�,c�-8�"�f�d�,K�)*�%&�	/"�=(�+�u�N%�]�B�k%�H�G�%O��<'��@7�[���N%�]�B��k%�$��H�G�G�s��	O	�'A!O
�	#N3�,A,N �N�/C9N �(5N�CN �+N3�3O
�?O	�
N � N0�)N0�+N3�3
O�O
�O�O�O	�O(
�O(
c
�H`�[2o[OQUQ02o[O29^tt^2o[
OOUQ2o[
OU2[U2o[UQU2oPo[[OU,29^tt^2oUO2vqyUO2Po[!UQ2o
RO#QU
2[%UO&2oRO)[+U]*O,2]2U]*O,]*oRO)UO.Q2[1U1QkUO222o
RO)U
U]
QP1U]QP1U]Q	P11,2RO)UO,,2PPP2[5Vu2PPP2P!)%fhK&9h[5Xu2h9h)%fhP!9h)
r.a�))

            async def gen_nested_call():
                sock.sendall(b"ready"); time.sleep(10_000)

            async def gen():
                for num in range(2):
                    yield num
                    if num == 1:
                        await gen_nested_call()

            async def main():
                async for el in gen():
                    pass

            asyncio.run(main())
            r{r|rr4c3�:�SF �DKo[9PIc!,U1QkUO2DMJ	3LU1QkUO22w�	JM	P!3h)c3�R:�SF �DoROU2w�	J	P!3hrr�r�s& �rr6�OTestGetStackTrace.test_asyncgen_remote_stack_trace.<locals>.<genexpr>.<genexpr>�s��o���o�U�d�9�9�%�@�@�o�r�r�r�s& �rr6�ETestGetStackTrace.test_asyncgen_remote_stack_trace.<locals>.<genexpr>�s:��$8���$8�D���^�d�o�o�^���^�d�o�o�^�^�^�$8�r��gen_nested_call�genr7)rr�r�rrr�r�r�r�r/rrUr�r�r�rWrCrFrmrgr��lenr�r�r�r�rY)r�r,r|r�rr.r�r�rTrhrHr�r�r�sf             r� test_asyncgen_remote_stack_trace�2TestGetStackTrace.test_asyncgen_remote_stack_traceus���� �!�����(�)-�v�.
�
�
��6�
�
�
!�
!�X������h��=�J��H�H�Z� �1�$�7�M�+�J��&�I�K� �M�%
?�(�#�.�.�+�)F�G�G�1�'4�';�';�'=�$�M�!�'�'�)�$(�M�/�
�x�H�H��M�M�(�H�5�"7����">�K��$�$�S��Q��)B�)B�%C�Q�G�&�q�>�4�4�Q�7�D��$�$�T�^�^�X�>�
'-�-�$(�$8�$8�-�'�O��$�$�'�"-�b�2C�T� J�!,�b�%�� >�!,�b�&�$� ?���	��$�$�T�_�_�b�9�EH�H!��>�["�
!�H�G��H!��>��["�
!�
!�sJ�AH�#H�9DG-	�H�H�-G=
�6G=
�8H�
H
�
H�H!	�H!	c�4``�[2o[OQUQ02o[O29^tt^2o[
OOUQ2o[
OU2[U2o[UQU2oPo[[OU,29^tt^2oUO2vqyUO2Po[!UQ2o
RO#QU
2[%UO&2oU]*O(Tt,tFDp�O*MJ	o
oQFDoRO#V�2J	RO-U2oRO/UQ[12QQ.-2RO3U2oRO/UQU]QP11,QU]QP1U]Q	P11,-2RO5U2nU]*O(Tt-tFD-oUO*[7UU1Q
kUO(22aJ/	ooRO/UQ,QQU]QP111,-2PPP2[9Vu2PPP2P!ttohttoh)%fhK09h[9Xu2h9h)%fhP!9h)r.a�))

            async def deep():
                await asyncio.sleep(0)
                sock.sendall(b"ready"); time.sleep(10_000)

            async def c1():
                await asyncio.sleep(0)
                await deep()

            async def c2():
                await asyncio.sleep(0)

            async def main():
                await asyncio.gather(c1(), c2())

            asyncio.run(main())
            r{r|rr4�Task-2r7�deepr<c3��:�SF �DhoRUO*O[9PIc!,U1QkUO2DMJ	3LU1QkUO221w�	Jj	P!3h)c3�R:�SF �DoROU2w�	J	P!3hrr�r�s& �rr6�STestGetStackTrace.test_async_gather_remote_stack_trace.<locals>.<genexpr>.<genexpr>(�!��Tc���Tc�5�D�$?�$?��$F�$F�Tc�r�r@rAs& ��rr6�ITestGetStackTrace.test_async_gather_remote_stack_trace.<locals>.<genexpr>%�d��)8���)8��!+�4�>�>� :� D� D� %��&"�TX�Tc�Tc�&"���&"�TX�Tc�Tc�&"�!"��)8�rC�r4rZ)rr�r�rrr�r�r�r�r/rrUr�r�r�rWrCrFrmrgr�r�r�r�r�r�r�r�rY�r�r,r|r�rr.r�r�rTrhrHr�r�rIr�rJrKrLr�sf                 @r�$test_async_gather_remote_stack_trace�6TestGetStackTrace.test_async_gather_remote_stack_trace�s���� �!�����(�)-�v�.
�
�
��8�
�
�
!�
!�X������h��=�J��H�H�Z� �1�$�7�M�+�J��&�I�K� �M�I
?�(�#�.�.�+�)F�G�G�1�'4�';�';�'=�$�M�!�'�'�)�$(�M�/�
�x�H�H��M�M�(�H�5�"7����">�K�4?�q�>�3L�3L�#�3L�4���3L� �#�&:�	��
�
�i�=�&:�%)�$F�$F�#�%�M��$�$�%�$�c�e�$�x�j���(,�'Q�'Q�#�(�$��$�$�(�$��b�&�$�(G�'I�&J�$�%0�"�f�d�$C�%0�"�d�D�$A�!"�'���"&�!6�!6�{�!C�J�%0��N�$=�$=�3�%>�D�����/�)-���/�)��%>�0�3��$�$�3�$�b�$�!)�[�"�f�d�,K�+M� N�'���}H�P!��>�c"�
!��(#��N3�eH�G��P!��>��c"�
!�
!�si�AJ�#I6�:A,I#	�&I�<B*I#	�&5I� I#	�;I6�J�
I#	�#I3
�,I3
�.I6�6
J�J�J	�J	c�``�[2o[OQUQ02o[O29^tt^2o[
OOUQ2o[
OU2[U2o[UQU2oPo[[OU,29^tt^2oUO2vqyUO2Po[!UQ2o
RO#QU
2[%UO&2oU]*O(Tt,tFDp�O*MJ	o
oQ
FDoRO#V�2J	RO-U2oRO/UQ[12QQ.-2RO3U2oRO/UQ[4O6[8QP1U]QP11,QU]Q	P1U]Q
P1[4O6[8QP11,-2RO;U2nU]*O(Tt-tFD-oUO*[=UU1QkUO(22aJ/	ooRO/UQ,QQ[4O6[8QP1U]QP111,-2PPP2[?Vu2PPP2P!ttohttoh)%fhK09h[?Xu2h9h)%fhP!9h)z�            import asyncio.staggered
            import time
            import sys
            import socket

            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(('localhost', a))

            async def deep():
                await asyncio.sleep(0)
                sock.sendall(b"ready"); time.sleep(10_000)

            async def c1():
                await asyncio.sleep(0)
                await deep()

            async def c2():
                await asyncio.sleep(10_000)

            async def main():
                await asyncio.staggered.staggered_race(
                    [c1, c2],
                    delay=None,
                )

            asyncio.run(main())
            r{r|rr4rZ�staggered_racer7r[r<z$staggered_race.<locals>.run_one_coroc3��:�SF �DhoRUO*O[9PIc!,U1QkUO2DMJ	3LU1QkUO221w�	Jj	P!3h)c3�R:�SF �DoROU2w�	J	P!3hrr�r�s& �rr6�[TestGetStackTrace.test_async_staggered_race_remote_stack_trace.<locals>.<genexpr>.<genexpr>�r_r�r@rAs& ��rr6�QTestGetStackTrace.test_async_staggered_race_remote_stack_trace.<locals>.<genexpr>�rarCrb) rr�r�rrr�r�r�r�r/rrUr�r�r�rWrCrFrmrgr�r�r�r�r�r�rrGrr�r�rYrcsf                 @r�,test_async_staggered_race_remote_stack_trace�>TestGetStackTrace.test_async_staggered_race_remote_stack_trace<s���� �!�����(�)-�v�.
�
�
��>�
�
�
!�
!�X������h��=�J��H�H�Z� �1�$�7�M�+�J��&�I�K� �M�U
?�(�#�.�.�+�)F�G�G�1�'4�';�';�'=�$�M�!�'�'�)�$(�M�/�
�x�H�H��M�M�(�H�5�"7����">�K�4?�q�>�3L�3L�#�3L�4���3L� �#�&:�	��
�
�i�=�&:�%)�$F�$F�#�%�M��$�$�%�$�c�e�$�x�j���(,�'Q�'Q�#�(�$��$�$�(�$�%.�%7�%7��>N�PT�$U�%0�"�f�d�$C�!"�'�%�%0�"�f�d�$C�%0�"�d�D�$A�%.�%7�%7��>d�fj�$k�!"�'���("&�!6�!6�{�!C�J�%0��N�$=�$=�3�%>�D�����/�)-���/�)��%>�0�3��$�$�3�$�b�$�$,�)2�);�);�S�BR�TX�(Y�)4�b�&�$�(G�%&�!"�'���IH�h!��>�{"�
!��(#��Z3�qH�G��h!��>��{"�
!�
!�si�AK�#J;�:A,J(	�&J�<CJ(	�5J#�	7J(	�J;�K�
J(	�(J8
�1J8
�3J;�;
K�K�K	�K	c�	�]do[2o[OQUQUQ02o[O29^tt^2o[
OOUQ2o[
OU2[U2o[UQU2oPo[[OU,29^tt^2o	UO2vq�UO2Po[!UQU2[)U	O*2oUO-[/U2]2UO-[/U]*2]2UO-U]*],12U]*]*o
UO1[/U
2U2[3[4O6[8Q[8,2[3[4O6[8Q[8,2[3U[8Q	[8,2,oUO;[=[8Q
[?U[8,2,,,2U
2UO;[=[8Q[?[3[@O6[8Q[8,2,[8,2,[?[3[4O6[8Q[8,2[3[4O6[8Q[8,2[3U[8Q	[8,2,[8,2,,2U
2UO;[=[8Q
[?[3[BO6[8Q[8,2[3U[8Q[8,2,[8,2,[?[3[4O6[8Q[8,2[3[4O6[8Q[8,2[3U[8Q[8,2,[8,2,,2U
2QoS
Tt,tFDoUU2%fJUMJ	ooUO1[/U2U2[ODQ6wc5UO-UP*OFU
P*OF2PPP2[IV�2PPP2P!["c&oSO%['S22Po=CK�Po=hh9httoh)%fhK^9h[IX�2h9h)%fhP!9h)�da�            import asyncio
            import os
            import random
            import sys
            import socket
            from string import ascii_lowercase, digits
            from test.support import socket_helper, SHORT_TIMEOUT

            HOST = '127.0.0.1'
            PORT = socket_helper.find_unused_port()
            connections = 0

            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(('localhost', a�))

            class EchoServerProtocol(asyncio.Protocol):
                def connection_made(self, transport):
                    global connections
                    connections += 1
                    self.transport = transport

                def data_received(self, data):
                    self.transport.write(data)
                    self.transport.close()

            async def echo_client(message):
                reader, writer = await asyncio.open_connection(HOST, PORT)
                writer.write(message.encode())
                await writer.drain()

                data = await reader.read(100)
                assert message == data.decode()
                writer.close()
                await writer.wait_closed()
                sock.sendall(b"ready")
                await asyncio.sleep(SHORT_TIMEOUT)

            async def echo_client_spam(server):
                async with asyncio.TaskGroup() as tg:
                    while connections < a:
                        msg = list(ascii_lowercase + digits)
                        random.shuffle(msg)
                        tg.create_task(echo_client("".join(msg)))
                        await asyncio.sleep(0)
                server.close()
                await server.wait_closed()

            async def main():
                loop = asyncio.get_running_loop()
                server = await loop.create_server(EchoServerProtocol, HOST, PORT)
                async with server:
                    async with asyncio.TaskGroup() as tg:
                        tg.create_task(server.serve_forever(), name="server task")
                        tg.create_task(echo_client_spam(server), name="echo client spam")

            asyncio.run(main())
            r{r|rr5r6r7r4zserver taskzServer.serve_foreverzTask-4�sleep�echo_client�echo_client_spamc��[UO2]6wcP
!UO]*o[UO2]6wcP
!UOTt,tFDp"OMJ	ooU,QN6H!ttoh)r�)r5r6rr)rVr�r�r�)r�r�r	rs&   r�matches_awaited_by_pattern�RTestGetStackTrace.test_async_global_awaited_by.<locals>.matches_awaited_by_pattern�sj���t���/�1�4�#(�#���q�1���t���/�1�4�#(�9=���$I��A�Z�Z��	�$I�(�-� ���%Js�A9r\)%rr�r�rrr�r�r�r�r/rrUr�r�r�rWrIr>�fail�strrprgr�rV�assertGreaterEqualrrrGrrFrrrrr�r�rY)r��	NUM_TASKSr,r|r�rr.r�r�rTrhrj�all_awaited_by�entries�
main_stackrtr��tasks_with_awaiteds&                 r�test_async_global_awaited_by�.TestGetStackTrace.test_async_global_awaited_by�s����	��!�����(�)-�v�.)�4*3��4
�Q9
�;
��z�
�
�
!�
!�X������h��=�J��H�H�Z� �1�$�7�M�+�J��&�I�K� �M�
?�(�#�.�.�+�)F�G�G�1�'4�';�';�'=�$�M�!�'�'�)�$(�M�*�+�M�8�Y�O�&8����%>�N��$�$�S��%8�!�<��$�$�S���):�%;�Q�?��$�$�^�A�%6��B��@�,�Q�/��2�G��+�+�C��L�)�D�"�'�0�0�#�7I�3�O��"�'�0�0�#�7L�c�R��"�;��V�S�"A�B�"�J��M�M� � �(�X�z�3�6G�-H�,I�2�N�� �	��M�M� � #� -�$,�1:�8C�8L�8L�8;�8N�8;�	56�12�	-.�-0�)*�%&�!"�$%-�1:�8B�8K�8K�8;�8J�8;�	56�12�1:�8B�8K�8K�8;�8M�8;�	56�12�1:�5@�#�v�s�4S�12�#-.�*-0�-)*�%&�!"�)0�2�f �i5�l�M�M� � #� (�$,�1:�8=���8;�8?�8;�	56�12�1:�8C�8;�8E�8;�	56�12�-.�$-0�')*�%&�!"�4%-�1:�8B�8K�8K�8;�8J�8;�	56�12�1:�8B�8K�8K�8;�8M�8;�	56�12�1:�8C�8;�8J�8;�	56�12�#-.�4-0�7)*�%&� !"�9=�?�@ �CB�J�%,�*�$+�D�5�d�;���$+�'�*�
�+�+�C�0B�,C�Y�O��|�|�w�.��(�(�.�r�2�=�=�#�B�K�2�2��sH�|!��>�O"�
!��"(�*��	�	�#�a�&�)�)��*��P*�aH�G��|!��>��O"�
!�
!�s��AR=�#R-�=%R	�#
Q"�0KR	�R�R�1R	�4R	�R-�R=�"	R�,R�-R
�R	�
R�R	�R*
�#R*
�%R-�-
R:�:R=�=S	�S	c
��`�[2o[OQUQ02o[O29^tt^2o[
OOUQ2o[
OU2[U2o[UQU2oPo[[OU,29^tt^2oUO2vqyUO2Po[!UQ2o
[#U
O%Q]2]*O'2]*2n[)[*2FDZo	[-UO.2o[09PIcU1QkU2D%fJP	L	P
LU1QkU22%fJYL	UO3Q2PPP2[5Vu2PPP2P!)%fhK&9h[5Xu2h9h)%fhP!9h)��            import asyncio
            import socket
            import threading
            import time

            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(('localhost', ac))

            async def worker_main():
                task = asyncio.create_task(
                    asyncio.sleep(10_000),
                    name="worker task",
                )
                await asyncio.sleep(0)
                sock.sendall(f"ready:{threading.get_native_id()}\n".encode())
                await task

            def run_worker_loop():
                asyncio.run(worker_main())

            threading.Thread(
                target=run_worker_loop,
                name="async-worker",
                daemon=True,
            ).start()
            time.sleep(10_000)
            r{r|�ready:c3�:�SF �D<oUOR6XfJUOFDoUOQ6Hw�	J	J>	P!3h�zworker task�r�r�r��r3�infor��worker_thread_ids&  �rr6�VTestGetStackTrace.test_async_global_awaited_by_from_non_main_thread.<locals>.<genexpr>
sF��(6���(6��#�~�~�1A�A�<�)-����!�N�N�m�;�)8�<�(6��
�A�,AzMget_all_awaited_by() did not report the asyncio task from the non-main thread)rr�r�rrr�r�r�r�r/rrUr�r�r�rWrC�int�split�
splitlinesr
r	rprg�anyrvrY)
r�r,r|r�rr.r�r�rTrhrHrzr�s
&           @r�1test_async_global_awaited_by_from_non_main_thread�CTestGetStackTrace.test_async_global_awaited_by_from_non_main_thread�s���� �!�����(�)-�v�.
�
�
��>�
�
�
!�
!�X������h��=�J��H�H�Z� �1�$�7�M�+�J��&�I�K� �M�
?�(�#�.�.�+�)F�G�G�1�'4�';�';�'=�$�M�!�'�'�)�$(�M�/�
�y�I�H�'*� ���y�!�4�Q�7�B�B�D�Q�G�(�$�(�
�6��);�A�E�E�)B���3��(6��3�3�3��(6����"�7��	�	�H��)H�2!��>�E"�
!�H�G��2!��>��E"�
!�
!��\�AG!�#G�9BF>	�F>	�+F>	�
F>	� G�(G!�>G
�G
�	G�
G�G!�!G2	�*G2	c
��`�[2o[OQUQ02o[O29^tt^2o[
OOUQ2o[
OU2[U2o[UQU2oPo[[OU,29^tt^2oUO2vqyUO2Po[!UQ2o
[#U
O%Q]2]*O'2]*2n[)[*2FDZo	[-UO.2o[09PIcU1QkU2D%fJP	L	P
LU1QkU22%fJYL	UO3Q2PPP2[5Vu2PPP2P!)%fhK&9h[5Xu2h9h)%fhP!9h)r�a�))

            def blocking_call():
                sock.sendall(f"ready:{threading.get_native_id()}\n".encode())
                time.sleep(10_000)

            async def worker_task():
                await asyncio.sleep(0)
                blocking_call()

            async def worker_main():
                task = asyncio.create_task(
                    worker_task(),
                    name="worker task",
                )
                await task

            def run_worker_loop():
                asyncio.run(worker_main())

            threading.Thread(
                target=run_worker_loop,
                name="async-worker",
                daemon=True,
            ).start()
            time.sleep(10_000)
            r{r|r�c3�:�SF �D<oUOR6XfJUOFDoUOQ6Hw�	J	J>	P!3hr�r�r�s&  �rr6�WTestGetStackTrace.test_async_remote_stack_trace_from_non_main_thread.<locals>.<genexpr>]sF��(3���(3��#�~�~�1A�A�<�)-����!�N�N�m�;�)8�<�(3�r�zXget_async_stack_trace() did not report the running asyncio task from the non-main thread)rr�r�rrr�r�r�r�r/rrUr�r�r�rWrCr�r�r�r
r	rmrgr�rvrY)
r�r,r|r�rr.r�r�rTrhrHr�r�s
&           @r�2test_async_remote_stack_trace_from_non_main_thread�DTestGetStackTrace.test_async_remote_stack_trace_from_non_main_threads���� �!�����(�)-�v�.
�!
�#
��J�
�
�
!�
!�X������h��=�J��H�H�Z� �1�$�7�M�+�J��&�I�K� �M�
?�(�#�.�.�+�)F�G�G�1�'4�';�';�'=�$�M�!�'�'�)�$(�M�/�
�y�I�H�'*� ���y�!�4�Q�7�B�B�D�Q�G�(�$�(�
�6��&;�A�E�E�&B���3��(3��3�3�3��(3����"�7��	�	�P��)H�2!��>�E"�
!�H�G��2!��>��E"�
!�
!�r�c��[[O22oPoSFDUoUOFD6oUO[
O26XfJ)UOoL	U%fJTL	UOU2UO[U2]2UOU]*OQ2UOU]*OOQ22UOU]*OQ2UOU]*OOQ22P!)Nreztest_external_inspection.pyz!TestGetStackTrace.test_self_trace)rer��getpidr�r��	threading�
get_native_idr�rrxrVr�r��
assertTruer��endswith)r�r��this_thread_stackr�r�s&    r�test_self_trace�!TestGetStackTrace.test_self_tracels��&�b�i�i�k�2�� �� +��/�7�7���(�(�I�,C�,C�,E�E�(3�(>�(>�%�� 8�!� ��
!,�	
���.�/�����$5� 6��:����*�1�-�6�6�8I�J����)�!�,�5�5�>�>�?\�]�^����*�1�-�6�6�8[�\����)�!�,�5�5�>�>�?\�]�^r c	��[2o]PHo[OQUQ02O	2oUOU2o[OQUQU8Q02o[O29^tt^2o[OOUQ2o[OU2[U2o[UQU2o	,o
[[O U	,29^tt^2o[#2o[%U2]6cjUO'2vq�U
O)U
2U
O+Q2oQ	U7cUO-Q
2QU7cUO-Q2JwJyUO32Po[5UO62oUO9[%U2]2PoPoSFD-oUO:]6XcSoJUO:]6�fJ+SoJ/	UO=UQ
2UO?U,Q2oUO=UQ2U%c'UO?U,Q2oUO=UQ2PPP2[A,U
NUM3PPP2P![.O0cCJh9h)%fhKG9h[A,S
NSM3h9h)%fhP!9h)rz�
            import socket
            import time

            def sub_worker():
                def nested_func():
                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    sock.connect(('localhost', z�))
                    sock.sendall(b"ready:sub\n")
                    time.sleep(10_000)
                nested_func()

            sub_worker()
        �
            from concurrent import interpreters
            import time
            import sys
            import socket
            import threading

            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(('localhost', a))

            def main_worker():
                sock.sendall(b"ready:main\n")
                time.sleep(10_000)

            def run_subinterp():
                subinterp = interpreters.create()
                import pickle
                pickled_code = av
                subinterp_code = pickle.loads(pickled_code)
                subinterp.exec(subinterp_code)

            sub_thread = threading.Thread(target=run_subinterp)
            sub_thread.start()

            main_thread = threading.Thread(target=main_worker)
            main_thread.start()

            main_thread.join()
            sub_thread.join()
            r{r|�rr7s	ready:sub�sub�"Main interpreter should be presentc�"�UOQ6H!)�main_workerrrs&rr
�CTestGetStackTrace.test_subinterpreter_stack_trace.<locals>.<lambda>�s
�����}�1Lr z1Main interpreter should have main_worker in stackc�"�UOQ7!)�
sub_worker)r��nested_funcrrs&rr
r��s��a�j�j�<�'=r z=Subinterpreter should have sub_worker or nested_func in stack)!r�pickler�r��strip�dumpsrrr�r�r�r�r/rrUr�r�r�rVr��appendr=�addr#r?rWrergrx�interpreter_idrr�rY)r�r,r��subinterp_code�pickled_coder|r�rr.r��client_socketsrT�	responsesr�rhrHr��main_interp�
sub_interpr��
main_found�	sub_founds&                     r�test_subinterpreter_stack_trace�1TestGetStackTrace.test_subinterpreter_stack_trace�s��� �!���!���.0�15�v�6	�
*�

��U�W�	��|�|�N�3�����(�)-�v�	. �!-�/�0
�#
�
��B�
�
�
!�
!�X������h��=�J��H�H�Z� �1�$�7�M�+�J��&�I�K��N�:
A�(�#�.�.�+�)F�G�G�1� #��I��i�.�1�,�	"�/<�/C�/C�/E�,�M�*�1�1�-�@�'4�'9�'9�$�'?�H�,��8� )�
�
�f� 5�+�x�7� )�
�
�e� 4� 8�
"�'�'�)�$(�M�"1�!�%�%�"8�K��+�+�C��,<�a�@�#'�K�!%�J�,7�(�+�:�:�a�?�*:�K�-�<�<�q�@�)9�J�	-8��(�(�#�%I��
"&�!:�!:�$�
�'L�"�J��(�(�"�K��"�$(�$=�$=�'�L�=�%�	�
�,�,�%�[��iH�r!�@�.�@�-�@�E"�
!��* &�~�~�"�!�"��H�G��r!�@�.�@�-�@��E"�
!�
!�s��AK�#J/�9J	�:I?�I?�(I?�9A J	�J	�1AJ	�7&J	�J/�%K�?J�J�J	�J�J	�J,
�%J,
�'J/�/K�K�K	�K	c
��[2o]PHo[OQUQUQ02O	2o[OQUQUQ02O	2oUOU2oUOU2o[OQUQU8QU8Q	02o[O29^tt^2o[OOUQ
2o	[OU	2[U]Q5o
[U	QU2o,o[[O U,29^tt^2o
.Qlo[#2o[%U2]6cqU
O'2vooUO)U2UO+Q
2oUO-2O	2oUU7cUO/U2J~J�U
O52Po
[7U
O82oUO;[%U2]2STt.tFDoUO<jJ	ooUO?]UQ2UO;[%U2]2[AQU22oUO;U]2[#2oSFDFoUOBFD2oUODFDoUO/UOF2J 	J4	JH	.QloUOIU2oUOK[%U2]2PPP2[M,UNU
M3PPP2P![0O2cCJqh9httoh)%fhKL9h[M,SNS
M3h9h)%fhP!9h)ra
            import socket
            import time
            import threading

            def worker1():
                def nested_func():
                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    sock.connect(('localhost', a8))
                    sock.sendall(b"ready:sub1-t1\n")
                    time.sleep(10_000)
                nested_func()

            def worker2():
                def nested_func():
                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    sock.connect(('localhost', aD))
                    sock.sendall(b"ready:sub1-t2\n")
                    time.sleep(10_000)
                nested_func()

            t1 = threading.Thread(target=worker1)
            t2 = threading.Thread(target=worker2)
            t1.start()
            t2.start()
            t1.join()
            t2.join()
        a8))
                    sock.sendall(b"ready:sub2-t1\n")
                    time.sleep(10_000)
                nested_func()

            def worker2():
                def nested_func():
                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    sock.connect(('localhost', aD))
                    sock.sendall(b"ready:sub2-t2\n")
                    time.sleep(10_000)
                nested_func()

            t1 = threading.Thread(target=worker1)
            t2 = threading.Thread(target=worker2)
            t1.start()
            t2.start()
            t1.join()
            t2.join()
        r�a))

            def main_worker():
                sock.sendall(b"ready:main\n")
                time.sleep(10_000)

            def run_subinterp1():
                subinterp = interpreters.create()
                import pickle
                pickled_code = z�
                subinterp_code = pickle.loads(pickled_code)
                subinterp.exec(subinterp_code)

            def run_subinterp2():
                subinterp = interpreters.create()
                import pickle
                pickled_code = a�
                subinterp_code = pickle.loads(pickled_code)
                subinterp.exec(subinterp_code)

            sub1_thread = threading.Thread(target=run_subinterp1)
            sub2_thread = threading.Thread(target=run_subinterp2)
            sub1_thread.start()
            sub2_thread.start()

            main_thread = threading.Thread(target=main_worker)
            main_thread.start()

            main_thread.join()
            sub1_thread.join()
            sub2_thread.join()
            r{�r-r|r�r�c3�X�SF �Do[UO2w�	J	P!3hr�rVr��r3r's& rr6�OTestGetStackTrace.test_multiple_subinterpreters_with_threads.<locals>.<genexpr>�s��:E���:E���F�N�N�+�+�+���#*>�
ready:main�
ready:sub1-t1�
ready:sub1-t2�
ready:sub2-t1�
ready:sub2-t2>�worker1�worker2r�r�)'rr�r�r�r�r�rrr�r�r�r�r/rrUr�r�r�rVr�r�r=�decoder�r#r?rWrergrxr�rF�sumr�r�r��intersection�
assertGreaterrY)r�r,r��subinterp1_code�subinterp2_code�
pickled_code1�
pickled_code2r|r�rr.r�r�rT�expected_responsesr�r�rhrH�response_strr�r'�interpreter_ids�
total_threads�
all_funcnamesr�r�r��expected_funcs�found_funcss&                             r�*test_multiple_subinterpreters_with_threads�<TestGetStackTrace.test_multiple_subinterpreters_with_threadssn�� �!���"�/�/�/0�15�v�60�15�v�6	�!+�
�6�U�W�7	�:#�/�/�/0�15�v�60�15�v�6	�!+�
�6�U�W�7	�:���_�5�
����_�5�
����(�)-�v�	. �!.�0�1 �!.�0�1
�1'
�)
��V�
�
�
!�
!�X������h��=�J��H�H�Z� �1�$��B�M�+�J��&�I�K��N�@
A�(�#�.�.�+�)F�G�G�1�*�&�!$��I��i�.�1�,�"�/<�/C�/C�/E�,�M�1�*�1�1�-�@�'4�'9�'9�$�'?�H�+3�?�?�+<�+B�+B�+D�L�+�/A�A� )�
�
�l� ;� B�
"�'�'�)�$(�M�"1�!�%�%�"8�K��+�+�C��,<�a�@�=H�'�<G�&��-�-�K�$�'��M�M��'�<��
�+�+�C��,@�!�D�%(�(�:E�(�%�M��+�+�M�1�=�%(�E�M�,7�(�+;�+C�+C�K�)4�)?�)?�� -� 1� 1�%�.�.� A�*@�,D�-8�
&�N�#1�"=�"=�m�"L�K��&�&�s�;�'7��;�{H�~!�@�.�@�-�@�Q"�
!��8 &�~�~�"�!�"��'�?H�G��~!�@�.�@�-�@��Q"�
!�
!�s��AM.�#M�>M	�AL%�8L%�	A	M	�M�)CM	�M�M.�%L?�9L?�:M	�>L?�?M	�M
�M
�M�M+�+M.�.M?	�7M?	z2Free threaded builds don't have an 'active thread'c
���[2o[OQUQ02o[O29^tt^2o[
OOUQ2o[
OU2[U2o[UQU2oPo[[OU,29^tt^2oUO2vqyUO2Po[!UQQ,2[#UO$P	Q5o
['[(2FDdo	[*O,[/9^tt^2U
O12oUO3UQ2oU%c
PPP2LPPP2Jf	UO5Q2[#UO$P	Q	5o
[7U
Q
Q5o[9QW22oUO;U]2[9Q
U22oUO=U]2PoSFD5oUO>%fJUO>]*O@oL	,oSFD2oUO>FDoUOCUO@2J 	J4	UOEUU2PPP2[GVu2PPP2P!)%fhCJ�9h)%fhK;9h[GXu2h9h)%fhP!9h)ra�))

            def worker_thread(name, barrier, ready_event):
                barrier.wait()
                ready_event.wait()
                time.sleep(10_000)

            def main_work():
                sock.sendall(b"working\n")
                count = 0
                while count < 100000000:
                    count += 1
                    if count % 10000000 == 0:
                        pass
                sock.sendall(b"done\n")

            num_threads = 3
            barrier = threading.Barrier(num_threads + 1)
            ready_event = threading.Event()

            threads = []
            for i in range(num_threads):
                t = threading.Thread(target=worker_thread, args=(f"Worker-{i}", barrier, ready_event))
                t.start()
                threads.append(t)

            barrier.wait()
            sock.sendall(b"ready\n")
            ready_event.set()
            main_work()
            r{r|rsworking�rcc�d�UOQ6H9%cUOO]6�!)�	main_workrrs&rr
�;TestGetStackTrace.test_only_active_thread.<locals>.<lambda>	s.��!�*�*��*C�+;�+;�$%�J�J�$5�$5��$:�+;r z/Main thread did not start its busy work on time)�only_active_threadc�,�[QU22]6�!)c3�X�SF �Do[UO2w�	J	P!3hrr�)r3�is& rr6�NTestGetStackTrace.test_only_active_thread.<locals>.<lambda>.<locals>.<genexpr>s������1��A�I�I����r�)r�)�ts&rr
r�s��C�/J��/J�,J�a�,Or �rsc3�X�SF �Do[UO2w�	J	P!3hrr�r�s& rr6�<TestGetStackTrace.test_only_active_thread.<locals>.<genexpr>���:D���:D���F�N�N�+�+�*�r�c3�X�SF �Do[UO2w�	J	P!3hrr�r�s& rr6r�$r�r�)$rr�r�rrr�r�r�r�r/rrUr�r�r�rWrCrrgr
r	�
contextlib�suppressrrrer�rvrvr�r�r�r�r�r�rFrY)r�r,r|r�rr.r�r�rTrh�unwinder_all�
all_traces�found�unwinder_gil�
gil_tracesr��total_gil_threads�
gil_thread_idr��all_thread_idsr�s&                    r�test_only_active_thread�)TestGetStackTrace.test_only_active_thread�s��� �!�����(�)-�v�.
�	"
�$
��L�
�
�
!�
!�X������h��=�J��H�H�Z� �1�$�7�M�+�J��&�I�K� �M�A
?�(�#�.�.�+�)F�G�G�1�'4�';�';�'=�$�M�!�'�'�)�$(�M�%�]�X�z�4J�K�$2�!�%�%�T�#J�L�'�
�6��'�0�0�2B�C�C�)5�)E�)E�)G�J�$(�$=�$=� *�!;�%�E�
 %� %�D�C� %�D�C�7��	�	�M��
$2����$�$�L�
"=�$�"O�"�J�%(�(�:D�(�%�M��&�&�}�a�8�(+�,�:D�,�)�%��$�$�%6��:�%)�M�,6�(�+�3�3�3�,<�,D�,D� !�-�'�i�*�"�-7�&(�N�,6�(�+;�+C�+C�K�*�1�1�+�2G�2G�H�,D�-7��M�M�-��@�}H�@!��>�S"�
!�(D�C�C��H�G��@!��>��S"�
!�
!�s|�AK�#K�8A=J4	�5+J�!J�"J4	�.BJ4	�A/J4	�K�	K�J1�(J1�*
J4	�4K
�=K
�?K�
K�K�K(	� K(	c�&�[OQ2oQoUOVQQ5vq4UOUQ2oUO	UQ2UOUO[2UOUO]2P!)z=Test that opcodes are collected when the opcodes flag is set.�            import time, sys, socket

            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(('localhost', {port}))

            def foo():
                sock.sendall(b"ready")
                time.sleep(10_000)

            foo()
            c�:�[UP	Q5O2!�T)�opcodes�rre�rgs&r�get_trace_with_opcodes�ITestGetStackTrace.test_opcodes_collection.<locals>.get_trace_with_opcodesR���!�#�t�4�D�D�F�Fr r�r�c�"�UOQ6H!rrrs&rr
�;TestGetStackTrace.test_opcodes_collection.<locals>.<lambda>[�
��1�:�:��#6r �Could not find foo frame)	r�r�r�r�r�assertIsInstancer�r�rx)r�r|r�r�rh�	foo_frames&     r�test_opcodes_collection�)TestGetStackTrace.test_opcodes_collection<s������
�

��	G��7�7��X�8�
���
�-�-��6�
�	�	
���Y�(B�C����i�.�.��4����	� 0� 0�!�4r c�n�[OQ2oQoUOVQQ5vq4UOUQ2oUO	UQ2UO
oUO
U[2UO[U2]2Uvqxq�UO
U[2UOU]2UO
U[2UOV�2UO
U	[2UOU	]2UO
U
[2UOV�2P!)zQTest that location is a 4-tuple (lineno, end_lineno, col_offset, end_col_offset).r�c�:�[UP	Q5O2!r�r�r�s&rr��LTestGetStackTrace.test_location_tuple_format.<locals>.get_trace_with_opcodeswr�r rrc�"�UOQ6H!rrrs&rr
�>TestGetStackTrace.test_location_tuple_format.<locals>.<lambda>�rr r)
r�r�r�r�rr�rr�r�rVr�r�rx)r�r|r�r�rhrr�r��
end_lineno�
col_offset�end_col_offsets&          r�test_location_tuple_format�,TestGetStackTrace.test_location_tuple_formatas�����
�

��	G��7�7��X�8�
���
�-�-��6�
�	�	
���Y�(B�C��%�%�����h��.�����X���*�9A�6��J����f�c�*����6�1�%����j�#�.����
�3����j�#�.����
�A�.����n�c�2�����;r c�L�[OQ2oQoUOVQQ5vq4UOUQ2oUO	UQ2UO
oQQ,oUOUOUOUO1oUOV�2P!)	z=Test exact values of location tuple including column offsets.r�c�:�[UP	Q5O2!r�r�r�s&rr��RTestGetStackTrace.test_location_tuple_exact_values.<locals>.get_trace_with_opcodes�r�r rrc�"�UOQ6H!rrrs&rr
�DTestGetStackTrace.test_location_tuple_exact_values.<locals>.<lambda>�rr r)�r��)�rr�)r�r�r�r�rr�r�rrrrF)	r�r|r�r�rhrr��valid_locations�actuals	&        r� test_location_tuple_exact_values�2TestGetStackTrace.test_location_tuple_exact_values�s������
�

��	G��7�7��X�8�
����-�-��6�
�	�	
���Y�(B�C��%�%����
���/�/�8�#6�#6��%�%�x�'>�'>�@���
�
�f�.r r2)r�r�r�r�r�r^r_r�r�rrrr+rMrWrdrlr~r�r�r�rar�r�rr�rrrr�r�r�s@rr�r��s������
�_�_������B�B�(B�$B�?��F?�	��
F?�P�
�_�_������B�B�(B�$B�?��#
�	��
#
�J�
�_�_������B�B�(B�$B�?��>;�	��
>;�@�
�_�_������B�B�(B�$B�?��EC�	��
EC�N�
�_�_������B�B�(B�$B�?��J?�	��
J?�X�
�_�_������B�B�(B�$B�?��o?�	��
o?�b�
�_�_������B�B�(B�$B�?��~?�	��
~?�@�
�_�_������B�B�(B�$B�?��J?�	��
J?�X�
�_�_������B�B�(B�$B�?��C?�	��
C?�J�
�_�_������B�B�(B�$B�?��I?�	��
I?�V�
�_�_������B�B�(B�$B�?��_�	��
_�(�
�_�_������B�B�(B�$B�?���yA��	��yA�v�
�_�_������B�B�(B�$B�?���uA��	��uA�n�
�_�_������B�B�(B�$B�?���N�O�q?�P�	��q?�f�
�_�_������B�B�(B�$B�?��5�	��
5�@�
�_�_������B�B�(B�$B�?��*<�	��
*<�X�
�_�_������B�B�(B�$B�?��%/�	��
%/r r�c�`�\sQsQsn\O
\OQ7Q2\O
\OQ6HQ2Q22sQs	Us
P!)�TestUnsupportedPlatformHandlingi�zFTest only runs on unsupported platforms (not Linux, macOS, or Windows)�android�'Android raises Linux-specific exceptionc��UO[29^tt^2o[[O22PPP2UOQ[
WO22P!)%fhK79h)Nz?Reading the PyRuntime section is not supported on this platform)�assertRaisesr>rr�r�rFrw�	exception)r��cms& r�test_unsupported_platform_error�?TestUnsupportedPlatformHandling.test_unsupported_platform_error�sP���
�
�|�
,�
,���2�9�9�;�'�-�	
�
�
�M������	
�-�
,�s�A-�-A=	�6A=	r2�r[rZr\)r�r�r�r�r^r_r�r�r)r�r�r�s@rr"r"�sR����
�_�_����4�4�P���_�_����	�!�#L��
��	�
r r"c�`�\sQsQsnQs\O\OQ7Q2\O\OQ6HQ2Q22s	\O\OQ7Q2\O\OQ6HQ2Q22s
\O\OQ7Q2\O\OQ6HQ2Q22sQ	s\
Q
2s\O\OQ7Q2\O\OQ6HQ2Q22s\O\OQ7Q2\O\OQ6HQ2Q22sQ
sUsP!)�TestDetectionOfThreadStatusi�c
���[2o[OQUQ02o[O29^tt^2o[
OOUQ2o[
OU2[U2o[UQU2oPo	[[OU,29^tt^2o
UO2vq�UO2Po[!U	,QN2oPo
PoUO#Q2FDyoUO%Q2%c%['UO#Q2P*2o
J>UO%Q2%fJW['UO#Q2P*2oJ{	UO-U
Q	2UO-UQ
2-o[/U
O0P	UP
Q5o[3[42FDio[6O8[;9^tt^2UO=2oUO?U2oUUV�2%c
PPP2L
PPP2Jk	UV�1ttPPP2[AV�2ttPPP2![([*1cCJqh9h[([*1cCJ�h9h)%fhJ�9h)%fhL9h[AX�2L[AX�2h9hPPP2P!)%fhP!9h)
z�
Common pattern for thread status detection tests.

Args:
    mode: Profiling mode (PROFILING_MODE_CPU, PROFILING_MODE_GIL, etc.)
    check_condition: Function(statuses, sleeper_tid, busy_tid) -> bool
z�            import time, sys, socket, threading
            import os

            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(('localhost', a�))

            def sleeper():
                tid = threading.get_native_id()
                sock.sendall(f'ready:sleeper:{tid}\n'.encode())
                time.sleep(10000)

            def busy():
                tid = threading.get_native_id()
                sock.sendall(f'ready:busy:{tid}\n'.encode())
                x = 0
                while True:
                    x = x + 1
                time.sleep(0.5)

            t1 = threading.Thread(target=sleeper)
            t2 = threading.Thread(target=busy)
            t1.start()
            t2.start()
            sock.sendall(b'ready:main\n')
            t1.join()
            t2.join()
            sock.close()
            r{�thread_status_script�
sready:sleeper:�:sready:busy:�Sleeper thread id not received�Busy thread id not received�rc�mode�skip_non_matching_threads)rs
ready:sleepers
ready:busy)!rr�r�rrr�r�r�r�r/rrUr�r�r�rWrCr��
startswithr��
ValueError�
IndexErrorrrrgr
r	r�r�rrrer�rY)r�r5�check_conditionr,r|r�rr.r�r�rTrhrH�sleeper_tid�busy_tid�liner�rirus&&&                r�_run_thread_status_test�3TestDetectionOfThreadStatus._run_thread_status_test�s��� �!�����(�
)-�v�.
�
�
��@�
�
�
!�
!�X������h��=�J��H�H�Z� �1�$�7�M�+��2�F��K�!�M�5
?�(�#�.�.�+�)F�G�G�1�'4�';�';�'=�$�M�!�'�'�)�$(�M� 0�%�H� �H�
#'�K�#�H� (���u� 5���?�?�+<�=�=�%�.1�$�*�*�T�2B�2�2F�.G��"�_�_�^�<�<�%�+.�t�z�z�$�/?��/C�+D��!6��(�(�#�%E���(�(� �"?��
 "�H�-����$(�!�27�	 �H�(�
�6��'�0�0�2B�C�C�%-�%=�%=�%?�F�'+�'@�'@��'H�H�.� (�+� � �!&�D�C� �	D�C�7�$�[�:�eH�G�h!��>�"�
!��8%/�
�#;�%� $�%��
%/�
�#;�%� $�%��&D�C�C��SH�G��G�h!��>�� ��>��>�"�
!�
!�
!�s��AK�#K�8A"J#	�!I�=J#	�!I6�:A6J#	�00J�!J�"J#	�.J#	�=
K�K�I3�-I3�.J#	�2I3�3J#	�6J�J�J#	�J�J#	�J �J �	J#	�#J3
�,J3
�.K�7K�
K�K�K/	�'K/	�@Test only runs on supported platforms (Linux, macOS, or Windows)r#r$c��QoUO[U2vq#oUOV22UOVB2UOV#*[*Q2UOV$*[*Q2P!)c��V79%c@V 79%c4V*[*%(9%cV*[*!r)�THREAD_STATUS_ON_CPU�r�r;r<s&&&r�check_cpu_status�RTestDetectionOfThreadStatus.test_thread_status_detection.<locals>.check_cpu_statusE	sT���'�@�@��(�@�@�!�.�1E�E�F�@�@��'�*>�>�	
r z Sleeper thread should be off CPUzBusy thread should be on CPU)r>�PROFILING_MODE_CPUrF�assertFalserCr�)r�rEr�r;r<s&    r�test_thread_status_detection�8TestDetectionOfThreadStatus.test_thread_status_detection=	sx��	�+/�*F�*F�� 0�+
�'��x�	
�
�
�k�,��
�
�h�)�����!�$8�8�.�	
�	
�����!5�5�*�	
r c��QoUO[U2vq#oUOV22UOVB2UOV#*[*Q2UOV$*[*Q2P!)c��V79%c@V 79%c4V*[*%(9%cV*[*!r)�THREAD_STATUS_HAS_GILrDs&&&r�check_gil_status�VTestDetectionOfThreadStatus.test_thread_status_gil_detection.<locals>.check_gil_statusd	sT���'�A�A��(�A�A�!�.�1F�F�G�A�A��'�*?�?�	
r z"Sleeper thread should not have GILzBusy thread should have GIL)r>�PROFILING_MODE_GILrFrHrMr�)r�rNr�r;r<s&    r� test_thread_status_gil_detection�<TestDetectionOfThreadStatus.test_thread_status_gil_detection\	sx��	�+/�*F�*F�� 0�+
�'��x�	
�
�
�k�,��
�
�h�)�����!�$9�9�0�	
�	
�����!6�6�)�	
r c
��[2o[OQUQUQ02o[O29^tt^2o[UQU2o[
U]Q5o,o[[OU,29^tt^2oPoPo	[]2FD�o
UO2vq�UOU2UOQ2oU%fJAUOQ2%c%[UO!Q2P*2oJ|UOQ2%fJ�[UO!Q2P*2o	J�	UO'2Po-o
[)UO*P	[,P
Q	5o[/[02FD�o
[2O4[79^tt^2UO92oUO;U2o
V�7cwV�7cqV�*[<*%fXV�*[>*%f?V�*[<*%c&V�*[>*%c
PPP2LPPP2J�	UOAUQ
2UOAU	Q2UOCV�2UOCV�2UOEV�*[<*Q2UOEV�*[>*Q
2UOGV�*[<*Q2UOGV�*[>*Q2PPP2[I,UNUM3PPP2P!["[$1cCJ�h9h["[$1cCJ�h9h)%fhCJ9h)%fhKq9h[I,SNSM3h9h)%fhP!9h)z�            import socket
            import threading
            import time
            import sys

            def sleeper_thread():
                conn = socket.create_connection(("localhost", z�))
                conn.sendall(b"sleeper:" + str(threading.get_native_id()).encode())
                while True:
                    time.sleep(1)

            def busy_thread():
                conn = socket.create_connection(("localhost", am))
                conn.sendall(b"busy:" + str(threading.get_native_id()).encode())
                while True:
                    sum(range(100000))

            t1 = threading.Thread(target=sleeper_thread)
            t2 = threading.Thread(target=busy_thread)
            t1.start()
            t2.start()
            t1.join()
            t2.join()
            r|r�r�ssleeper:r1sbusy:r4r2r3zSleeper should be off CPUzSleeper should not have GILzBusy should be on CPUzBusy should have GIL)%rr�r�rrrr/rUr�r��ranger�r�r=r7r�r�r8r9rWrrg�PROFILING_MODE_ALLr
r	r�r�rrrer�rCrMrrFrHr�rY)r�r,r|�tmp_dir�script_filer.r�rTr;r<rhr�r=r�rirus&               r�%test_thread_status_all_mode_detection�ATestDetectionOfThreadStatus.test_thread_status_all_mode_detection{	sd�� �!�����?�@D�f�E?�@D�f�E
�
�
��8�
�
�
!�
!�W�%�g�x��@�K�1�$��B�M��N�W
A�(��^�^�[�1����"&�K�#�H�#�1�X��+8�+?�+?�+A�(�
�&�-�-�m�<�,�1�1�$�7���4�#���{�;�;�!)�25�d�j�j��6F�r�6J�2K�K�"&����!:�!:�!)�/2�4�:�:�d�3C�B�3G�/H�H�&� "�'�'�)�$(�M�!�H�-����$(�/�27�	 �H�(�
�6��'�0�0�2B�C�C�%-�%=�%=�%?�F�'+�'@�'@��'H�H�!,� 7�$,�$8�$,�$9�&:�%;�%;�%-�$9�&;�%<�%<�&.�%7�:N�%N�%N�$,�$6�9N�$N�$N�!&�+D�C�C�7�0�(�(�#�%E���(�(� �"?���M�M�+�8��M�M�(�5��$�$� �-�0D�D�3���$�$� �-�0E�E�5���O�O� �*�-A�A�/���O�O� �*�-B�B�.��c�l!�@�.�@�-�@�y"�
!��*)3�J�'?�!)�$(�!)��
)3�J�'?�!)�$(�!)��D�C�C��E���l!�@�.�@�-�@��y"�
!�
!�s��O�$#N/�A
N	�N	�1!M�N	�.!M.�A(N	�7'N�N�%N�>N�N�0N�	N�
C)N	�3N/�;O�M+�%M+�&N	�*M+�+N	�.N�>N�?N	�N�N	�N�N�
N	�N,
�%N,
�'N/�/O�O�O	�O	c�>�[OQUQUQ02!)z<Create script with exception and normal threads for testing.z�            import socket
            import threading
            import time

            def exception_thread():
                conn = socket.create_connection(("localhost", aq))
                conn.sendall(b"exception:" + str(threading.get_native_id()).encode())
                try:
                    raise ValueError("test exception")
                except ValueError:
                    while True:
                        time.sleep(0.01)

            def normal_thread():
                conn = socket.create_connection(("localhost", aq))
                conn.sendall(b"normal:" + str(threading.get_native_id()).encode())
                while True:
                    sum(range(1000))

            t1 = threading.Thread(target=exception_thread)
            t2 = threading.Thread(target=normal_thread)
            t1.start()
            t2.start()
            t1.join()
            t2.join()
            )r�r�)r�r,s&&r�_make_exception_test_script�7TestDetectionOfThreadStatus._make_exception_test_script�	s;�����?�@D�f�	E?�@D�f�E
�
�
�	
r c#�� �[2oUOU2o[O29^tt^2o[	UQU2o[U]Q5o,o[
[OU,29^tt^2oPoPo	[]2FD�o
UO2vq�UOU2UOQ2oU%fJAUOQ2%c%[UOQ2P*2oJ|UOQ2%fJ�[UOQ2P*2o	J�	UO%2PoVxU	1w�PPP2[',UNUM3PPP2P![ ["1cCJh9h[ ["1cCJ$h9h)%fhK\9h[',SNSM3h9h)%fhP!9h3h)zNContext manager to run exception test script and yield thread IDs and process.r|r�r�s
exception:r1snormal:)rr[rrrr/rUr�r�rTr�r�r=r7r�r�r8r9rWrY)
r�r,r|rVrWr.r�rT�
exception_tid�
normal_tidrhr�r=s
&            r�_run_exception_test_process�7TestDetectionOfThreadStatus._run_exception_test_process
s���� �!���1�1�$�7��
�
�
�
!�
!�W�%�g�x��@�K�1�$��B�M��N�
A�(�#�.�.�+�)F�G�G�1�$(�M�!%�J�"�1�X��+8�+?�+?�+A�(�
�&�-�-�m�<�,�1�1�$�7���4�#���}�=�=�!)�47��
�
�4�8H��8L�4M�M�"&����!<�!<�!)�14�T�Z�Z��5E�b�5I�1J�J�&� "�'�'�)�$(�M��J�6�6�/H�2!�@�.�@�-�@�?"�
!��$)3�J�'?�!)�$(�!)��
)3�J�'?�!)�$(�!)��#H�G��2!�@�.�@�-�@��?"�
!�
!�s��:G1�G�#G	�=A
F6	�F6	�'!F�F6	�$!F�F6	�"G	�*G�:
G1�F�F�F6	�F�F6	�F3�-F3�.F6	�2F3�3F6	�6G
�?G
�G	�	G�G�G.	�&G.	�(	G1c�N�UO29^tt^2vqoUOUQ2UOUQ2-o[UOP	[P
Q5o[[2FD�o[O[9^tt^2UO2oUOU2oV$7cEV47c?VB*[*%c&VC*[*%f
PPP2LPPP2J�	UOV$2UOV42UOVB*[*Q2UOVC*[*Q2PPP2P!)%fhCJ9h)%fhP!9h)zQTest that THREAD_STATUS_HAS_EXCEPTION is set when thread has an active exception.� Exception thread id not received�Normal thread id not receivedr4z/Exception thread should have HAS_EXCEPTION flagz0Normal thread should not have HAS_EXCEPTION flag)r`rrrgrUr
r	r�r�rrrer��THREAD_STATUS_HAS_EXCEPTIONrFr�rH)r�rTr^r_r�rirhrus&       r�&test_thread_status_exception_detection�BTestDetectionOfThreadStatus.test_thread_status_exception_detectionE
sJ���
-�
-�
/�
/�3Q�A�j�� � ��0R�S�� � ��-L�M��H�%���� �'�*/�	�H� �
�.���(�(�*:�;�;�%�5�5�7�F�#�8�8��@�H�&�1�&�2�%�4�7R�R�R�!)�!5�8S�!S�!S��<�;�;�/�
�M�M�-�2��M�M�*�/��O�O��'�*E�E�A�
�
����$�'B�B�B�
�=0�
/�<�;�;��0�
/�
/�sI�A:F�'E>
�<E>
�E>
�E>
�4E>
�5A?F�>F�F�	
F�F$	�F$	c�d�UO29^tt^2vqoUOUQ2UOUQ2[UOP	[P	Q5o[[2FD|o[O[9^tt^2UO2oUOU2oV'7c)UOUUQ2PPP2PPP2P!PPP2J~	UOQ2PPP2P!)%fhJ�9h)%fhP!9h)z=Test that PROFILING_MODE_EXCEPTION correctly filters threads.rcrdr4z6Normal thread should be filtered out in exception modez.Never found exception thread in exception mode)r`rrrg�PROFILING_MODE_EXCEPTIONr
r	r�r�rrrer��assertNotInrv)r�rTr^r_rirhrur�s&       r�+test_thread_status_exception_mode_filtering�GTestDetectionOfThreadStatus.test_thread_status_exception_mode_filteringq
s���
-�
-�
/�
/�3Q�A�j�� � ��0R�S�� � ��-L�M�%���� �-�*.�	�H� �
�.���(�(�*:�;�;�%�5�5�7�F�#�8�8��@�H�$�0��(�(�&�$�T��
�<�;�0�
/�1�	<�;�/�
�I�I�F�G�/0�
/�<�;�;��0�
/�
/�s<�A8D�'D

�:D

�
D�#D�
D�D�	D�D/	�'D/	r2r+)r�r�r�r�r>r^r_r�r�rIrQrXr[rr`rfrkr�r�r�s@rr-r-�s�����h?�T�_�_����8�8�J���_�_����	�!�#L��
��	�
�0�_�_����8�8�J���_�_����	�!�#L��
��	�
�0�_�_����8�8�J���_�_����	�!�#L��zA��	�zA�x
�@�$A��$A�L�_�_����8�8�J���_�_����	�!�#L��#��	�#�J�_�_����8�8�J���_�_����	�!�#L��H��	�Hr r-c�`�\sQsQsnQsQs\Q2sQQksQs	\
O\OQ7Q2\
O\OQ6HQ	2Q
22s\
O\OQ7Q2\
O\OQ6HQ	2Q22s\
O\OQ7Q2\
O\OQ6HQ	2Q22s\
O\OQ7Q2\
O\OQ6HQ	2Q
22sQsUsP!)�TestExceptionDetectionScenariosi�
a�Test exception detection across all scenarios.

This class verifies the exact conditions under which THREAD_STATUS_HAS_EXCEPTION
is set. Each test covers a specific scenario:

1. except_block: Thread inside except block
   -> SHOULD have HAS_EXCEPTION (exc_info->exc_value is set)

2. finally_propagating: Exception propagating through finally block
   -> SHOULD have HAS_EXCEPTION (current_exception is set)

3. finally_after_except: Finally block after except handled exception
   -> Should NOT have HAS_EXCEPTION (exc_info cleared after except)

4. finally_no_exception: Finally block with no exception raised
   -> Should NOT have HAS_EXCEPTION (no exception state)
c
�H�QQUQ0QQUQ0QQUQ	0Q
QUQ0-oV2*!)
z.Create script for a single exception scenario.�except_blockz�import socket
import threading
import time

def target_thread():
    '''Inside except block - exception info is present'''
    conn = socket.create_connection(("localhost", z�))
    conn.sendall(b"ready:" + str(threading.get_native_id()).encode())
    try:
        raise ValueError("test")
    except ValueError:
        while True:
            time.sleep(0.01)

t = threading.Thread(target=target_thread)
t.start()
t.join()
�finally_propagatingz�import socket
import threading
import time

def target_thread():
    '''Exception propagating through finally - current_exception is set'''
    conn = socket.create_connection(("localhost", a�))
    conn.sendall(b"ready:" + str(threading.get_native_id()).encode())
    try:
        try:
            raise ValueError("propagating")
        finally:
            # Exception is propagating through here
            while True:
                time.sleep(0.01)
    except:
        pass  # Never reached due to infinite loop

t = threading.Thread(target=target_thread)
t.start()
t.join()
�finally_after_exceptz�import socket
import threading
import time

def target_thread():
    '''Finally runs after except handled - exc_info is cleared'''
    conn = socket.create_connection(("localhost", a4))
    conn.sendall(b"ready:" + str(threading.get_native_id()).encode())
    try:
        raise ValueError("test")
    except ValueError:
        pass  # Exception caught and handled
    finally:
        while True:
            time.sleep(0.01)

t = threading.Thread(target=target_thread)
t.start()
t.join()
�finally_no_exceptionz�import socket
import threading
import time

def target_thread():
    '''Finally with no exception at all'''
    conn = socket.create_connection(("localhost", z�))
    conn.sendall(b"ready:" + str(threading.get_native_id()).encode())
    try:
        pass  # No exception
    finally:
        while True:
            time.sleep(0.01)

t = threading.Thread(target=target_thread)
t.start()
t.join()
r2)r�r,�scenario�	scenarioss&&& r�_make_single_scenario_script�<TestExceptionDetectionScenarios._make_single_scenario_script�
s���
�!3�48�&�9��&
"�(3�48�&�9�$�.
#�)3�48�&�
9�%�*
#�)3�48�&�9�%�AS
�	�j�"�"r c	#�� �[2oUOV!2o[O29^tt^2o[	UQU2o[U]Q5oPo[
[OU,29^tt^2oPo	UO2vqzUOQ2oU%c:UOQ2%c#[UOQ2P*2o	UO!2PoV�1w�PPP2[#Vv2PPP2P![[1cKIh9h)%fhK=9h[#Xv2h9h)%fhP!9h3h)zIContext manager to run a single scenario and yield thread ID and process.r|r�r�r�r1)rrvrrrr/rUr�r�r�r=r7r�r�r8r9rWrY)r�rtr,r|rVrWr.r�rT�
thread_tidrhr=s&&          r�_run_scenario_process�5TestExceptionDetectionScenarios._run_scenario_processs*��� �!���2�2�4�B��
�
�
�
!�
!�W�%�g�x��@�K�1�$��B�M� �M�
?�(�#�.�.�+�)F�G�G�1�!%�J�'4�';�';�'=�$�M�(�-�-�d�3�D�����	� :� :�!�),�T�Z�Z��-=�b�-A�)B�J�"�'�'�)�$(�M��-�'�H� !��>�-"�
!��!+�J�7�!� �!��H�G�� !��>��-"�
!�
!�s��:E(�E�#E�=-D1	�+D1	�!D�$D1	�<E�E�
E(�D.�*D.�+D1	�-D.�.D1	�1E
�:E
�<E�
E�E�E%	�E%	�	E(c	���[UOP	[P
Q5o]o[[2FD�o[
O[9^tt^2UO2oUOU2o	V)7c/UV�2%cU]*
oU]6�cPPP2P!L]oPPP2J�	UOQUQ02P!)%fhJ�9h)aEHelper to check thread status with a custom condition.

This waits until we see 3 consecutive samples where the condition
returns True, which confirms the thread has reached and is stable
in the expected state. Samples that don't match are ignored (the
thread may not have reached the expected state yet).

Args:
    p: Process object with pid attribute
    thread_tid: Thread ID to check
    condition: Callable(statuses, thread_tid) -> bool that returns
               True when the thread is in the expected state
    condition_name: Description of condition for error messages
r4z,Thread did not stabilize in expected state (z) within timeout)rrgrUr
r	r�r�rrrer�rv)
r�rTryrs�condition_nameri�matching_samplesrhrur�s
&&&&&     r�_check_thread_status�4TestExceptionDetectionScenarios._check_thread_statuss���""�
�E�E��#�&+�	
�����M�*�A��$�$�&6�7�7�!�1�1�3���4�4�V�<���)� ��6�6�(�A�-�(�+�q�0�"�8�7�1�,-�(�8�7�+�	
�	�	����/�
1�	
�8�7�7�s*�'C
	�<
C
	�
C
	�C
	�'C
	�
C
�C
c�D`�U1QkoUOVUQR0Q5P!)z8Helper to check if thread has expected exception status.c�H:�[V*[*2oUR6H!r)�boolre)r��tid�has_exc�expect_exceptions&& �rrs�JTestExceptionDetectionScenarios._check_exception_status.<locals>.conditionMs!����8�=�+F�F�G�G��.�.�.r zexpect_exception=)r})r)r�rTryr�rss&&&f r�_check_exception_status�7TestExceptionDetectionScenarios._check_exception_statusKs.���	/�	
�!�!�
�9�.�/?�.@�A�	"�	
r r@r#r$c���UOQ29^tt^2vqUOUQ2UOVP	Q5PPP2P!)%fhP!9h)z�Test that thread inside except block has HAS_EXCEPTION flag.

When a thread is executing inside an except block, exc_info->exc_value
is set, so THREAD_STATUS_HAS_EXCEPTION should be True.
rp�Thread ID not received�r��rzrr��r�rTrys&  r�test_except_block_has_exception�?TestExceptionDetectionScenarios.test_except_block_has_exceptionVsL���
'�
'��
7�
7�?�A�� � ��-E�F��(�(���(�N�8�
7�
7�
7���(A
�
A	�A	c���UOQ29^tt^2vqUOUQ2UOVP	Q5PPP2P!)%fhP!9h)z�Test that finally block with propagating exception has HAS_EXCEPTION flag.

When an exception is propagating through a finally block (not yet caught),
current_exception is set, so THREAD_STATUS_HAS_EXCEPTION should be True.
rqr�r�r�r�s&  r�&test_finally_propagating_has_exception�FTestExceptionDetectionScenarios.test_finally_propagating_has_exceptiongsM���
'�
'�(=�
>�
>�/�1�� � ��-E�F��(�(���(�N�?�
>�
>�
>�r�c���UOQ29^tt^2vqUOUQ2UOVP
Q5PPP2P!)%fhP!9h)z�Test that finally block after except has NO HAS_EXCEPTION flag.

When a finally block runs after an except block has handled the exception,
Python clears exc_info before entering finally, so THREAD_STATUS_HAS_EXCEPTION
should be False.
rrr�r�r�r�s&  r�&test_finally_after_except_no_exception�FTestExceptionDetectionScenarios.test_finally_after_except_no_exceptionxsN���
'�
'�(>�
?�
?�?�A�� � ��-E�F��(�(���(�O�@�
?�
?�
?�r�c���UOQ29^tt^2vqUOUQ2UOVP
Q5PPP2P!)%fhP!9h)z�Test that finally block with no exception has NO HAS_EXCEPTION flag.

When a finally block runs during normal execution (no exception raised),
there is no exception state, so THREAD_STATUS_HAS_EXCEPTION should be False.
rsr�r�r�r�s&  r�!test_finally_no_exception_no_flag�ATestExceptionDetectionScenarios.test_finally_no_exception_no_flag�sN���
'�
'�(>�
?�
?�?�A�� � ��-E�F��(�(���(�O�@�
?�
?�
?�r�r2r�r+)r�r�r�r�r�rvrrzrr�r^r_r�r�r�r�r�r�r�r�r�s@rrnrn�
st�����$W#�r�?��?�:+
�Z	
��_�_����8�8�J���_�_����	�!�#L��O��	�O��_�_����8�8�J���_�_����	�!�#L��O��	�O��_�_����8�8�J���_�_����	�!�#L��	P��	�	P��_�_����8�8�J���_�_����	�!�#L��P��	�Pr rnc�`�\sQsQsnQs\Q2sQsQQks\	\
O\OQ6H9%c\%(Q2Q22s\	\
O\OQ6H9%c\%(Q2Q	22s\	\
O\OQ6H9%c\%(Q2Q
22s\	\
O\OQ6H9%c\%(Q2Q22s\	\
O\OQ6H9%c\%(Q2Q22s\	\
O\OQ6H9%c\%(Q2Q
22s\	\
O\OQ6H9%c\%(Q2Q22s\	\
O\OQ6H9%c\%(Q2Q22s\	\
O\OQ6H9%c\%(Q2Q22s\	\
O\OQ6H9%c\%(Q2Q22s\	\
O\OQ6H9%c\%(Q2Q22s\	\
O\OQ6H9%c\%(Q2Q22sQsUsP!)�TestFrameCachingi�z�Test that frame caching produces correct results.

Uses socket-based synchronization for deterministic testing.
All tests verify cache reuse via object identity checks (assertIs).
c	#�` �[2oQUQ[OU2Q0o[O29^tt^2o[
OOUQ2o[
OU2[U2o[UQU2oPo[[OU,29^tt^2nUO2vq�UO2PoQU1Qkko
RV�1w�PPP2[!V�2PPP2P!)%fhK&9h[!X�2h9h)%fhP!9h3h)z>Context manager for running a target process with socket sync.zbimport socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', z))
�
r{r|c�6:�[ROP	UQ5!)T)rc�cache_frames)rrg)r�rTs&�r�
make_unwinder�7TestFrameCaching._target_process.<locals>.make_unwinder�s���-��E�E�t�,� �r )T)rr�r�rrr�r�r�r�r/rrUr�r�r�rWrY)r��script_bodyr,r|r�rr.r�r�rhr�rTs&&         @r�_target_process� TestFrameCaching._target_process�s���� �!���!�6�"�	�������	���
�
�
!�
!�X������h��=�J��H�H�Z� �1�$�7�M�+�J��&�I�K� �M�

?�(�#�.�.�+�)F�G�G�1�'4�';�';�'=�$�M�!�'�'�)�$(�M��
�]�9�9�H�!��>�+"�
!�H�G��!��>��+"�
!�
!�s[�AE�	AD3�#D#�>4D	�2D#�:D3�
E�D 
�D 
�D#�#
D0�0D3�3E	�<E	�>	Ec
��[[2FD�o[O[	9^tt^2UO2oSFDroUOFD^oUOTt.tFDpwOjJ	ooUOU2%fJAUOttttPPP2t!	Jt	PPP2[O[2J�	P!ttoh)%fhK59h)zFGet frames containing required_funcs, with retry for transient errors.)
rT�	MAX_TRIESr�r�rrrer�r�r��issubset�timerp�RETRY_DELAY)	r�ri�required_funcsrhrur'r(r	�funcss	&&&      r�_get_frames_with_retry�'TestFrameCaching._get_frames_with_retry�s����y�!�A��$�$�&6�7�7�!�1�1�3��$�F�"(�.�.��5;�5F�5F� G�5F����5F�� G�)�2�2�5�9�9�#)�#4�#4�4�
8�7�#1�%�8�
�J�J�{�#�"���	!H�	8�7�s/�4C,	�)C'�?C,	�C,	�9C,	�'C,	�,C<
�5C<
c��[V2Po[[2FDIoUOV%2oU%c[	U2U6�cL[
O[2JK	UOU2U!)zQWait for signal, sample frames with retry until required funcs present, send ack.)	rCrTr�r�rVr�rpr��sendall)	r�r�ri�wait_signal�send_ackr��expected_framesr)rhs	&&&&&&&  r�_sample_frames�TestFrameCaching._sample_frames�sb��	��4����y�!�A��0�0��J�F��#�f�+��8���J�J�{�#�	"�
	���h�'��
r r[r�c	��QoUOU29^tt^2voooUP	Q5o.QloUOV5QQU2oUOV5QQU2oUOV5QQU2o	PPP2UOW2UOW2UOW	2UO[	U2[	U22UO[	U2[	U	22UOU]*O
U]*O
2UOU]*O
U	]*O
2[
][	U22FDFo
Vz*V�*V�*q�oUOV�QU
Q	02UOV�QU
Q
02JH	P!)%fhCKV9h)z�Test that consecutive samples reuse cached parent frame objects.

The current frame (index 0) is always re-read from memory to get
updated line numbers, so it may be a different object. Parent frames
(index 1+) should be identical objects from cache.
as            def level3():
                sock.sendall(b"sync1")
                sock.recv(16)
                sock.sendall(b"sync2")
                sock.recv(16)
                sock.sendall(b"sync3")
                sock.recv(16)

            def level2():
                level3()

            def level1():
                level2()

            level1()
            �r��sync1�ack�sync2ssync3�done�Frame z!: samples 1-2 must be same objectz!: samples 2-3 must be same object>�level1�level2�level3)r�r�rr�rVr�rT�assertIs)r�r�rTr�r�ri�expected�frames1�frames2�frames3r��f1�f2�f3s&             r�test_cache_hit_same_stack�*TestFrameCaching.test_cache_hit_same_stack�s�����$�
!�
!�+�
.�
.�3
�
���$�$�7�H�5�H��)�)���6�8��G��)�)���6�8��G��)�)���7�H��G�/�$	
���W�%����W�%����W�%�����W��s�7�|�4�����W��s�7�|�4�	
������,�,�g�a�j�.A�.A�B�������,�,�g�a�j�.A�.A�B��q�#�g�,�'�A� ��W�Z���B�B��M�M��&���#D�E�
�
�M�M��&���#D�E�
�(�;/�
.�
.�s�AF8�8G		�G		c	�L�QoUOU29^tt^2voooUP	Q5oUOV5QQQ.2oUOV5QQQ.2oUOV5QQQ.2oUOV5QQ	Q.2o	PPP2UOW2UOW2UOW2UOW	2U]*o
U]*oU]*oU	]*o
UOU
OQ2UOUOQ2UOUOQ2UOU
OQ2UOU
OOUOOQ
2UOUOOUOOQ2UOUOOU
OOQ2P!)%fhCK�9h)
z�Test that line numbers are correctly updated when execution moves within a function.

When the profiler samples at different points within the same function,
it must report the correct line number for each sample, not stale cached values.
aH            def outer():
                inner()

            def inner():
                sock.sendall(b"line_a"); sock.recv(16)
                sock.sendall(b"line_b"); sock.recv(16)
                sock.sendall(b"line_c"); sock.recv(16)
                sock.sendall(b"line_d"); sock.recv(16)

            outer()
            r�sline_ar��innersline_bsline_csline_dr�zLine B should be after line AzLine C should be after line BzLine D should be after line C)r�r�rr�r��
assertLessr�r�)r�r�rTr�r�ri�frames_a�frames_b�frames_c�frames_d�inner_a�inner_b�inner_c�inner_ds&             r�&test_line_number_updates_in_same_frame�7TestFrameCaching.test_line_number_updates_in_same_frame+s������
!�
!�+�
.�
.�3
�
���$�$�7�H��*�*���F�W�I��H��*�*���F�W�I��H��*�*���F�W�I��H��*�*���G�g�Y��H�!/�(	
���X�&����X�&����X�&����X�&��1�+���1�+���1�+���1�+������)�)�7�3�����)�)�7�3�����)�)�7�3�����)�)�7�3�	
������#�#�W�%5�%5�%<�%<�>]�	
�	
������#�#�W�%5�%5�%<�%<�>]�	
�	
������#�#�W�%5�%5�%<�%<�>]�	
�W/�
.�
.�s�A"H�H#	�H#	c
�<�QoUOU29^tt^2voooUP	Q5oUOUUQQQQ.2oUOV5QQQ.2oPPP2UOW2UOW2STt,tFDp�OMJ	o	oSTt,tFDp�OMJ	o
oUO	QU	2UO	QU	2UOQU
2UO	QU
2P!)%fhK�9httohttoh)	z>Test cache invalidation when stack shrinks (function returns).z�            def inner():
                sock.sendall(b"at_inner")
                sock.recv(16)

            def outer():
                inner()
                sock.sendall(b"at_outer")
                sock.recv(16)

            outer()
            r�sat_innerr�r��outersat_outerr��r�r�rr�rFrj)r�r�rTr�r�ri�frames_deep�frames_shallowr	�
funcs_deep�
funcs_shallows&          r�!test_cache_invalidation_on_return�2TestFrameCaching.test_cache_invalidation_on_returnrs�����
!�
!�+�
.�
.�3
�
���$�$�7�H��-�-������'�"��K�"�0�0���g��y��N�/�$	
���[�)����^�,�*5�6�+�Q�j�j�+�
�6�-;�<�^����^�
�<��
�
�g�z�*��
�
�g�z�*�����-�0��
�
�g�}�-�7/�
.��*7��<s�:D�D�D�D	�
D	c
��QoUOU29^tt^2voooUP	Q5oUOUUQQQQ.2oUOUUQQ.Q
l2oPPP2UOW2UOW2STt,tFDp�OMJ	o	oSTt,tFDp�OMJ	o
oUO	QU	2UO	QU	2UOQ	U	2UO	Q	U
2UO	QU
2UO	QU
2P!)%fhK�9httohttoh)z?Test cache invalidation when stack grows (new function called).a0            def deeper():
                sock.sendall(b"at_deeper")
                sock.recv(16)

            def middle():
                sock.sendall(b"at_middle")
                sock.recv(16)
                deeper()

            def top():
                middle()

            top()
            r�s	at_middler��middle�tops	at_deeperr��deeper>r�r�r�r�)r�r�rTr�r�ri�
frames_before�frames_afterr	�funcs_before�funcs_afters&          r�test_cache_invalidation_on_call�0TestFrameCaching.test_cache_invalidation_on_call�s/���� �
!�
!�+�
.�
.�3
�
���$�$�7�H� �/�/������5�!��M� �.�.�����+��L�/�,	
���]�+����\�*�,9�:�M�q�
�
�M��:�+7�8�<�a�z�z�<��8��
�
�h��-��
�
�e�\�*�����<�0��
�
�h��,��
�
�h��,��
�
�e�[�)�E/�
.��2;��8s�<D'�D:�!D?�'D7	�0D7	c
���QoUOU29^tt^2voooUP	Q5oUOUUQQ.Q
l2oUOUUQQ.Q
l2oPPP2UOW2UOW2QoUUQ2o	UUQ2o
UOU	2UOU
2UOU	OO
U
OO
Q	2QFDPoUVk2oUV{2o
UOV�Q
02UOV�Q02UO
V�UQ02JR	P!)%fhK�9h)zMTest that unchanged parent frames are reused from cache when top frame moves.�b            def level4():
                sock.sendall(b"sync1")
                sock.recv(16)
                sock.sendall(b"sync2")
                sock.recv(16)

            def level3():
                level4()

            def level2():
                level3()

            def level1():
                level2()

            level1()
            r�r�r��level4r�r�c�H�SFDoUOU6XfJUt!	P!rr)r)r�r	s&& r�
find_frame�=TestFrameCaching.test_partial_stack_reuse.<locals>.find_frame
s"�����:�:��)��H��r z#level4 should be at different linesz missing from sample 1z missing from sample 2z should be reused from cache>r�r�r�r�)r�r�r�)r�r�r�assertNotEqualr�r�r�)r�r�rTr�r�rir�r�r��l4_1�l4_2�namer�r�s&             r�test_partial_stack_reuse�)TestFrameCaching.test_partial_stack_reuse�sk����&�
!�
!�+�
.�
.�3
�
���$�$�7�H��)�)�����8��G��)�)�����8��G�!/�0	
���W�%����W�%�	��'�8�,���'�8�,�����T�"����T�"�����M�M� � ��M�M� � �1�	
�3�D��G�*�B��G�*�B�� � ��v�-C�%D�E�� � ��v�-C�%D�E��M�M�"�T�F�*F�"G�H�3�[/�
.�s�<E�E	�E	c	��QoUOU29^tt^2voooUP	Q5oUOV5QQQ.2oUOV5QQQ.2oPPP2UOW2UOW2[QU22oUO	U]Q	2UO	[U2[U22UO	U]*OU]*O2[][U22FD&o	UOVi*Vy*Q
U	Q02J(	P!)%fhK�9h)zETest caching with same function appearing multiple times (recursion).a.            def recurse(n):
                if n <= 0:
                    sock.sendall(b"sync1")
                    sock.recv(16)
                    sock.sendall(b"sync2")
                    sock.recv(16)
                else:
                    recurse(n - 1)

            recurse(5)
            r�r�r��recurser�r�c3�V�SF �DpOQ6XfJ]w�	J	P!3h)r�r)r3r	s& rr6�9TestFrameCaching.test_recursive_frames.<locals>.<genexpr>R
s��w���w�!�*�*�	�2I�A�A�w�s�)�)zShould have 6 recursive framesr�z&: recursive frames must be same object)	r�r�rr�r�rVr�rTr�)
r�r�rTr�r�rir�r��
recurse_countr�s
&         r�test_recursive_frames�&TestFrameCaching.test_recursive_frames,
s5�����
!�
!�+�
.�
.�3
�
���$�$�7�H��)�)���6�I�;��G��)�)���7�Y�K��G�/�	
���W�%����W�%��J�w�J�J�
������+K�L�����W��s�7�|�4�	
������,�,�g�a�j�.A�.A�B��q�#�g�,�'�A��M�M��
��
����A�B�
�(�7/�
.�s�8D=�=E
	�E
	c���QoUOU29^tt^2vooo[UQ2UP	Q5oUOU.Ql2oUP
Q5oUOU.Ql2oUOQ2PPP2UO	W2UO	W2UO[
U2[
U22ST	t,tFDp�OMJ	o
o	ST	t,tFDp�OMJ	oo	UOV�2QQ.o[[
U22FD�o
Vm*OoV�*OoVm*OQ6XcSUOUOUO1U2UOUOUO1U2J�UOV�2J�	P!)%fhCK^9htto	htto	h)	zNTest that cache_frames=True and cache_frames=False produce equivalent results.z�            def level3():
                sock.sendall(b"ready"); sock.recv(16)

            def level2():
                level3()

            def level1():
                level2()

            level1()
            rr�r�r�>r�r�r�)rr)��))
r�rCr�r�rr�rVr�rTr�rFrr)r�r�rTr�r��unwinder_cache�
frames_cached�unwinder_no_cache�frames_no_cacher	�funcs_cached�funcs_no_cache�level3_valid_colsr��
loc_cached�loc_no_caches&               r�"test_cache_vs_no_cache_equivalence�3TestFrameCaching.test_cache_vs_no_cache_equivalenceb
s������
!�
!�+�
.�
.�3
�
����]�H�5�+��=�N� �7�7�� >��M�
!.�5� A��"�9�9�!�#A��O�
�!�!�'�*�'/�*	
���]�+����_�-�	
����]�+�S��-A�B�-:�:�M�q�
�
�M��:�.=�>�o��*�*�o��>�����6�%�h�/���s�=�)�*�A�&�)�2�2�J�*�-�6�6�L���(�(�H�4��
�
��*�*�J�,E�,E�F�%���
�
�!�,�,�l�.I�.I�J�%��� � ��:�!+�Q/�
.�
.��8;��>s�AG�
G"�%G'�G	�G	c���QoUOU29^tt^2voooUP	Q5oQ.QlQ.QlQQQ.Q
QQ
.-o-o[UQ2o[]2FD�o	UOQ2vq�oUO	V�QU
802Vj*oUOV\2o
UO
U
QU
802S
Tt,tFDp�OMJ	toVz$UOQ2U	]6fJ�U[UQ2*
oJ�	UOQ2oUOQ2oUO
UQ2UO
UQ2UO	QU2UO	QU2UO	QU2UOQU2UOQU2UOQ	U2UOQ
U2UO	QU2UO	Q	U2UO	Q
U2UOQU2UOQU2UOQU2UOQU2UOQ2oUOQ
2oUO
UQ2UO
UQ2UO	QU2UO	QU2UOQUQ2UOQUQ2UOQU2UO	QU2UO	Q
U2UOQ	UQ2UOQUQ2UOQU2PPP2P!ttoh)%fhP!9h)zOTest that frame cache is per-thread and cache invalidation works independently.a=            import threading

            lock = threading.Lock()

            def sync(msg):
                with lock:
                    sock.sendall(msg + b"\n")
                    sock.recv(1)

            # Thread 1 functions
            def baz1():
                sync(b"t1:baz1")

            def bar1():
                baz1()

            def blech1():
                sync(b"t1:blech1")

            def foo1():
                bar1()  # Goes down to baz1, syncs
                blech1()  # Returns up, goes down to blech1, syncs

            # Thread 2 functions
            def baz2():
                sync(b"t2:baz2")

            def bar2():
                baz2()

            def blech2():
                sync(b"t2:blech2")

            def foo2():
                bar2()  # Goes down to baz2, syncs
                blech2()  # Returns up, goes down to blech2, syncs

            t1 = threading.Thread(target=foo1)
            t2 = threading.Thread(target=foo2)
            t1.start()
            t2.start()
            t1.join()
            t2.join()
            r�st1:baz1�baz1�bar1�foo1st2:baz2�baz2�bar2�foo2s	t1:blech1�blech1s	t2:blech2�blech2r0zUnexpected message: zThread not found for �kzMissing t1:baz1 snapshotzMissing t2:baz2 snapshotzMissing t1:blech1 snapshotzMissing t2:blech2 snapshotz)Cache not invalidated: bar1 still presentz)Cache not invalidated: baz1 still presentz)Cache not invalidated: bar2 still presentz)Cache not invalidated: baz2 still present>r
rr>rrr)r�rCrT�	partitionrFr�rr�r��getrj)r�r�rTr�r�ri�dispatch�resultsr5r��msg�sepr�r)r	�t1_baz�t2_baz�t1_blech�t2_blechs&                  r�test_cache_per_thread_isolation�0TestFrameCaching.test_cache_per_thread_isolation�
sL��,��\�
!�
!�+�
.�
.�3
�
���$�$�7�H��4��4��x��0��x��0�	�H��G�&�m�U�;�F��1�X��#)�#3�#3�E�#:� ��&��
�
�c�/C�C�7�-K�L�"*����4�4�X�N���$�$�V�/D�S�G�-L�M�4:�;�F�q�
�
�F�;����%�%�d�+��q�5��.�}�e�D�D�F��"�[�[��,�F��[�[��,�F�� � ��)C�D�� � ��)C�D�
�M�M�&�&�)��M�M�&�&�)��M�M�&�&�)����X�v�.����V�V�,����V�V�,����V�V�,�
�M�M�&�&�)��M�M�&�&�)��M�M�&�&�)����X�v�.����V�V�,����V�V�,����V�V�,��{�{�<�0�H��{�{�<�0�H�� � ��+G�H�� � ��+G�H�
�M�M�(�H�-��M�M�&�(�+������"M�
�
�����"M�
�
���X�x�0�
�M�M�(�H�-��M�M�&�(�+������"M�
�
�����"M�
�
���X�x�0�u/�
.��: <�;/�
.�
.�s+�BM�6M�M�+IM�M�M"	�M"	c	�p�QoUOU29^tt^2vooo.Q
loUP	Q5oUOV6QQU2oUP	Q5oUOV8QQU2o	PPP2UOW2UOW	2ST
t,tFDp�OMJ	oo
S	T
t,tFDp�OMJ	oo
QFD-o
UO	V�U
Q02UO	V�U
Q02J/	UO[
U2[
U	2Q	2P!)%fhK�9htto
htto
h)zITest that a new unwinder returns complete stack when cache lookup misses.r�r�r�r�r�r�z missing from first samplez missing from second samplezKNew unwinder should return complete stack despite stale last_profiled_frame>r�r�r�r�)r�r�r�r�)r�r�rr�rFr�rV)r�r�rTr�r�r��	unwinder1r��	unwinder2r�r	�funcs1�funcs2�levels&             r�0test_new_unwinder_with_stale_last_profiled_frame�ATestFrameCaching.test_new_unwinder_with_stale_last_profiled_frameAs2����&�
!�
!�+�
.�
.�3
�
���?�H�&�4�8�I��)�)��(�F�H��G�&�4�8�I��)�)��(�G�X��G�!/�(	
���W�%����W�%�&-�.�g��*�*�g��.�&-�.�g��*�*�g��.�>�E��M�M�%�E�7�2L�)M�N��M�M�%�E�7�2M�)N�O�>�
	
�����L���L�Y�	
�A/�
.��./��.s�AD�
D.�(D3�D+	�$D+	c��QoQUQ0oUOU29^tt^2voooUP	Q5oUP
Q5oUOUUQQQ.QQ	5oUOUUQ
QQ.QQ	5o	PPP2UOW2UOW	2ST
t,tFDp�OMJ	to
O	Q2oS	T
t,tFDp�OMJ	to
O	Q2oUOUQQ
2UOUQQ
2UO
[U2[U	2Q2P!)%fhK�9htto
htto
h)z�Test cache works when frame limit (1024) is exceeded.

FRAME_CACHE_MAX_FRAMES=1024. With 1100 recursive frames,
the cache can't store all of them but should still work.
iLz�import sys
sys.setrecursionlimit(2000)

def recurse(n):
    if n <= 0:
        sock.sendall(b"ready")
        sock.recv(16)  # wait for ack
        sock.sendall(b"ready2")
        sock.recv(16)  # wait for done
        return
    recurse(n - 1)

recurse(z)
r�rr�r�iN)r�sready2r���z Should have >1000 recurse framesz5Cache exhaustion should not affect stack completeness)r�r�rr�rFr�r�rV)
r��depthr�rTr�r�rrrrr	�cached_count�no_cache_counts
&            r�test_cache_exhaustion�&TestFrameCaching.test_cache_exhaustion�st����
	�
����� �
!�
!�+�
.�
.�3
�
���*��=�N� -�5� A�� �/�/������� $�
0��M�#�1�1��!����� $�
2��O�#/�4	
���]�+����_�-�-:�:�M�q�
�
�M�:�@�@��K��.=�>�o��*�*�o�>�D�D�Y�O������$� B�	
�	
����D�"D�	
�
	
����
���� �C�	
�S/�
.��<;��>s�AD7�E
�E�7E	�E	c��QoUOU29^tt^2vq#o[UOP	P	Q5o[UQ2[	U2UO2oUO
Q2PPP2,QNoSFDoUOUW2J	UOWQ*]2P!)%fhKK9h)z9Test that get_stats() returns statistics when stats=True.�I            sock.sendall(b"ready")
            sock.recv(16)
            )rc�statsrr��
total_samples)r3�frame_cache_hits�frame_cache_misses�frame_cache_partial_hits�frames_read_from_cache�frames_read_from_memory�frame_cache_hit_rate�batched_read_attempts�batched_read_successes�batched_read_misses�batched_read_segments_requested�batched_read_segments_completed�batched_read_success_rate�$batched_read_segment_completion_rate)	r�rrgrCrv�	get_statsr�rFr�)	r�r�rTr�rhrir2�
expected_keys�keys	&        r�test_get_stats�TestFrameCaching.test_get_stats�s�����
�
!�
!�+�
.�
.�2G�1�Q�%�a�e�e��T�J�H��]�H�5�
(��1��&�&�(�E��!�!�'�*�/�
�
� !�C��M�M�#�u�%�!�	
�����/��3�=/�
.�s�AB4�4C	�=C	c	�x�QoUOU29^tt^2vq#o[UOP	Q5o[UQ2UO	[
29^tt^2UO
2PPP2UOQ2PPP2P!)%fhK+9h)%fhP!9h)z;Test that get_stats() raises RuntimeError when stats=False.r1r�rr�)r�rrgrCr&r>rAr�)r�r�rTr�rhris&     r�test_get_stats_disabled_raises�/TestFrameCaching.test_get_stats_disabled_raises�s�����
�
!�
!�+�
.�
.�2G�1�Q�%����4��H�
�]�H�5��"�"�<�0�0��"�"�$�1�
�!�!�'�*�/�
.�1�0��
/�
.�
.�s0�AB(�!B	�2B(�B%
�B%
� B(�(B9	�1B9	r2�r�)r�r�r�r�r�rr�r�r�r�r^r_r�r�rr�r�r�r�r�r�r	rr'r.rDrGr�r�r�s@rr�r��s@������?��?�B��(�
�_�_������B�B�(B�$B�?��=�	��
=�~�
�_�_������B�B�(B�$B�?��@
�	��
@
�D�
�_�_������B�B�(B�$B�?��*.�	��
*.�X�
�_�_������B�B�(B�$B�?��4*�	��
4*�l�
�_�_������B�B�(B�$B�?��GI�	��
GI�R�
�_�_������B�B�(B�$B�?��/�	��
/�b�
�_�_������B�B�(B�$B�?��G;�	��
G;�R�
�_�_������B�B�(B�$B�?��J1�	��
J1�X�
�_�_������B�B�(B�$B�?��9
�	��
9
�v�
�_�_������B�B�(B�$B�?��E
�	��
E
�N�
�_�_������B�B�(B�$B�?��%4�	��
%4�N�
�_�_������B�B�(B�$B�?��+�	��
+r r��__main__rI)Or^r�r�r�rr�r#r�r�r�asynciorrrr�
unittest.mockr�test.supportrr	r
rr�test.support.import_helperr
�test.support.script_helperr�test.support.socket_helperrrL�PROFILING_MODE_WALLrGrPrUrirMrC�THREAD_STATUS_UNKNOWNrer�r�rRr>�UnicodeDecodeErrorrr�
concurrentr�ImportErrorr�_remote_debuggingrrrr�SkipTestrr/rCrIrUrYr_r�r�rarermrprv�TestCaserxr�r�r"r-rnr�r�r7r2r r�<module>rYs����	����
�
���%�=�=����5�2�7������������������$��
�	����\�+=�>���'�#���<�0�?�?���6C�'�T>K�%�P�&3����2�!������� �	$�	$��L�L�G�#�	$�	$��L�L�G�#�0�
���B�H�E�3@�4�C�<R
�x�0�0�R
�t&�'�.
�1�.
�(�.
�b&�'�P/�0�P/�(�P/�f6
�h�&7�&7�
�$&�'�H�":�H�(�H�B&�'�EP�&>�EP�(�EP�P&�'�q
+�/�q
+�(�q
+�h�z���M�M�O���Cw���L�����
�
�
�<����s*�>G�G�G�G�G�G9�%G9

Youez - 2016 - github.com/yon3zu
LinuXploit