
    0hhZF                        S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SKJ	r	  S SK
JrJrJr  S SKJr  \	R                   (       d  \ R"                  " S5      e\	R$                  " SSSS9(       a  \ R"                  " S5      eS	 r\" 5       (       d  \ R"                  " S
5      e " S S\ R(                  5      rS rS rSS.S jr " S S5      r\ R4                  " \" 5       S5      \ R4                  " \" 5       S5       " S S\ R(                  \5      5       5       rS r\ R4                  " \" 5       S5      \ R4                  " \" SS5      S5       " S S\ R(                  \5      5       5       r\S:X  a  \ R>                  " 5         gg)    N)support)make_scriptassert_python_failureassert_python_ok)temp_dirztest module requires subprocessT)addressmemoryubz,test crash randomly on ASAN/MSAN/UBSAN buildc                  Z    [         R                  " S5      n U (       d  g[        U 5      S:H  $ )NPY_HAVE_PERF_TRAMPOLINEF   )	sysconfigget_config_varint)perf_trampolines    @/opt/python-3.13.8/usr/lib/python3.13/test/test_perf_profiler.pysupports_trampoline_profilingr      s)    ../HIO1$$    z'perf trampoline profiling not supportedc                   \   ^  \ rS rSrU 4S jrSU 4S jjrS rS rS rS r	S r
S	 rS
rU =r$ )TestPerfTrampoline&   c                    > [         TU ]  5         [        [        R                  " S5      R                  S5      5      U l        g N/tmp/z
perf-*.mapsupersetUpsetpathlibPathglob
perf_filesself	__class__s    r   r   TestPerfTrampoline.setUp'   ,    gll7388FGr   c                    > [         TU ]  5         [        [        R                  " S5      R                  S5      5      U R                  -
  nU H  nUR                  5         M     g r   r   tearDownr   r   r    r!   r"   unlinkr$   files_to_deletefiler%   s      r   r*   TestPerfTrampoline.tearDown+   M    W%**<89DOOK 	 $DKKM $r   c                   ^ Sn[        5        n[        USU5      n[        R                  " [        R
                  SU/S[        R                  [        R                  S9 nUR                  5       u  pVS S S 5        S S S 5        U R                  WS5        U R                  WS5        [        R                  " SWR                   S35      nU R                  UR                  5       5        UR                  5       nUR                  5       n	S	W 3S
U 3SU 3/n
U
 H  m[!        U4S jU	 5       S 5      nU R#                  UST S35        UR%                  S5      S   nU R'                  UR)                  S5      S5        U R                  [+        U5      R-                  [.        R0                  5      S5        M     g ! , (       d  f       GNO= f! , (       d  f       GNY= f)Nzif 1:
                def foo():
                    pass

                def bar():
                    foo()

                def baz():
                    bar()

                baz()
                perftest-XperfTtextstderrstdout 
/tmp/perf-.mappy::foo:py::bar:py::baz:c              3   8   >#    U  H  nTU;   d  M  Uv   M     g 7fN ).0lineexpected_symbols     r   	<genexpr>;TestPerfTrampoline.test_trampoline_works.<locals>.<genexpr>X   s     H*$40G*s   
	zCould not find z in perf file r   0xz&Address should not be prefixed with 0xz*Address should contain only hex characters)r   r   
subprocessPopensys
executablePIPEcommunicateassertEqualr   r    pid
assertTrueexists	read_text
splitlinesnextassertIsNotNonesplitassertFalse
startswithr   issubsetstring	hexdigits)r$   code
script_dirscriptprocessr7   r6   	perf_fileperf_file_contents
perf_linesexpected_symbols	perf_line	perf_addrrC   s                @r   test_trampoline_works(TestPerfTrampoline.test_trampoline_works3   s    Z: Z>F!!62!!	
 !(!4!4!6  	$$LL:gkk]$!?@		((*+&002'224
vhvhvh

  0OH*H$I   __,=]K ",Q/I$$T*,T OOI''(8(89<  0)  Zs$   AG F;3G;
G
	G
Gc                    Sn[        5        n[        USU5      n[        R                  " [        R
                  SU/S[        R                  [        R                  S9 nUR                  5       u  pVS S S 5        S S S 5        U R                  WR                  S5        U R                  WS5        [        WR                  5       5      n[        R                  " SUR                   S	35      n[        R                  " SU S	35      n	U R                  UR!                  5       5        U R                  U	R!                  5       5        UR#                  5       n
U R%                  S
W 3U
5        U R%                  SU 3U
5        U R%                  SU 3U
5        U	R#                  5       nU R%                  SU 3U5        U R%                  SU 3U5        U R%                  SU 3U5        g ! , (       d  f       GNy= f! , (       d  f       GN= f)Na  if 1:
                import os, sys

                def foo_fork():
                    pass

                def bar_fork():
                    foo_fork()

                def baz_fork():
                    bar_fork()

                def foo():
                    pid = os.fork()
                    if pid == 0:
                        print(os.getpid())
                        baz_fork()
                    else:
                        _, status = os.waitpid(-1, 0)
                        sys.exit(status)

                def bar():
                    foo()

                def baz():
                    bar()

                baz()
                r2   r3   Tr4   r   r8   r9   r:   r;   r<   r=   py::foo_fork:py::bar_fork:zpy::baz_fork:)r   r   rH   rI   rJ   rK   rL   rM   rN   
returncoder   stripr   r    rO   rP   rQ   rR   assertIn)r$   r\   r]   r^   r_   r7   r6   	child_pidr`   perf_child_filera   child_perf_file_contentss               r    test_trampoline_works_with_forks3TestPerfTrampoline.test_trampoline_works_with_forksf   s   : Z: Z>F!!62!!	
 !(!4!4!6  	++Q/$'	LL:gkk]$!?@	!,,I;d'CD	((*+..01&002)+=>)+=>)+=>#2#<#<#> fX.0HIfX.0HIfX.0HI1  Zs$   AG6G$2G6$
G3	.G66
Hc                    Sn[        5        n[        USU5      n[        R                  " [        R
                  U/S[        R                  [        R                  S9 nUR                  5       u  pVS S S 5        S S S 5        U R                  WS5        U R                  WS5        [        R                  " SWR                   S35      nU R                  UR                  5       5        UR                  5       nU R                  SW 3U5        U R!                  S	U 3U5        U R!                  S
U 3U5        U R!                  SU 3U5        g ! , (       d  f       N= f! , (       d  f       N= f)Na  if 1:
                import sys
                def foo():
                    pass

                def spam():
                    pass

                def bar():
                    sys.deactivate_stack_trampoline()
                    foo()
                    sys.activate_stack_trampoline("perf")
                    spam()

                def baz():
                    bar()

                sys.activate_stack_trampoline("perf")
                baz()
                r2   Tr4   r8   r9   r:   r;   z	py::spam:r<   r=   )r   r   rH   rI   rJ   rK   rL   rM   rN   r   r    rO   rP   rQ   rR   assertNotInrm   )	r$   r\   r]   r^   r_   r7   r6   r`   ra   s	            r   test_sys_apiTestPerfTrampoline.test_sys_api   s8   ( Z: Z>F!!(!!	
 !(!4!4!6  	$$LL:gkk]$!?@		((*+&0028F8,.@A	&*,>?)+=>)+=>#  Zs$   AEE1E
E	E
E,c                      Sn[        SU5        g )Nzif 1:
                import sys
                sys.activate_stack_trampoline("perf")
                sys.activate_stack_trampoline("perf")
                -cr   r$   r\   s     r   %test_sys_api_with_existing_trampoline8TestPerfTrampoline.test_sys_api_with_existing_trampoline   s    
 	t$r   c                 f    Sn[        SU5      u  p#nU R                  SUR                  5       5        g )Nzjif 1:
                import sys
                sys.activate_stack_trampoline("invalid")
                rx   zinvalid backend: invalid)r   rm   decode)r$   r\   rcouterrs        r   $test_sys_api_with_invalid_trampoline7TestPerfTrampoline.test_sys_api_with_invalid_trampoline   s0     -T480#**,?r   c                      Sn[        SU5        g )Na  if 1:
                import sys
                sys.activate_stack_trampoline("perf")
                assert sys.is_stack_trampoline_active() is True
                sys.deactivate_stack_trampoline()
                assert sys.is_stack_trampoline_active() is False
                rx   ry   rz   s     r   test_sys_api_get_status*TestPerfTrampoline.test_sys_api_get_status   s     	t$r   r"   returnN)__name__
__module____qualname____firstlineno__r   r*   rf   rq   ru   r{   r   r   __static_attributes____classcell__r%   s   @r   r   r   &   s6    H1f8Jt(?T%@% %r   r   c                  `    [         R                  " S5      n U (       d  gSU ;   =(       a    SU ;  $ )NPY_CORE_CFLAGSFzno-omit-frame-pointer_Py_JIT)r   r   )cflagss    r   )is_unwinding_reliable_with_frame_pointersr      s.    %%&67F"f,H&1HHr   c                      SS/n [         R                  " U SS9nSU;  a  g[	        5        n US-   nSSS	S
SSSUS[
        R                  SS4n [         R                  " XS[         R                  S9nSU;  a
   S S S 5        g S S S 5        g! [         R                  [        4 a     gf = f! [         R                  [        4 a     S S S 5        gf = f! , (       d  f       g= f)Nperfz--helpTr5   Fz	perf.data/perf_output.perfrecord--no-buildid--no-buildid-cache-g--call-graph=fp-o--rx   zprint("hello"))cwdr5   r6   hello)rH   check_outputSubprocessErrorOSErrorr   rJ   rK   STDOUT)cmdr7   r]   output_files       r   perf_command_worksr      s   x ((48 &  
z	$'::K$! C  ,,$z7H7HF & 1 
. !/ 
4 G &&0 : **G4 	+ 
(	) 
4 s@   B CAB-3CB*)B*-CCCC
C#Fuse_jitc                   U(       a0  [         R                  R                  5       nUR                  U5        OS nU S-   nU(       d  SSSSSSSUS	4	nOSSSSSS
SSSUS	4n[        R
                  " Xb-   [        R                  [        R                  USS9nUR                  (       a:  [        UR                  [        R                  S9  [        SUR                   35      eU(       a  U S-   nSSSSUSU4n	[        R
                  " U	[        R                  [        R                  USS9nUR                  (       a:  [        UR                  [        R                  S9  [        SUR                   35      e[         R                  " X5        Sn[        R
                  " SSSU4[        R                  [        R                  USSS9nUR                  UR                  4$ )Nr   r   r   r   r   r   r   r   r   z--call-graph=dwarf,65528z-F99z-k1T)r7   r6   envr5   )r.   zPerf failed with return code z/jit_output.dumpinjectz-jz-i)r6   r7   r   r5   )r   r^   r^   )r7   r6   r   checkr5   )osenvironcopyupdaterH   runrL   rk   printr6   rJ   
ValueErrorrenamer7   )
r   r   argsenv_varsr   r   base_cmdprocjit_output_filecommands
             r   run_perfr     s   jjoo

8++K +	
  &
 >>D dkk

+88IJKK 228T4dOT~~JOOJOOSW
 ??$++CJJ/<T__<MNOO
		//!H>>	4-D ;;##r   c                   &    \ rS rSrS rS rS rSrg)TestPerfProfilerMixiniY  c                     [        5       er?   )NotImplementedError)r$   r]   	perf_moder^   s       r   r   TestPerfProfilerMixin.run_perfZ  s    !##r   c                 2   [        5        nSn[        USU5      nU R                  X5      u  pEU R                  US5        U R	                  SU 3U5        U R	                  SU 3U5        U R	                  SU 3U5        S S S 5        g ! , (       d  f       g = f)N!  if 1:
                def foo(n):
                    x = 0
                    for i in range(n):
                        x += i

                def bar(n):
                    foo(n)

                def baz(n):
                    bar(n)

                baz(10000000)
                r2   r8   r;   r<   r=   )r   r   r   rN   rm   r$   r]   r\   r^   r7   r6   s         r   7test_python_calls_appear_in_the_stack_if_perf_activatedMTestPerfProfilerMixin.test_python_calls_appear_in_the_stack_if_perf_activated]  s    Z:D !Z>F!]]:>NFVR(MMHVH-v6MMHVH-v6MMHVH-v6+ ZZs   A4B
Bc                 0   [        5        nSn[        USU5      nU R                  XSS9u  pEU R                  US5        U R	                  SU 3U5        U R	                  SU 3U5        U R	                  SU 3U5        S S S 5        g ! , (       d  f       g = f)	Nr   r2   F)activate_trampoliner8   r;   r<   r=   )r   r   r   rN   rt   r   s         r   @test_python_calls_do_not_appear_in_the_stack_if_perf_deactivatedVTestPerfProfilerMixin.test_python_calls_do_not_appear_in_the_stack_if_perf_deactivatedu  s    Z:D !Z>F!]] + NF VR(xx0&9xx0&9xx0&9/ ZZs   A3B
Br@   N)r   r   r   r   r   r   r   r   r@   r   r   r   r   Y  s    $70:r   r   zperf command doesn't workz+Unwinding is unreliable with frame pointersc                   H   ^  \ rS rSrSS jrU 4S jrSU 4S jjrS rSrU =r	$ )	TestPerfProfileri  c                 ~    U(       a  [        U[        R                  SU5      $ [        U[        R                  U5      $ )Nr3   r   rJ   rK   r$   r]   r^   r   s       r   r   TestPerfProfiler.run_perf  s-    J&II
CNNF;;r   c                    > [         TU ]  5         [        [        R                  " S5      R                  S5      5      U l        g r   r   r#   s    r   r   TestPerfProfiler.setUp  r'   r   c                    > [         TU ]  5         [        [        R                  " S5      R                  S5      5      U R                  -
  nU H  nUR                  5         M     g r   r)   r,   s      r   r*   TestPerfProfiler.tearDown  r0   r   c                    Sn[        5        n[        USU5      n[        R                  " [        R
                  SU/S[        R                  [        R                  S9 nUR                  5       u  pVS S S 5        S S S 5        U R                  WR                  S5        U R                  SW5        [        WR                  5       5      n[        R                  " SUR                   S	35      n[        R                  " SU S	35      n	U R!                  UR#                  5       5        U R!                  U	R#                  5       5        UR%                  5       n
U R'                  S
W 3U
5        U R'                  SU 3U
5        U R'                  SU 3U
5        U R'                  SU 3U
5        U	R%                  5       nU R'                  SU 3U5        U R'                  SU 3U5        U
R)                  S5      nU H(  nSU 3U;   d  SU 3U;   d  M  U R'                  X5        M*     g ! , (       d  f       GN= f! , (       d  f       GN= f)Na  if 1:
                import sys
                import os
                import sysconfig
                from _testinternalcapi import (
                    compile_perf_trampoline_entry,
                    perf_trampoline_set_persist_after_fork,
                )

                def foo_fork():
                    pass

                def bar_fork():
                    foo_fork()

                def foo():
                    import time; time.sleep(1)

                def bar():
                    foo()

                def compile_trampolines_for_all_functions():
                    perf_trampoline_set_persist_after_fork(1)
                    for _, obj in globals().items():
                        if callable(obj) and hasattr(obj, '__code__'):
                            compile_perf_trampoline_entry(obj.__code__)

                if __name__ == "__main__":
                    compile_trampolines_for_all_functions()
                    pid = os.fork()
                    if pid == 0:
                        print(os.getpid())
                        bar_fork()
                    else:
                        bar()
                r2   r3   T)universal_newlinesr6   r7   r   zError:r9   r:   r;   r<   ri   rj   
)r   r   rH   rI   rJ   rK   rL   rM   rN   rk   rt   r   rl   r   r    rO   rP   rQ   rR   rm   rV   )r$   r\   r]   r^   r_   r7   r6   rn   r`   ro   ra   rp   perf_file_linesrB   s                 r   test_pre_fork_compile&TestPerfProfiler.test_pre_fork_compile  s   #J Z: Z>F!!62#'!!	
 !(!4!4!6  	++Q/6*'	LL:gkk]$!?@	!,,I;d'CD	((*+..01&002)+=>)+=>fX.0BCfX.0BC#2#<#<#> fX.0HIfX.0HI -2248#Dvh'4/]6(3Kt3Sd= $;  Zs$   AH5H#2H5#
H2	-H55
Ir   Tr   )
r   r   r   r   r   r   r*   r   r   r   r   s   @r   r   r     s    <
HG> G>r   r   c                 0    [         R                  " SS/SS9nUR                  5       S   nUR                  S5      S   nUR                  S	5      n[        [        [        US S 5      5      nX0U4:  $ ! [         R                  [        [        4 a     gf = f)
Nr   z	--versionTr   F   -r   .)	rH   r   CalledProcessErrorFileNotFoundErrorPermissionErrorrV   tuplemapr   )majorminoroutputversions       r   _is_perf_vesion_at_leastr     s    ((&+)>TJ llnQGmmC #GmmC GCWRa[)*Gen$$ ))+<oN s   A3 3BB   z+perf command may not work due to a perf bugc                   B   ^  \ rS rSrSS jrU 4S jrSU 4S jjrSrU =r$ )TestPerfProfilerWithDwarfi  c                 z    U(       a  [        U[        R                  SUSS9$ [        U[        R                  USS9$ )Nz
-Xperf_jitTr   r   r   s       r   r   "TestPerfProfilerWithDwarf.run_perf  s8    CNNL&$  
CNNFDIIr   c                 
  > [         TU ]  5         [        [        R                  " S5      R                  S5      5      U l        U =R                  [        [        R                  " S5      R                  S5      5      -  sl        g Nr   z	jit*.dumpzjitted-*.sor   r#   s    r   r   TestPerfProfilerWithDwarf.setUp  sS    gll7388EF3w||G499-HIIr   c                 .  > [         TU ]  5         [        [        R                  " S5      R                  S5      5      nU[        [        R                  " S5      R                  S5      5      -  nXR                  -
  nU H  nUR                  5         M     g r   r)   r,   s      r   r*   "TestPerfProfilerWithDwarf.tearDown  sn    gll7388EF3w||G499-HII)OO;#DKKM $r   r   r   r   )	r   r   r   r   r   r   r*   r   r   r   s   @r   r   r     s    JJ
 r   r   __main__) unittestrZ   rH   rJ   r   r   r   shutiltestr   test.support.script_helperr   r   r   test.support.os_helperr   has_subprocess_supportSkipTestcheck_sanitizerr   TestCaser   r   r   r   r   
skipUnlessr   r   r   r   mainr@   r   r   <module>r     s      
  	    
 , %%


=
>>
4> 

J
KK% %&&


E
FF|%** |%~I'T "' @$F4: 4:l 
')+FG	-/1Y>x((*? Y>	 H
Y>x%$ 
')+FG	-a35bc 1 13H  d H, zMMO r   