a
    ze&                     @   s   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Zd dlm	Z	 d dl
mZmZ dd Ze \ZZZedk redeeef e sedd	e v rejd
krededpdedpdv rede je jejdZdZdd Ze Zdd Zed\ZZes2ededej\ZZ de v rbdZ!ee!e "  dd Z#e# Z$dZ%e&e	j'dG d d! d!ej(Z)G d"d# d#e)Z*e&e d$G d%d& d&e)Z+G d'd( d(e)Z,G d)d* d*e)Z-G d+d, d,e)Z.G d-d. d.e)Z/d/d0 Z0e1d1kre2  dS )2    N)support)findfilepython_is_optimizedc               	   C   s   zg d} t j| t jt jdd}| | \}}W d    n1 sF0    Y  |jr~tdd| d|j d|d|W n ty   t	d	Y n0 t
d
|}|d u rtd| |t|dt|dfS )N)gdb-nxz	--versionT)stdoutstderruniversal_newlineszCommand  z failed with exit code z	: stdout=z stderr=zCouldn't find gdb on the pathz ^(?:GNU|HP) gdb.*?\b(\d+)\.(\d+)zunable to parse GDB version: %r      )
subprocessPopenPIPEcommunicate
returncode	ExceptionjoinOSErrorunittestSkipTestresearchintgroup)cmdprocversionr   match r   #/usr/lib/python3.9/test/test_gdb.pyget_gdb_version   s.    *r!      zFgdb versions before 7.0 didn't support python embedding. Saw %s.%s:
%sz3test_gdb only works on source builds at the moment.ZClangdarwinzDtest_gdb doesn't work correctly when python is built with LLVM clangZPGO_PROF_USE_FLAGZxxxZPY_CORE_CFLAGS z&test_gdb is not reliable on PGO buildszpython-gdb.pyZ123c                  C   s4   t d} | sdS |  }d|v o2tdd |D S )NZCFLAGSFz-mcetc                 s   s$   | ]}| d o|d V  qdS )z-fcf-protection)z=nonez=returnN)
startswithendswith).0flagr   r   r    	<genexpr>Q   s   
z!cet_protection.<locals>.<genexpr>)	sysconfigget_config_varsplitany)Zcflagsflagsr   r   r    cet_protectionI   s    
r/   c                  O   s   |rt j }|| nd}d}ttfdkr>|ddt f7 }tj||  tj	tj	tj	|d}| |
 \}}W d   n1 s0    Y  |dd|ddfS )	zRuns gdb in --batch mode with the additional arguments given by *args.

    Returns its (stdout, stderr) decoded from utf-8 using the replace handler.
    N)r   z--batchr   r"      z-iexzadd-auto-load-safe-path )stdinr   r   envzutf-8replace)osenvironcopyupdategdb_major_versiongdb_minor_versioncheckout_hook_pathr   r   r   r   decode)argsZenv_varsr3   Zbase_cmdr   outerrr   r   r    run_gdbY   s     

*r@   z9--eval-command=python import sys; print(sys.version_info)z*gdb not built with embedded python support--argszauto-loading has been declinedz3gdb security settings prevent use of custom hooks: c                  C   s>   t d\} }td| }|s&td|dd}d|v S )Nz+--eval-command=python print(dir(gdb.Frame))z.*\[(.*)\].*z1Unable to parse output from gdb.Frame.select testr   z, z'select')r@   r   r   r   r   r   r,   )r   _mZgdb_frame_dirr   r   r    gdb_has_frame_select   s    
rD   
builtin_idznot useful for PGOc                   @   sH   e Zd ZdZddedddfddZdddZdd	 Zd
d Zdd Z	dS )DebuggerTestsz(Test that the debugger can debug Python.NFc                 C   s  dd| ddg}t tfdkr&|dg7 }|rBtr8|dg7 }||7 }n
|dg7 }d	d
 |D }|dtjg7 }|t  |s|dg7 }|r|d|g7 }n|r||g7 }t|dt	i\}	}
|s|

 D ]}t|tjd qd|
v rtddD ]}||	v rt|dq|	S )z
        Run 'python -c SOURCE' under gdb with a breakpoint.

        Support injecting commands after the breakpoint is reached

        Returns the stdout from gdb

        cmds_after_breakpoint: if provided, a list of strings: gdb commands
        zset breakpoint pending yeszbreak %szset print address offrunr0   zset print entry-values nonext	backtracec                 S   s   g | ]}d | qS )z--eval-command=%sr   )r'   r   r   r   r    
<listcomp>       z1DebuggerTests.get_stack_trace.<locals>.<listcomp>rA   z-Sz-cPYTHONHASHSEED)filezPC not savedzKgdb cannot walk the frame object because the Program Counter is not present)z!(frame information optimized out)z*Unable to read information on python framez found in gdb output)r9   r:   CET_PROTECTIONsys
executableextendr   _args_from_interpreter_flagsr@   rL   
splitlinesprintr   r   r   )selfsourcescript
breakpointcmds_after_breakpointimport_siteignore_stderrcommandsr=   r>   r?   linepatternr   r   r    get_stack_trace   sB    







zDebuggerTests.get_stack_tracec                 C   sP   |pdg}| j |t||d}td|tj}|sB| d||f  |d|fS )Nzbacktrace 1)rX   rY   rZ   zS#0\s+builtin_id\s+\(self\=.*,\s+v=\s*(.*?)?\)\s+at\s+\S*[A-Za-z]+/[A-Za-z0-9_-]+\.czUnexpected gdb output: %r
%sr   )r_   BREAKPOINT_FNr   r   DOTALLfailr   )rU   rV   rY   rZ   
gdb_outputrC   r   r   r    get_gdb_repr   s    
	zDebuggerTests.get_gdb_reprc                 C   s    | j ||d||f d dS )z9Ensure that the given "actual" string ends with "exp_end"z%r did not end with %rmsgN)
assertTruer&   )rU   actualZexp_endr   r   r    assertEndsWith!  s    
zDebuggerTests.assertEndsWithc                 C   s,   t ||t j}|s(| jd||f d d S )Nz%r did not match %rre   )r   r   ra   rb   )rU   rh   r^   rC   r   r   r    assertMultilineMatches&  s    z$DebuggerTests.assertMultilineMatchesc                 C   s   t dS )Nzgdb_sample.py)r   rU   r   r   r    get_sample_script+  s    zDebuggerTests.get_sample_script)NF)
__name__
__module____qualname____doc__r`   r_   rd   ri   rj   rl   r   r   r   r    rF      s   
m  
$rF   c                   @   s   e Zd Zdd Zd<ddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zd=d d!Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; ZdS )>PrettyPrintTestsc                 C   s   |  d}| t|v  d S )Nid(42))r_   rg   r`   rU   rc   r   r   r    test_getting_backtrace/  s    
z'PrettyPrintTests.test_getting_backtraceNc                 C   sB   |  dt| d \}}|s&t|}| ||d|||f  d S )Nzid()z1%r did not equal expected %r; full output was:
%s)rd   asciireprassertEqual)rU   valZexp_reprgdb_reprrc   r   r   r    assertGdbRepr3  s    zPrettyPrintTests.assertGdbReprc                 C   s6   |  d |  d |  d |  d |  d dS )z0Verify the pretty-printing of various int values*   r   il    J)l  I5 Nr{   rk   r   r   r    test_int=  s
    



zPrettyPrintTests.test_intc                 C   s"   |  d |  d |  d dS )z2Verify the pretty-printing of True, False and NoneTFNr}   rk   r   r   r    test_singletonsE  s    

z PrettyPrintTests.test_singletonsc                 C   s0   |  i  |  ddid |  dddd dS )z*Verify the pretty-printing of dictionariesfoobarz{'foo': 'bar'}r|   )r   Zdouglasz{'foo': 'bar', 'douglas': 42}Nr}   rk   r   r   r    
test_dictsK  s    
zPrettyPrintTests.test_dictsc                 C   s    |  g  |  ttd dS )z#Verify the pretty-printing of lists   N)r{   listrangerk   r   r   r    
test_listsR  s    
zPrettyPrintTests.test_listsc                 C   sR   |  d |  d |  d |  d |  d |  tdd tdD  d	S )
z#Verify the pretty-printing of bytesrK   s(   And now for something hopefully the sames7   string with embedded NUL here   and then some more texts7   this is a tab:	 this is a slash-N:
 this is a slash-R:s!   this is byte 255: and byte 128:c                 S   s   g | ]}|qS r   r   )r'   br   r   r    rJ   c  rK   z/PrettyPrintTests.test_bytes.<locals>.<listcomp>   N)r{   bytesr   rk   r   r   r    
test_bytesW  s    




zPrettyPrintTests.test_bytesc                    sx   t dd\}}|  |s s,td|  fdd}d d d |d	 |d
 |td dS )z-Verify the pretty-printing of unicode stringsz--eval-commandz:python import locale; print(locale.getpreferredencoding())zFunable to determine the preferred encoding of embedded Python in GDB: c                    s@   z|    W n" ty0   | t|  Y n0 |  d S N)encodeUnicodeEncodeErrorr{   rv   )textencodingrU   r   r    
check_repru  s
    z1PrettyPrintTests.test_strings.<locals>.check_reprr$   z(And now for something hopefully the samez7string with embedded NUL here   and then some more textu   ☠u   文字化けi! N)r@   rstripRuntimeErrorr{   chr)rU   r>   r?   r   r   r   r    test_stringse  s$    


zPrettyPrintTests.test_stringsc                 C   s(   |  t d |  dd |  d dS )z$Verify the pretty-printing of tuplesz())r   z(1,))r   r   ZbazN)r{   tuplerk   r   r   r    test_tuples  s    zPrettyPrintTests.test_tuplesc                 C   s   t tfdk r| d | t d | tdgd tjjsf| tddgd | tg dd	 | d
\}}| 	|d dS )z"Verify the pretty-printing of setsr"      z.pretty-printing of sets needs gdb 7.3 or laterzset()az{'a'}r   z
{'a', 'b'}r1   r      z	{4, 5, 6}z&s = set(['a','b'])
s.remove('a')
id(s)z{'b'}N)
r9   r:   skipTestr{   setrO   r.   ignore_environmentrd   rx   rU   rz   rc   r   r   r    	test_sets  s    
zPrettyPrintTests.test_setsc                 C   sj   t tfdk r| d | t d | tdgd tjjsf| tddgd | tg dd	 d
S )z(Verify the pretty-printing of frozensetsr   z4pretty-printing of frozensets needs gdb 7.3 or laterzfrozenset()r   zfrozenset({'a'})r   zfrozenset({'a', 'b'})r   zfrozenset({4, 5, 6})N)r9   r:   r   r{   	frozensetrO   r.   r   rk   r   r   r    test_frozensets  s    
z PrettyPrintTests.test_frozensetsc                 C   s8   |  d\}}| |d |  d\}}| |d d S )NzR
try:
    raise RuntimeError("I am an error")
except RuntimeError as e:
    id(e)
zRuntimeError('I am an error',)z=
try:
    a = 1 / 0
except ZeroDivisionError as e:
    id(e)
z&ZeroDivisionError('division by zero',)rd   rx   r   r   r   r    test_exceptions  s    z PrettyPrintTests.test_exceptionsc                 C   s0   |  d\}}td|}| j|d| d dS )z7Verify the pretty-printing of new-style class instancesz8
class Foo:
    pass
foo = Foo()
foo.an_int = 42
id(foo)*<Foo\(an_int=42\) at remote 0x-?[0-9a-f]+>'Unexpected new-style class rendering %rre   Nrd   r   r   rg   rU   rz   rc   rC   r   r   r    test_modern_class  s
    z"PrettyPrintTests.test_modern_classc                 C   s0   |  d\}}td|}| j|d| d dS )z<Verify the pretty-printing of an instance of a list subclasszO
class Foo(list):
    pass
foo = Foo()
foo += [1, 2, 3]
foo.an_int = 42
id(foo)r   r   re   Nr   r   r   r   r    test_subclassing_list  s
    z&PrettyPrintTests.test_subclassing_listc                 C   s0   |  d\}}td|}| j|d| d dS )z=Verify the pretty-printing of an instance of a tuple subclasszH
class Foo(tuple):
    pass
foo = Foo((1, 2, 3))
foo.an_int = 42
id(foo)r   r   re   Nr   r   r   r   r    test_subclassing_tuple  s
    z'PrettyPrintTests.test_subclassing_tuplec           	      C   s`   |r|dg}ndg}| j ||d\}}|r6||kr6dS d}t||}|s\| d||f  dS )zRun Python under gdb, corrupting variables in the inferior process
        immediately before taking a backtrace.

        Verify that the variable's representation is the expected failsafe
        representationrI   rY   Nz<.* at remote 0x-?[0-9a-f]+>$Unexpected gdb representation: %r
%s)rd   r   r   rb   )	rU   rV   Z
corruptionexpreprrY   rz   rc   r^   rC   r   r   r    
assertSane  s     
zPrettyPrintTests.assertSanec                 C   s&   | j dddgd\}}| |d dS )z2Ensure that a NULL PyObject* is handled gracefullyrr   zset variable v=0rI   r   Z0x0Nr   r   r   r   r    test_NULL_ptr  s    zPrettyPrintTests.test_NULL_ptrc                 C   s   |  dd dS )z?Ensure that a PyObject* with NULL ob_type is handled gracefullyrr   zset v->ob_type=0Nr   rk   r   r   r    test_NULL_ob_type  s    z"PrettyPrintTests.test_NULL_ob_typec                 C   s   | j dddd dS )zDEnsure that a PyObject* with a corrupt ob_type is handled gracefullyrr   zset v->ob_type=0xDEADBEEF42r   Nr   rk   r   r   r    test_corrupt_ob_type  s    z%PrettyPrintTests.test_corrupt_ob_typec                 C   s   | j dddd dS )zDEnsure that a PyObject* with a type with corrupt tp_flags is handledrr   zset v->ob_type->tp_flags=0x0r   r   Nr   rk   r   r   r    test_corrupt_tp_flags%  s    z&PrettyPrintTests.test_corrupt_tp_flagsc                 C   s   | j dddd dS )zCEnsure that a PyObject* with a type with corrupt tp_name is handledrr   z"set v->ob_type->tp_name=0xDEADBEEFr   r   Nr   rk   r   r   r    test_corrupt_tp_name+  s    z%PrettyPrintTests.test_corrupt_tp_namec                 C   sF   t jjr| d | jddd\}}td|}| j|d| d dS )	zAEnsure that the new-style class _Helper in site.py can be handledz(need site module, but -S option was usedzid(__builtins__.help)T)rZ   z!<_Helper at remote 0x-?[0-9a-f]+>zUnexpected rendering %rre   N)rO   r.   no_siter   rd   r   r   rg   r   r   r   r    test_builtins_help1  s    
z#PrettyPrintTests.test_builtins_helpc                 C   s8   |  d\}}| |d |  d\}}| |d dS )zbEnsure that a reference loop involving a list doesn't lead proxyval
        into an infinite loop:z#a = [3, 4, 5] ; a.append(a) ; id(a)z[3, 4, 5, [...]]z-a = [3, 4, 5] ; b = [a] ; a.append(b) ; id(a)z[3, 4, 5, [[...]]]Nr   r   r   r   r    test_selfreferential_list?  s    z*PrettyPrintTests.test_selfreferential_listc                 C   s   |  d\}}| |d dS )zbEnsure that a reference loop involving a dict doesn't lead proxyval
        into an infinite loop:z-a = {} ; b = {'bar':a} ; a['foo'] = b ; id(a)z{'foo': {'bar': {...}}}Nr   r   r   r   r    test_selfreferential_dictJ  s    z*PrettyPrintTests.test_selfreferential_dictc                 C   s.   |  d\}}| td|d||f  d S )Nz:
class Foo:
    pass
foo = Foo()
foo.an_attr = foo
id(foo)1<Foo\(an_attr=<\.\.\.>\) at remote 0x-?[0-9a-f]+>r   rd   rg   r   r   r   r   r   r    'test_selfreferential_old_style_instanceR  s    
z8PrettyPrintTests.test_selfreferential_old_style_instancec                 C   sX   |  d\}}| td|d||f  |  d\}}| td|d||f  d S )NzB
class Foo(object):
    pass
foo = Foo()
foo.an_attr = foo
id(foo)r   r   zR
class Foo(object):
    pass
a = Foo()
b = Foo()
a.an_attr = b
b.an_attr = a
id(a)zZ<Foo\(an_attr=<Foo\(an_attr=<\.\.\.>\) at remote 0x-?[0-9a-f]+>\) at remote 0x-?[0-9a-f]+>r   r   r   r   r    'test_selfreferential_new_style_instance_  s$    
	
z8PrettyPrintTests.test_selfreferential_new_style_instancec                 C   s6   |  d\}}| |d | t|dtd  dS )z)Verify that very long output is truncatedzid(list(range(1000)))a  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226...(truncated)i   z...(truncated)N)rd   rx   lenr   r   r   r    test_truncationz  s    

z PrettyPrintTests.test_truncationc                 C   s.   |  d\}}| td|d||f  d S )Nz$import sys; id(sys.stdout.readlines)zO<built-in method readlines of _io.TextIOWrapper object at remote 0x-?[0-9a-f]+>r   r   r   r   r   r    test_builtin_method  s    
z$PrettyPrintTests.test_builtin_methodc                 C   s6   | j dddgd}| td|tjd||f  d S )Nz:
def foo(a, b, c):
    pass

foo(3, 4, 5)
id(foo.__code__)rE   z:print (PyFrameObject*)(((PyCodeObject*)v)->co_zombieframe))rX   rY   zM.*\s+\$1 =\s+Frame 0x-?[0-9a-f]+, for file <string>, line 3, in foo \(\)\s+.*r   )r_   rg   r   r   ra   rs   r   r   r    test_frames  s    	

zPrettyPrintTests.test_frames)N)N) rm   rn   ro   rt   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   r   r   r   r   r   r   r    rq   .  s:   

,

rq   &Python was compiled with optimizationsc                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
PyListTestsc                 C   s   |  || d S r   )ri   )rU   Zexpectedrh   r   r   r    assertListing  s    zPyListTests.assertListingc                 C   s$   | j |  dgd}| d| dS )z'Verify that the "py-list" command workszpy-listrW   rY   z   5    
   6    def bar(a, b, c):
   7        baz(a, b, c)
   8    
   9    def baz(*args):
 >10        id(42)
  11    
  12    foo(1, 2, 3)
Nr_   rl   r   rU   btr   r   r    test_basic_command  s    
zPyListTests.test_basic_commandc                 C   s$   | j |  dgd}| d| dS )z7Verify the "py-list" command with one absolute argumentz	py-list 9r   zI   9    def baz(*args):
 >10        id(42)
  11    
  12    foo(1, 2, 3)
Nr   r   r   r   r    test_one_abs_arg  s    
zPyListTests.test_one_abs_argc                 C   s$   | j |  dgd}| d| dS )z8Verify the "py-list" command with two absolute argumentszpy-list 1,3r   zR   1    # Sample script for use by test_gdb.py
   2    
   3    def foo(a, b, c):
Nr   r   r   r   r    test_two_abs_args  s    
zPyListTests.test_two_abs_argsN)rm   rn   ro   r   r   r   r   r   r   r   r    r     s   r   c                   @   sx   e Zd Zeedee ddd Zeeddd Z	eeddd Z
eedee dd	d
 ZdS )StackNavigationTests$test requires py-up/py-down commandsr   c                 C   s&   | j |  ddgd}| |d dS )z%Verify that the "py-up" command workspy-upr   zp^.*
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\)
    baz\(a, b, c\)
$Nr_   rl   rj   r   r   r   r    test_pyup_command  s    
z&StackNavigationTests.test_pyup_commandc                 C   s$   | j |  dgd}| |d dS )z7Verify handling of "py-down" at the bottom of the stackpy-downr   z$Unable to find a newer python frame
Nr_   rl   ri   r   r   r   r    test_down_at_bottom  s    
z(StackNavigationTests.test_down_at_bottomc                 C   s(   | j |  dgd d}| |d dS )z2Verify handling of "py-up" at the top of the stackr   r   r   z%Unable to find an older python frame
Nr   r   r   r   r    test_up_at_top  s    
z#StackNavigationTests.test_up_at_topc                 C   s&   | j |  g dd}| |d dS )z$Verify "py-up" followed by "py-down")r   r   r   r   z^.*
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\)
    baz\(a, b, c\)
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 10, in baz \(args=\(1, 2, 3\)\)
    id\(42\)
$Nr   r   r   r   r    test_up_then_down  s    
z&StackNavigationTests.test_up_then_downN)rm   rn   ro   r   
skipUnlessHAS_PYUP_PYDOWNskipIfr   r   r   r   r   r   r   r   r    r     s   






r   c                   @   s   e Zd Zee ddd Zee ddd Zdd Zee ddd	 Z	ee dd
d Z
ee ddd Zee ddd ZdS )	PyBtTestsr   c                 C   s$   | j |  dgd}| |d dS )z%Verify that the "py-bt" command workspy-btr   aF  ^.*
Traceback \(most recent call first\):
  <built-in method id of module object .*>
  File ".*gdb_sample.py", line 10, in baz
    id\(42\)
  File ".*gdb_sample.py", line 7, in bar
    baz\(a, b, c\)
  File ".*gdb_sample.py", line 4, in foo
    bar\(a, b, c\)
  File ".*gdb_sample.py", line 12, in <module>
    foo\(1, 2, 3\)
Nr   r   r   r   r    test_bt  s    
zPyBtTests.test_btc                 C   s$   | j |  dgd}| |d dS )z*Verify that the "py-bt-full" command works
py-bt-fullr   a>  ^.*
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\)
    baz\(a, b, c\)
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 4, in foo \(a=1, b=2, c=3\)
    bar\(a, b, c\)
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 12, in <module> \(\)
    foo\(1, 2, 3\)
Nr   r   r   r   r    test_bt_full  s    
zPyBtTests.test_bt_fullc                 C   s@   d}| j |dgd}| d| | j |dgd}| d| dS )zBVerify that "py-bt" indicates threads that are waiting for the GILaN  
from threading import Thread

class TestThread(Thread):
    # These threads would run forever, but we'll interrupt things with the
    # debugger
    def run(self):
        i = 0
        while 1:
             i += 1

t = {}
for i in range(4):
   t[i] = TestThread()
   t[i].start()

# Trigger a breakpoint on the main thread
id(42)

zthread apply all py-btr   zWaiting for the GILzthread apply all py-bt-fullNr_   assertInrU   r   rc   r   r   r    test_threads(  s    zPyBtTests.test_threadsc                 C   sD   d}| j |g dd}| d| | j |g dd}| d| dS )z?Verify that "py-bt" indicates if a thread is garbage-collectingzRfrom gc import collect
id(42)
def foo():
    collect()
def bar():
    foo()
bar()
)break update_refscontinuer   r   zGarbage-collecting)r   r   r   Nr   r   r   r   r    test_gcH  s    zPyBtTests.test_gcc                 C   s   dD ]\}}}dD ]}|  | d|  td| d| d| d}| j||ddgd	d
}| d| | | j||dgd	d
}| d| d| | W d   q1 s0    Y  qqdS )zAVerify that "py-bt" displays invocations of PyCFunction instances))Zmeth_varargsr$   r   )Zmeth_varargs_keywordsr$   r   )Zmeth_oz[]r   )Zmeth_noargsr$   r   )Zmeth_fastcallr$   r   )Zmeth_fastcall_keywordsr$   r   )Z	_testcapiz_testcapi.MethClassz_testcapi.MethClass()z_testcapi.MethStatic().zi
                        import _testcapi
                        def foo():
                            (zy)
                        def bar():
                            foo()
                        bar()
                    r   r   T)rX   rY   r[   z<built-in method r   #z <built-in method N)ZsubTesttextwrapdedentr_   r   )rU   	func_namer=   Zexpected_frameobjr   rc   r   r   r    test_pycfunctionc  s6    	
	zPyBtTests.test_pycfunctionc                 C   sH   t d}ddg}tr |d |d | j||d}| |d d S )Nz
            class MyList(list):
                def __init__(self):
                    super().__init__()   # wrapper_call()

            id("first break point")
            l = MyList()
        zbreak wrapper_callr   rH   r   r   z1<method-wrapper u?'__init__' of MyList object at )r   r   rN   appendr_   ZassertRegex)rU   r   rY   rc   r   r   r    test_wrapper_call  s    


zPyBtTests.test_wrapper_callc                 C   s*   t d}| j|dgd}| |d d S )Na%  
            def foo(x):
                try:
                    raise RuntimeError("error")
                    return x
                except:
                    id("break point")
                finally:
                    x += 2
                return x
            r = foo(3)
        r   r   z^.*
Traceback \(most recent call first\):
  <built-in method id of module object .*>
  File "<string>", line 7, in foo
  File "<string>", line 11, in <module>
)r   r   r_   rj   r   r   r   r    test_try_finally_lineno  s    
z!PyBtTests.test_try_finally_linenoN)rm   rn   ro   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r     s2   

 

7
r   c                   @   sp   e Zd Zee ddd Zee deeddd Z	ee ddd Z
ee dd	d
 ZdS )PyPrintTestsr   c                 C   s&   | j |  ddgd}| |d dS )z(Verify that the "py-print" command worksr   zpy-print argsr   z".*\nlocal 'args' = \(1, 2, 3\)\n.*Nr   r   r   r   r    r     s    
zPyPrintTests.test_basic_commandr   c                 C   s&   | j |  g dd}| |d d S )N)r   r   z
py-print cz
py-print bz
py-print ar   z3.*\nlocal 'c' = 3\nlocal 'b' = 2\nlocal 'a' = 1\n.*r   r   r   r   r    test_print_after_up  s    
z PyPrintTests.test_print_after_upc                 C   s&   | j |  ddgd}| |d d S )Nr   zpy-print __name__r   z&.*\nglobal '__name__' = '__main__'\n.*r   r   r   r   r    test_printing_global  s    
z!PyPrintTests.test_printing_globalc                 C   s&   | j |  ddgd}| |d d S )Nr   zpy-print lenr   zV.*\nbuiltin 'len' = <built-in method len of module object at remote 0x-?[0-9a-f]+>\n.*r   r   r   r   r    test_printing_builtin  s    
z"PyPrintTests.test_printing_builtinN)rm   rn   ro   r   r   r   r   r   r   r   r   r   r   r   r   r    r     s"   


r   c                   @   sD   e Zd Zee ddd Zeedee ddd Z	dS )PyLocalsTestsr   c                 C   s&   | j |  ddgd}| |d d S )Nr   	py-localsr   z.*\nargs = \(1, 2, 3\)\n.*r   r   r   r   r    r     s    
z PyLocalsTests.test_basic_commandr   c                 C   s&   | j |  g dd}| |d d S )N)r   r   r   r   z.*\na = 1\nb = 2\nc = 3\n.*r   r   r   r   r    test_locals_after_up  s    
z"PyLocalsTests.test_locals_after_upN)
rm   rn   ro   r   r   r   r   r   r   r   r   r   r   r    r     s   

r   c                  C   s4   t jr0tdttf  t D ]} td|   qd S )NzGDB version %s.%s:z    )r   verboserT   r9   r:   gdb_versionrS   )r]   r   r   r    setUpModule  s    r   __main__)3r5   platformr   r   rO   r*   r   r   testr   Ztest.supportr   r   r!   r   r9   r:   r   Zis_python_buildZpython_compilerr+   pathr   dirnamerP   r;   rL   r/   rN   r@   Zgdbpy_versionrB   Zgdbpy_errorsrf   r   rD   r   r`   r   ZPGOZTestCaserF   rq   r   r   r   r   r   r   rm   mainr   r   r   r    <module>   sz   




	 "   (- V#
