
    2hh;                     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  S SKJ	r	J
r
  \R                  " S5      r\R                  " S5      r\" 5        " S S\R                  5      5       r\R                   " 5        " S	 S
\5      5       r\R$                  " \R&                  " 5       S5       " S S\5      5       r\R$                  " \R*                  " 5       S5       " S S\5      5       r\R$                  " \R.                  S5       " S S\5      5       r\S:X  a  \R4                  " 5         gg)    N)support)import_helperrequires_subprocess)assert_python_failureassert_python_ok	_testcapi_testinternalcapic                       \ rS rSrSrSrS rS rS rS r	S r
S	 rS
 rS rS rS rS r\R$                  " \R(                  S5      S 5       rSrg)PyMemDebugTests   debugz(?:0x)?[0-9a-fA-F]+c                     [         R                  " 5          [        SUU R                  SS9nS S S 5        WR                  nUR                  SS5      $ ! , (       d  f       N,= f)N-c
junk:falsePYTHONMALLOCMALLOC_CONFasciireplace)r   SuppressCrashReportr   r   errdecode)selfcodeoutstderrs       @/opt/python-3.13.8/usr/lib/python3.13/test/test_capi/test_mem.pycheckPyMemDebugTests.check   sU    ((*'d!.. )C + }}Wi00 +*s   A
A!c                     U R                  S5      nSnUR                  U R                  S9n[        R                  " U[        R
                  S9nU R                  X5        g )Nz3import _testcapi; _testcapi.pymem_buffer_overflow()a6  Debug memory block at address p={ptr}: API 'm'\n    16 bytes originally requested\n    The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n    The [0-9] pad bytes at tail={ptr} are not all FORBIDDENBYTE \(0x[0-9a-f]{{2}}\):\n        at tail\+0: 0x78 \*\*\* OUCH\n        at tail\+1: 0xfd\n        at tail\+2: 0xfd\n        .*\n(    The block was made by call #[0-9]+ to debug malloc/realloc.\n)?    Data at p: cd cd cd .*\n\nEnable tracemalloc to get the memory block allocation traceback\n\nFatal Python error: _PyMem_DebugRawFree: bad trailing pad byteptr)flags)r   format	PTR_REGEXrecompileDOTALLassertRegexr   r   regexs      r   test_buffer_overflow$PyMemDebugTests.test_buffer_overflow"   sQ    jjNOS 0

5		2$    c                 ~    U R                  S5      nSnUR                  U R                  S9nU R                  X5        g )Nz.import _testcapi; _testcapi.pymem_api_misuse()a  Debug memory block at address p={ptr}: API 'm'\n    16 bytes originally requested\n    The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n    The [0-9] pad bytes at tail={ptr} are FORBIDDENBYTE, as expected.\n(    The block was made by call #[0-9]+ to debug malloc/realloc.\n)?    Data at p: cd cd cd .*\n\nEnable tracemalloc to get the memory block allocation traceback\n\nFatal Python error: _PyMem_DebugRawFree: bad ID: Allocated using API 'm', verified using API 'r'\nr!   )r   r$   r%   r)   r*   s      r   test_api_misusePyMemDebugTests.test_api_misuse6   s=    jjIJ	w 0$r.   c                 L    U R                  U5      nSnU R                  X25        g )Nz^Fatal Python error: _PyMem_DebugMalloc: Python memory allocator called without holding the GIL)r   assertIn)r   r   r   expecteds       r   check_malloc_without_gil(PyMemDebugTests.check_malloc_without_gilE   s$    jjMh$r.   c                 *    SnU R                  U5        g )Nz6import _testcapi; _testcapi.pymem_malloc_without_gil()r5   r   r   s     r   test_pymem_malloc_without_gil-PyMemDebugTests.test_pymem_malloc_without_gilK   s     H%%d+r.   c                 *    SnU R                  U5        g )Nz9import _testcapi; _testcapi.pyobject_malloc_without_gil()r8   r9   s     r    test_pyobject_malloc_without_gil0PyMemDebugTests.test_pyobject_malloc_without_gilQ   s     K%%d+r.   c                 d    [         R                  " SU S35      n[        SUU R                  SS9  g )Nz
            import gc, os, sys, _testinternalcapi
            # Disable the GC to avoid crash on GC collection
            gc.disable()
            _testinternalcapi.z()
            # Exit immediately to avoid a crash while deallocating
            # the invalid object
            os._exit(0)
        r   r   r   )textwrapdedentr   r   )r   	func_namer   s      r   check_pyobject_is_freed'PyMemDebugTests.check_pyobject_is_freedW   sA     $  )k *		   	$**$	
r.   c                 &    U R                  S5        g )Ncheck_pyobject_null_is_freedrC   r   s    r   test_pyobject_null_is_freed+PyMemDebugTests.test_pyobject_null_is_freedg   s    $$%CDr.   c                 &    U R                  S5        g )N%check_pyobject_uninitialized_is_freedrG   rH   s    r   $test_pyobject_uninitialized_is_freed4PyMemDebugTests.test_pyobject_uninitialized_is_freedj   s    $$%LMr.   c                 &    U R                  S5        g )N'check_pyobject_forbidden_bytes_is_freedrG   rH   s    r   &test_pyobject_forbidden_bytes_is_freed6PyMemDebugTests.test_pyobject_forbidden_bytes_is_freedm   s    $$%NOr.   c                 &    U R                  S5        g )Ncheck_pyobject_freed_is_freedrG   rH   s    r   test_pyobject_freed_is_freed,PyMemDebugTests.test_pyobject_freed_is_freedp   s    $$%DEr.   zcannot test Py_TRACE_REFS buildc                 &   Sn[        SU5      u  p#nUR                  5       n[        US5       H`  u  pgU R                  SU5        UR	                  S5      Gt p[        U	5      n	U R                  XS-  5        U R                  XS-  S-
  5        Mb     g )Na*  if 1:
            import _testcapi

            class C(): pass

            # The first loop tests both functions and that remove_mem_hooks()
            # can be called twice in a row. The second loop checks a call to
            # set_nomemory() after a call to remove_mem_hooks(). The third
            # loop checks the start and stop arguments of set_nomemory().
            for outer_cnt in range(1, 4):
                start = 10 * outer_cnt
                for j in range(100):
                    if j == 0:
                        if outer_cnt != 3:
                            _testcapi.set_nomemory(start)
                        else:
                            _testcapi.set_nomemory(start, start + 1)
                    try:
                        C()
                    except MemoryError as e:
                        if outer_cnt != 3:
                            _testcapi.remove_mem_hooks()
                        print('MemoryError', outer_cnt, j)
                        _testcapi.remove_mem_hooks()
                        break
        r      s   MemoryError    
      )r   
splitlines	enumerater3   splitintassertLessEqualassertGreaterEqual)
r   r   rcr   r   linesiline_counts
             r   test_set_nomemory!PyMemDebugTests.test_set_nomemoryu   s    4 (d3  *GAMM.#.

4(IQJE  "-##ER462 +r.    N)__name__
__module____qualname____firstlineno__r   r%   r   r,   r0   r5   r:   r=   rC   rI   rM   rQ   rU   unittestskipIfr   Py_TRACE_REFSrh   __static_attributes__rj   r.   r   r   r      sn    L&I
1%(%%,,
 ENPF
 __W**,MN"3 O"3r.   r   c                       \ rS rSrSrSrg)PyMemMallocDebugTests   malloc_debugrj   Nrk   rl   rm   rn   r   rr   rj   r.   r   rt   rt      s    !Lr.   rt   zneed pymallocc                       \ rS rSrSrSrg)PyMemPymallocDebugTests   pymalloc_debugrj   Nrw   rj   r.   r   ry   ry          #Lr.   ry   zneed mimalocc                       \ rS rSrSrSrg)PyMemMimallocDebugTests   mimalloc_debugrj   Nrw   rj   r.   r   r~   r~      r|   r.   r~   zneed Py_DEBUGc                       \ rS rSrSrSrg)PyMemDefaultTests    rj   Nrw   rj   r.   r   r   r      s	     Lr.   r   __main__)r&   r@   ro   testr   test.supportr   r   test.support.script_helperr   r   import_moduler   r	   TestCaser   requires_gil_enabledrt   
skipUnlesswith_pymallocry   with_mimallocr~   Py_DEBUGr   rk   mainrj   r.   r   <module>r      s/   	    ; N
 ''4	!//0CD G3h'' G3 G3V 	"O "  " 
W**,o>$o $ ?$ 
W**,n=$o $ >$ 
W%%7  8
 zMMO r.   