
    daf}                        d dl Z d dlZd dlZd dlmZ d dlmZmZ d dlm	Z	m
Z
  ej                  d      Z e        G d dej                               Z G d d	e      Z ej                    ej"                         d
       G d de             Z ej                   ej&                  d       G d de             Zedk(  r ej,                          yy)    N)support)import_helperrequires_subprocess)assert_python_failureassert_python_ok	_testcapic                   \    e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zy)PyMemDebugTestsdebugz(?:0x)?[0-9a-fA-F]+c                     t        j                         5  t        d|| j                  d      }d d d        j                  }|j                  dd      S # 1 sw Y   'xY w)N-c
junk:falsePYTHONMALLOCMALLOC_CONFasciireplace)r   SuppressCrashReportr   r   errdecode)selfcodeoutstderrs       2/root/Python-3.12.4/Lib/test/test_capi/test_mem.pycheckzPyMemDebugTests.check   s\    ((* 	'd!.. )C	 }}Wi00	 	s   AAc                     | j                  d      }d}|j                  | j                        }t        j                  |t        j
                        }| j                  ||       y )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_overflowz$PyMemDebugTests.test_buffer_overflow    sS    jjNOS 0

5		2e$    c                     | j                  d      }d}|j                  | j                        }| j                  ||       y )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_misusezPyMemDebugTests.test_api_misuse4   s?    jjIJ	w 0e$r*   c                 N    | j                  |      }d}| j                  ||       y )Nz^Fatal Python error: _PyMem_DebugMalloc: Python memory allocator called without holding the GIL)r   assertIn)r   r   r   expecteds       r   check_malloc_without_gilz(PyMemDebugTests.check_malloc_without_gilC   s&    jjMh$r*   c                 *    d}| j                  |       y )Nz6import _testcapi; _testcapi.pymem_malloc_without_gil()r0   r   r   s     r   test_pymem_malloc_without_gilz-PyMemDebugTests.test_pymem_malloc_without_gilI   s     H%%d+r*   c                 *    d}| j                  |       y )Nz9import _testcapi; _testcapi.pyobject_malloc_without_gil()r2   r3   s     r    test_pyobject_malloc_without_gilz0PyMemDebugTests.test_pyobject_malloc_without_gilO   s     K%%d+r*   c                 h    t        j                  d| d      }t        d|| j                  d       y )Nz
            import gc, os, sys, _testcapi
            # Disable the GC to avoid crash on GC collection
            gc.disable()
            try:
                _testcapi.z()
                # Exit immediately to avoid a crash while deallocating
                # the invalid object
                os._exit(0)
            except _testcapi.error:
                os._exit(1)
        r   r   r   )textwrapdedentr   r   )r   	func_namer   s      r   check_pyobject_is_freedz'PyMemDebugTests.check_pyobject_is_freedU   sA     $
 %+ &	   	$**$	
r*   c                 &    | j                  d       y )Ncheck_pyobject_null_is_freedr;   r   s    r   test_pyobject_null_is_freedz+PyMemDebugTests.test_pyobject_null_is_freedh   s    $$%CDr*   c                 &    | j                  d       y )N%check_pyobject_uninitialized_is_freedr>   r?   s    r   $test_pyobject_uninitialized_is_freedz4PyMemDebugTests.test_pyobject_uninitialized_is_freedk   s    $$%LMr*   c                 &    | j                  d       y )N'check_pyobject_forbidden_bytes_is_freedr>   r?   s    r   &test_pyobject_forbidden_bytes_is_freedz6PyMemDebugTests.test_pyobject_forbidden_bytes_is_freedn   s    $$%NOr*   c                 &    | j                  d       y )Ncheck_pyobject_freed_is_freedr>   r?   s    r   test_pyobject_freed_is_freedz,PyMemDebugTests.test_pyobject_freed_is_freedq   s    $$%DEr*   c                 ,   d}t        d|      \  }}}|j                         }t        |d      D ]c  \  }}| j                  d|       |j	                  d      ^ }}	t        |	      }	| j                  |	|dz         | j                  |	|dz  dz
         e y )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	enumerater.   splitintassertLessEqualassertGreaterEqual)
r   r   rcr   r   linesiline_counts
             r   test_set_nomemoryz!PyMemDebugTests.test_set_nomemoryt   s    4 (d3C  * 	2GAtMM.#.

4(IQJE  !,##E1Q3q51	2r*   N)__name__
__module____qualname__r   r"   r   r)   r,   r0   r4   r6   r;   r@   rC   rF   rI   r[    r*   r   r
   r
      sL    L&I
1%(%%,,
&ENPF"2r*   r
   c                       e Zd ZdZy)PyMemMallocDebugTestsmalloc_debugNr\   r]   r^   r   r_   r*   r   ra   ra      s    !Lr*   ra   zneed pymallocc                       e Zd ZdZy)PyMemPymallocDebugTestspymalloc_debugNrc   r_   r*   r   re   re      s    #Lr*   re   zneed Py_DEBUGc                       e Zd ZdZy)PyMemDefaultTests Nrc   r_   r*   r   rh   rh      s	     Lr*   rh   __main__)r#   r8   unittesttestr   test.supportr   r   test.support.script_helperr   r   import_moduler   TestCaser
   ra   
skipUnlesswith_pymallocre   Py_DEBUGrh   r\   mainr_   r*   r   <module>ru      s    	    ; N (M''4	G2h'' G2 G2T"O " *W**,o>$o $ ?$ W%%7  8
 zHMMO r*   