B
    u9aïo  ã               @   s:  d dl mZ d dlZd dlZd dlZd dlZ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Zd dlZd dlZd dlmZ yd dlZW n ek
r¨   dZY nX dZejdkZe d¡pÄd	Ze d
¡pÒd	ZdekpâdekZdekpòdekZddd„Zdd„ Zedd„ ƒZG dd„ dej ƒZ!e"dkr6e #¡  dS )é    )ÚcontextmanagerN)Úsupport)Úscript_helperÚ
is_android)Údedentg      à?ÚntZCFLAGSÚ ZCONFIG_ARGSz-fsanitize=undefinedz#--with-undefined-behavior-sanitizerz-fsanitize=memoryz--with-memory-sanitizeré   c             C   sL   |}|d|  7 }|d| 7 }d|k r<d|d |d   | S d| d S d S )Nz#  File "<string>", line %s in func
z&  File "<string>", line %s in <module>r	   ú^Ú
ú$© )Zlineno1Zlineno2ÚheaderÚ	min_countÚregexr   r   ú'/usr/lib/python3.7/test_faulthandler.pyÚexpected_traceback#   s    r   c             C   s   t  td¡| ƒS )Nz(raising SIGSEGV on Android is unreliable)ÚunittestÚskipIfr   )Útestr   r   r   Úskip_segfault_on_android,   s    r   c           	   c   s$   t  ¡ } z
| V  W d t | ¡ X d S )N)ÚtempfileZmktempr   Úunlink)Úfilenamer   r   r   Útemporary_filename1   s    
r   c               @   sB  e Zd Zddd„Zddddddœdd„Zdd	„ Zd
d„ Ze e	j
 d¡d¡dd„ ƒZedd„ ƒZdd„ Zdd„ Ze e	j
dkd¡dd„ ƒZe edkd¡e eedƒd¡edd„ ƒƒƒZe edkd¡e eedƒd ¡ed!d"„ ƒƒƒZd#d$„ Zd%d&„ Ze e	j
 d'¡d(¡e eed)ƒ d*¡d+d,„ ƒƒZed-d.„ ƒZe ep>ed/¡ed0d1„ ƒƒZe e	j
dkd2¡e epled/¡ed3d4„ ƒƒƒZ ed5d6„ ƒZ!ed7d8„ ƒZ"d9d:„ Z#d;d<„ Z$d=d>„ Z%d?d@„ Z&dddAœdBdC„Z'dDdE„ Z(dFdG„ Z)e e	j
dkd2¡dHdI„ ƒZ*dJdK„ Z+dLdM„ Z,dNdO„ Z-dPdQ„ Z.e eedRƒ dS¡d‚dddAœdVdW„ƒZ/dXdY„ Z0dZd[„ Z1d\d]„ Z2d^d_„ Z3e e	j
dkd2¡d`da„ ƒZ4dbdc„ Z5e eeddƒ de¡dƒdfdg„ƒZ6dhdi„ Z7djdk„ Z8dldm„ Z9e e	j
dkd2¡dndo„ ƒZ:dpdq„ Z;drds„ Z<e=dtdu„ ƒZ>dvdw„ Z?e e@dx¡dydz„ ƒZAe e@dx¡d{d|„ ƒZBe e@dx¡d}d~„ ƒZCe e@dx¡dd€„ ƒZDdS )„ÚFaultHandlerTestsNc          
   C   s  t |ƒ ¡ }g }|dk	r"| |¡ t ¡ : tjd||d}| | ¡ \}}| ¡ }W dQ R X W dQ R X t 	|¡}	|	 
dd¡}	|r¼|  |	d¡ t|dƒ}
|
 ¡ }	W dQ R X |	 
dd¡}	nT|dk	r|  |	d¡ t |tjd¡ t|dd	d
}
|
 ¡ }	W dQ R X |	 
dd¡}	|	 ¡ |fS )a{  
        Run the specified code in Python (in a new child process) and read the
        output from the standard error or from a file (if filename is set).
        Return the output lines as a list.

        Strip the reference count from the standard error for Python debug
        build, and replace "Current thread 0x00007f8d8fbd9700" by "Current
        thread XXX".
        Nz-c)Úpass_fdsÚasciiÚbackslashreplacer   Úrbr   F)Úclosefd)r   ÚstripÚappendr   ZSuppressCrashReportr   Zspawn_pythonZcommunicateÚwaitZstrip_python_stderrÚdecodeÚassertEqualÚopenÚreadÚosÚlseekÚSEEK_SETÚ
splitlines)ÚselfÚcoder   Úfdr   ZprocessÚstdoutÚstderrÚexitcodeÚoutputÚfpr   r   r   Ú
get_output:   s.    




zFaultHandlerTests.get_outputT)r   Úall_threadsÚother_regexr.   Úknow_current_threadc            C   s~   |r|rd}	qd}	nd}	d}
t |
j|||	dƒ ¡ }
|rD|
d| 7 }
| j|||d\}}d |¡}|  ||
¡ |  |d	¡ d
S )zÒ
        Check that the fault handler for fatal errors is enabled and check the
        traceback from the child process output.

        Raise an error if the output doesn't match the expected format.
        zCurrent thread 0x[0-9a-f]+zThread 0x[0-9a-f]+ZStackz—
            (?m)^{fatal_error}

            {header} \(most recent call first\):
              File "<string>", line {lineno} in <module>
            )ÚlinenoÚfatal_errorr   ú|)r   r.   r   r   N)r   Úformatr!   r4   ÚjoinÚassertRegexÚassertNotEqual)r,   r-   Úline_numberr9   r   r5   r6   r.   r7   r   r   r2   r1   r   r   r   Úcheck_error\   s     	
zFaultHandlerTests.check_errorc             K   s   d| }| j |||f|Ž d S )NzFatal Python error: %s)r@   )r,   r-   r?   Ú
name_regexÚkwr9   r   r   r   Úcheck_fatal_error}   s    z#FaultHandlerTests.check_fatal_errorc             K   s   d| }| j |||f|Ž d S )NzWindows fatal exception: %s)r@   )r,   r-   r?   rA   rB   r9   r   r   r   Úcheck_windows_exception   s    z)FaultHandlerTests.check_windows_exceptionZaixz5the first page of memory is a mapped read-only on AIXc             C   s&   t s|  ddd¡ n|  ddd¡ d S )Nz…
                import faulthandler
                faulthandler.enable()
                faulthandler._read_null()
                é   z4(?:Segmentation fault|Bus error|Illegal instruction)zaccess violation)Ú
MS_WINDOWSrC   rD   )r,   r   r   r   Útest_read_null…   s    z FaultHandlerTests.test_read_nullc             C   s   |   ddd¡ d S )Nzs
            import faulthandler
            faulthandler.enable()
            faulthandler._sigsegv()
            rE   zSegmentation fault)rC   )r,   r   r   r   Útest_sigsegvœ   s    zFaultHandlerTests.test_sigsegvc             C   s   | j ddddd d S )Nz€
            import faulthandler
            faulthandler.enable()
            faulthandler._fatal_error_c_thread()
            rE   zin new threadF)r7   )rC   )r,   r   r   r   Útest_fatal_error_c_thread¦   s
    z+FaultHandlerTests.test_fatal_error_c_threadc             C   s   |   ddd¡ d S )Nzs
            import faulthandler
            faulthandler.enable()
            faulthandler._sigabrt()
            rE   ZAborted)rC   )r,   r   r   r   Útest_sigabrt°   s    zFaultHandlerTests.test_sigabrtÚwin32z"SIGFPE cannot be caught on Windowsc             C   s   |   ddd¡ d S )Nzr
            import faulthandler
            faulthandler.enable()
            faulthandler._sigfpe()
            rE   zFloating point exception)rC   )r,   r   r   r   Útest_sigfpe¹   s    zFaultHandlerTests.test_sigfpezneed _testcapiÚSIGBUSzneed signal.SIGBUSc             C   s   |   ddd¡ d S )Nz¹
            import _testcapi
            import faulthandler
            import signal

            faulthandler.enable()
            _testcapi.raise_signal(signal.SIGBUS)
            é   z	Bus error)rC   )r,   r   r   r   Útest_sigbusÄ   s    zFaultHandlerTests.test_sigbusÚSIGILLzneed signal.SIGILLc             C   s   |   ddd¡ d S )Nz¹
            import _testcapi
            import faulthandler
            import signal

            faulthandler.enable()
            _testcapi.raise_signal(signal.SIGILL)
            rN   zIllegal instruction)rC   )r,   r   r   r   Útest_sigillÓ   s    zFaultHandlerTests.test_sigillc             C   s   |   ddd¡ d S )Nz[
            import faulthandler
            faulthandler._fatal_error(b'xyz')
            é   Úxyz)rC   )r,   r   r   r   Útest_fatal_errorâ   s    z"FaultHandlerTests.test_fatal_errorc             C   s   |   ddd¡ d S )Nza
            import faulthandler
            faulthandler._fatal_error(b'xyz', True)
            rR   rS   )rC   )r,   r   r   r   Útest_fatal_error_without_gilê   s    z.FaultHandlerTests.test_fatal_error_without_gilZopenbsdzVIssue #12868: sigaltstack() doesn't work on OpenBSD if Python is compiled with pthreadZ_stack_overflowz#need faulthandler._stack_overflow()c             C   s   | j ddddd d S )Nzz
            import faulthandler
            faulthandler.enable()
            faulthandler._stack_overflow()
            rE   z (?:Segmentation fault|Bus error)z unable to raise a stack overflow)r6   )rC   )r,   r   r   r   Útest_stack_overflowò   s
    z%FaultHandlerTests.test_stack_overflowc             C   s   |   ddd¡ d S )Nzw
            import faulthandler
            faulthandler.enable()
            faulthandler._sigsegv(True)
            rE   zSegmentation fault)rC   )r,   r   r   r   Útest_gil_released  s    z#FaultHandlerTests.test_gil_releasedz0sanitizer builds change crashing process output.c          	   C   s4   t ƒ $}| jdjt|ƒddd|d W d Q R X d S )Nz¹
                import faulthandler
                output = open({filename}, 'wb')
                faulthandler.enable(output)
                faulthandler._sigsegv()
                )r   é   zSegmentation fault)r   rC   r;   Úrepr)r,   r   r   r   r   Útest_enable_file  s    z"FaultHandlerTests.test_enable_filez.subprocess doesn't support pass_fds on Windowsc          	   C   s8   t  d¡$}| ¡ }| jd| dd|d W d Q R X d S )Nzwb+z 
                import faulthandler
                import sys
                faulthandler.enable(%s)
                faulthandler._sigsegv()
                rX   zSegmentation fault)r.   )r   ÚTemporaryFileÚfilenorC   )r,   r3   r.   r   r   r   Útest_enable_fd  s    z FaultHandlerTests.test_enable_fdc             C   s   | j ddddd d S )Nz„
            import faulthandler
            faulthandler.enable(all_threads=False)
            faulthandler._sigsegv()
            rE   zSegmentation faultF)r5   )rC   )r,   r   r   r   Útest_enable_single_thread,  s
    z+FaultHandlerTests.test_enable_single_threadc             C   sH   d}d}|   |¡\}}d |¡}|  ||kd||f ¡ |  |d¡ d S )Nz–
            import faulthandler
            faulthandler.enable()
            faulthandler.disable()
            faulthandler._sigsegv()
            zFatal Python errorr   z%r is present in %rr   )r4   r<   Ú
assertTruer>   )r,   r-   Znot_expectedr0   r1   r   r   r   Útest_disable7  s    

zFaultHandlerTests.test_disablec             C   sr   t j}z^t jt _t ¡ }z0t ¡  |  t ¡ ¡ t ¡  |  t ¡ ¡ W d |rXt ¡  nt ¡  X W d |t _X d S )N)	Úsysr0   Ú
__stderr__ÚfaulthandlerZ
is_enabledÚenabler_   ZdisableZassertFalse)r,   Zorig_stderrZwas_enabledr   r   r   Útest_is_enabledF  s    
z!FaultHandlerTests.test_is_enabledc             C   s0   d}t jdd|f}t |¡}|  | ¡ d¡ d S )Nz5import faulthandler; print(faulthandler.is_enabled())z-Ez-cs   False)ra   Ú
executableÚ
subprocessÚcheck_outputr%   Úrstrip)r,   r-   Úargsr2   r   r   r   Útest_disabled_by_default\  s    
z*FaultHandlerTests.test_disabled_by_defaultc             C   s`   d}t d tjtjjrdndddd|fƒ}tj ¡ }| dd ¡ t	j
||d}|  | ¡ d	¡ d S )
Nz5import faulthandler; print(faulthandler.is_enabled())z-Er   z-Xrc   z-cÚPYTHONFAULTHANDLER)Úenvs   True)Úfilterra   rf   ÚflagsÚignore_environmentr(   ÚenvironÚcopyÚpoprg   rh   r%   ri   )r,   r-   rj   rm   r2   r   r   r   Útest_sys_xoptionsd  s    
z#FaultHandlerTests.test_sys_xoptionsc             C   s„   d}t jd|f}ttjƒ}d|d< d|d< tj||d}|  | ¡ d¡ ttjƒ}d|d< d|d< tj||d}|  | ¡ d	¡ d S )
Nz5import faulthandler; print(faulthandler.is_enabled())z-cr   rl   ZPYTHONDEVMODE)rm   s   FalseÚ1s   True)	ra   rf   Údictr(   rq   rg   rh   r%   ri   )r,   r-   rj   rm   r2   r   r   r   Útest_env_varp  s    

zFaultHandlerTests.test_env_var)r   r.   c            C   sl   d}|j ||d}|rd}n|dk	r*d}nd}dd| d	d
g}|  |||¡\}}|  ||¡ |  |d¡ dS )z™
        Explicitly call dump_traceback() function and check its output.
        Raise an error if the output doesn't match the expected format.
        a[  
            import faulthandler

            filename = {filename!r}
            fd = {fd}

            def funcB():
                if filename:
                    with open(filename, "wb") as fp:
                        faulthandler.dump_traceback(fp, all_threads=False)
                elif fd is not None:
                    faulthandler.dump_traceback(fd,
                                                all_threads=False)
                else:
                    faulthandler.dump_traceback(all_threads=False)

            def funcA():
                funcB()

            funcA()
            )r   r.   é	   Né   é   zStack (most recent call first):z#  File "<string>", line %s in funcBz#  File "<string>", line 17 in funcAz&  File "<string>", line 19 in <module>r   )r;   r4   r%   )r,   r   r.   r-   r8   ÚexpectedÚtracer1   r   r   r   Úcheck_dump_traceback‚  s     z&FaultHandlerTests.check_dump_tracebackc             C   s   |   ¡  d S )N)r}   )r,   r   r   r   Útest_dump_traceback°  s    z%FaultHandlerTests.test_dump_tracebackc          	   C   s"   t ƒ }| j|d W d Q R X d S )N)r   )r   r}   )r,   r   r   r   r   Útest_dump_traceback_file³  s    z*FaultHandlerTests.test_dump_traceback_filec          	   C   s*   t  d¡}| j| ¡ d W d Q R X d S )Nzwb+)r.   )r   r[   r}   r\   )r,   r3   r   r   r   Útest_dump_traceback_fd·  s    z(FaultHandlerTests.test_dump_traceback_fdc             C   sd   d}d|d  }d| d }d}|j |d}dd| d	g}|  |¡\}}|  ||¡ |  |d
¡ d S )Niô  Úxé2   z...z§
            import faulthandler

            def {func_name}():
                faulthandler.dump_traceback(all_threads=False)

            {func_name}()
            )Ú	func_namezStack (most recent call first):z  File "<string>", line 4 in %sz%  File "<string>", line 6 in <module>r   )r;   r4   r%   )r,   Úmaxlenrƒ   Z	truncatedr-   r{   r|   r1   r   r   r   Útest_truncate½  s    zFaultHandlerTests.test_truncatec             C   sp   d}|j t|ƒd}|  ||¡\}}d |¡}|r8d}nd}d}t|j |dƒ ¡ }|  ||¡ |  |d¡ d	S )
z 
        Call explicitly dump_traceback(all_threads=True) and check the output.
        Raise an error if the output doesn't match the expected format.
        aÅ  
            import faulthandler
            from threading import Thread, Event
            import time

            def dump():
                if {filename}:
                    with open({filename}, "wb") as fp:
                        faulthandler.dump_traceback(fp, all_threads=True)
                else:
                    faulthandler.dump_traceback(all_threads=True)

            class Waiter(Thread):
                # avoid blocking if the main thread raises an exception.
                daemon = True

                def __init__(self):
                    Thread.__init__(self)
                    self.running = Event()
                    self.stop = Event()

                def run(self):
                    self.running.set()
                    self.stop.wait()

            waiter = Waiter()
            waiter.start()
            waiter.running.wait()
            dump()
            waiter.stop.set()
            waiter.join()
            )r   r   é   é
   aï  
            ^Thread 0x[0-9a-f]+ \(most recent call first\):
            (?:  File ".*threading.py", line [0-9]+ in [_a-z]+
            ){{1,3}}  File "<string>", line 23 in run
              File ".*threading.py", line [0-9]+ in _bootstrap_inner
              File ".*threading.py", line [0-9]+ in _bootstrap

            Current thread 0x[0-9a-f]+ \(most recent call first\):
              File "<string>", line {lineno} in dump
              File "<string>", line 28 in <module>$
            )r8   r   N)r;   rY   r4   r<   r   r!   r=   r%   )r,   r   r-   r2   r1   r8   r   r   r   r   Úcheck_dump_traceback_threadsÕ  s    $
z.FaultHandlerTests.check_dump_traceback_threadsc             C   s   |   d ¡ d S )N)rˆ   )r,   r   r   r   Útest_dump_traceback_threads  s    z-FaultHandlerTests.test_dump_traceback_threadsc          	   C   s    t ƒ }|  |¡ W d Q R X d S )N)r   rˆ   )r,   r   r   r   r   Ú test_dump_traceback_threads_file  s    z2FaultHandlerTests.test_dump_traceback_threads_fileÚdump_traceback_laterz(need faulthandler.dump_traceback_later()Fr	   c            C   sš   t tjtdƒ}d}|jt|||||d}|  ||¡\}}	d |¡}|s~|}
|rX|
d9 }
d| }tdd||
d	}|  ||¡ n|  	|d
¡ |  	|	d¡ dS )a  
        Check how many times the traceback is written in timeout x 2.5 seconds,
        or timeout x 3.5 seconds if cancel is True: 1, 2 or 3 times depending
        on repeat and cancel options.

        Raise an error if the output doesn't match the expect format.
        )ZsecondsaÉ  
            import faulthandler
            import time
            import sys

            timeout = {timeout}
            repeat = {repeat}
            cancel = {cancel}
            loops = {loops}
            filename = {filename!r}
            fd = {fd}

            def func(timeout, repeat, cancel, file, loops):
                for loop in range(loops):
                    faulthandler.dump_traceback_later(timeout, repeat=repeat, file=file)
                    if cancel:
                        faulthandler.cancel_dump_traceback_later()
                    time.sleep(timeout * 5)
                    faulthandler.cancel_dump_traceback_later()

            if filename:
                file = open(filename, "wb")
            elif fd is not None:
                file = sys.stderr.fileno()
            else:
                file = None
            func(timeout, repeat, cancel, file, loops)
            if filename:
                file.close()
            )ZtimeoutÚrepeatÚcancelÚloopsr   r.   r   rR   zATimeout \(%s\)!\nThread 0x[0-9a-f]+ \(most recent call first\):\né   é   )r   r   r   N)
ÚstrÚdatetimeZ	timedeltaÚTIMEOUTr;   r4   r<   r   r=   r%   )r,   rŒ   r   rŽ   r   r.   Ztimeout_strr-   r|   r1   Úcountr   r   r   r   r   Úcheck_dump_traceback_later  s(    
z,FaultHandlerTests.check_dump_traceback_laterc             C   s   |   ¡  d S )N)r•   )r,   r   r   r   Útest_dump_traceback_laterW  s    z+FaultHandlerTests.test_dump_traceback_laterc             C   s   | j dd d S )NT)rŒ   )r•   )r,   r   r   r   Ú test_dump_traceback_later_repeatZ  s    z2FaultHandlerTests.test_dump_traceback_later_repeatc             C   s   | j dd d S )NT)r   )r•   )r,   r   r   r   Ú test_dump_traceback_later_cancel]  s    z2FaultHandlerTests.test_dump_traceback_later_cancelc          	   C   s"   t ƒ }| j|d W d Q R X d S )N)r   )r   r•   )r,   r   r   r   r   Útest_dump_traceback_later_file`  s    z0FaultHandlerTests.test_dump_traceback_later_filec          	   C   s*   t  d¡}| j| ¡ d W d Q R X d S )Nzwb+)r.   )r   r[   r•   r\   )r,   r3   r   r   r   Útest_dump_traceback_later_fdd  s    z.FaultHandlerTests.test_dump_traceback_later_fdc             C   s   | j dd d S )NrR   )rŽ   )r•   )r,   r   r   r   Útest_dump_traceback_later_twicej  s    z1FaultHandlerTests.test_dump_traceback_later_twiceÚregisterzneed faulthandler.registerc             C   s”   t j}d}|j||||||d}|  ||¡\}}	d |¡}|sf|rHd}
nd}
tdd|
ƒ}
|  ||
¡ n|  |d¡ |r„|  |	d	¡ n|  |	d	¡ d
S )a  
        Register a handler displaying the traceback on a user signal. Raise the
        signal and check the written traceback.

        If chain is True, check that the previous signal handler is called.

        Raise an error if the output doesn't match the expected format.
        ax  
            import faulthandler
            import os
            import signal
            import sys

            all_threads = {all_threads}
            signum = {signum}
            unregister = {unregister}
            chain = {chain}
            filename = {filename!r}
            fd = {fd}

            def func(signum):
                os.kill(os.getpid(), signum)

            def handler(signum, frame):
                handler.called = True
            handler.called = False

            if filename:
                file = open(filename, "wb")
            elif fd is not None:
                file = sys.stderr.fileno()
            else:
                file = None
            if chain:
                signal.signal(signum, handler)
            faulthandler.register(signum, file=file,
                                  all_threads=all_threads, chain={chain})
            if unregister:
                faulthandler.unregister(signum)
            func(signum)
            if chain and not handler.called:
                if file is not None:
                    output = file
                else:
                    output = sys.stderr
                print("Error: signal handler not called!", file=output)
                exitcode = 1
            else:
                exitcode = 0
            if filename:
                file.close()
            sys.exit(exitcode)
            )r5   ÚsignumÚ
unregisterÚchainr   r.   r   z8Current thread 0x[0-9a-f]+ \(most recent call first\):\nz#Stack \(most recent call first\):\nrz   é    r   r   N)	ÚsignalÚSIGUSR1r;   r4   r<   r   r=   r%   r>   )r,   r   r5   rž   rŸ   r.   r   r-   r|   r1   r   r   r   r   Úcheck_registerm  s*    .
z FaultHandlerTests.check_registerc             C   s   |   ¡  d S )N)r£   )r,   r   r   r   Útest_registerÀ  s    zFaultHandlerTests.test_registerc             C   s   | j dd d S )NT)rž   )r£   )r,   r   r   r   Útest_unregisterÃ  s    z!FaultHandlerTests.test_unregisterc          	   C   s"   t ƒ }| j|d W d Q R X d S )N)r   )r   r£   )r,   r   r   r   r   Útest_register_fileÆ  s    z$FaultHandlerTests.test_register_filec          	   C   s*   t  d¡}| j| ¡ d W d Q R X d S )Nzwb+)r.   )r   r[   r£   r\   )r,   r3   r   r   r   Útest_register_fdÊ  s    z"FaultHandlerTests.test_register_fdc             C   s   | j dd d S )NT)r5   )r£   )r,   r   r   r   Útest_register_threadsÐ  s    z'FaultHandlerTests.test_register_threadsc             C   s   | j dd d S )NT)rŸ   )r£   )r,   r   r   r   Útest_register_chainÓ  s    z%FaultHandlerTests.test_register_chainc          	   c   sL   t j}z8d t _|  t¡}d V  W d Q R X |  t|jƒd¡ W d |t _X d S )Nzsys.stderr is None)ra   r0   ZassertRaisesÚRuntimeErrorr%   r‘   Z	exception)r,   r0   Úcmr   r   r   Úcheck_stderr_noneÖ  s    z#FaultHandlerTests.check_stderr_nonec          	   C   sŽ   |   ¡  t ¡  W d Q R X |   ¡  t ¡  W d Q R X ttdƒr`|   ¡  t d¡ W d Q R X ttdƒrŠ|   ¡  t tj¡ W d Q R X d S )Nr‹   gü©ñÒMbP?rœ   )	r¬   rc   rd   Zdump_tracebackÚhasattrr‹   rœ   r¡   r¢   )r,   r   r   r   Útest_stderr_Noneá  s    





z"FaultHandlerTests.test_stderr_Nonezspecific to Windowsc             C   s,   x&dD ]\}}|   d|› dd|¡ qW d S )N))ZEXCEPTION_ACCESS_VIOLATIONzaccess violation)ZEXCEPTION_INT_DIVIDE_BY_ZEROzint divide by zero)ZEXCEPTION_STACK_OVERFLOWzstack overflowz‡
                import faulthandler
                faulthandler.enable()
                faulthandler._raise_exception(faulthandler._z)
                rE   )rD   )r,   ÚexcÚnamer   r   r   Útest_raise_exceptionï  s    
z&FaultHandlerTests.test_raise_exceptionc             C   sL   xFdD ]>}d|› d}t |ƒ}|  |¡\}}|  |g ¡ |  ||¡ qW d S )N)l   csÚ@ l   RC†@ z…
                    import faulthandler
                    faulthandler.enable()
                    faulthandler._raise_exception(z)
                    )r   r4   r%   )r,   Zexc_coder-   r2   r1   r   r   r   Útest_ignore_exceptionþ  s    z'FaultHandlerTests.test_ignore_exceptionc             C   sJ   xDdD ]<}|   d|d›d¡\}}|  |g ¡ |  |||d@ f¡ qW d S )N)r   ixV4i   @i  @i   piÿÿÿz{
                import faulthandler
                faulthandler.enable()
                faulthandler._raise_exception(0xr   z)
                iÿÿÿï)r4   r%   ZassertIn)r,   r¯   r2   r1   r   r   r   Útest_raise_nonfatal_exception  s    z/FaultHandlerTests.test_raise_nonfatal_exceptionc             C   s2   t dƒ}|  |¡\}}|  |g ¡ |  |d¡ d S )NzÚ
            import faulthandler
            faulthandler.enable()
            faulthandler.disable()
            code = faulthandler._EXCEPTION_ACCESS_VIOLATION
            faulthandler._raise_exception(code)
        l       )r   r4   r%   )r,   r-   r2   r1   r   r   r   Ú test_disable_windows_exc_handler*  s
    z2FaultHandlerTests.test_disable_windows_exc_handler)NN)FFr	   )FFFFN)EÚ__name__Ú
__module__Ú__qualname__r4   r@   rC   rD   r   r   ra   ÚplatformÚ
startswithrG   r   rH   rI   rJ   rL   Ú	_testcapiZ
skipUnlessr­   r¡   rO   rQ   rT   rU   rc   rV   rW   ÚUB_SANITIZERÚMEMORY_SANITIZERrZ   r]   r^   r`   re   rk   rt   rw   r}   r~   r   r€   r…   rˆ   r‰   rŠ   r•   r–   r—   r˜   r™   rš   r›   r£   r¤   r¥   r¦   r§   r¨   r©   r   r¬   r®   rF   r±   r²   r³   r´   r   r   r   r   r   9   s˜   
#

	

.;= Pr   Ú__main__)r	   )$Ú
contextlibr   r’   rc   r(   r¡   rg   ra   Z	sysconfigr   r   Ztest.supportr   r   r   Z	threadingr   Útextwrapr   rº   ÚImportErrorr“   r°   rF   Zget_config_varZ_cflagsZ_config_argsr»   r¼   r   r   r   ZTestCaser   rµ   Úmainr   r   r   r   Ú<module>   sJ   


	      
