1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
7 import xml
.etree
.ElementTree
12 def AssertRaises(exc_class
, func
):
18 raise AssertionError('Function did not raise %r' % exc_class
)
21 def GetTargetArch(connection
):
22 """Get the CPU architecture of the NaCl application."""
23 reply
= connection
.RspRequest('qXfer:features:read:target.xml:0,fff')
24 assert reply
[0] == 'l', reply
25 tree
= xml
.etree
.ElementTree
.fromstring(reply
[1:])
26 arch_tag
= tree
.find('architecture')
27 assert arch_tag
is not None, reply
28 return arch_tag
.text
.strip()
31 def ReverseBytes(byte_string
):
32 """Reverse bytes in the hex string: '09ab' -> 'ab09'. This converts
33 little-endian number in the hex string to its normal string representation.
35 assert len(byte_string
) % 2 == 0, byte_string
36 return ''.join([byte_string
[i
- 2 : i
]
37 for i
in xrange(len(byte_string
), 0, -2)])
40 def GetProgCtrString(connection
, arch
):
41 """Get current execution point."""
42 registers
= connection
.RspRequest('g')
43 # PC register indices can be found in
44 # native_client/src/trusted/debug_stub/abi.cc in AbiInit function.
47 return ReverseBytes(registers
[8 * 8 : 8 * 8 + 8])
48 if arch
== 'i386:x86-64':
50 return ReverseBytes(registers
[16 * 16 : 16 * 16 + 8])
53 return ReverseBytes(registers
[15 * 8 : 15 * 8 + 8])
54 raise AssertionError('Unknown architecture: %s' % arch
)
57 def TestContinue(connection
):
58 # Once the NaCl test module reports that the test passed, the NaCl <embed>
59 # element is removed from the page. The NaCl module will be killed by the
60 # browser which will appear as EOF (end-of-file) on the debug stub socket.
61 AssertRaises(gdb_rsp
.EofOnReplyException
,
62 lambda: connection
.RspRequest('vCont;c'))
65 def TestBreakpoint(connection
):
66 # Breakpoints and single-stepping might interfere with Chrome sandbox. So we
67 # check that they work properly in this test.
68 arch
= GetTargetArch(connection
)
69 registers
= connection
.RspRequest('g')
70 pc
= GetProgCtrString(connection
, arch
)
72 result
= connection
.RspRequest('Z0,%s,1' % pc
)
73 assert result
== 'OK', result
74 # Check that we stopped at breakpoint
75 result
= connection
.RspRequest('vCont;c')
76 stop_reply
= re
.compile(r
'T05thread:(\d+);')
77 assert stop_reply
.match(result
), result
78 thread
= stop_reply
.match(result
).group(1)
79 # Check that registers haven't changed
80 result
= connection
.RspRequest('g')
81 assert result
== registers
, (result
, registers
)
83 result
= connection
.RspRequest('z0,%s,1' % pc
)
84 assert result
== 'OK', result
85 # Check single stepping
86 result
= connection
.RspRequest('vCont;s:%s' % thread
)
87 assert result
== 'T05thread:%s;' % thread
, result
88 assert pc
!= GetProgCtrString(connection
, arch
)
89 # Check that we terminate normally
90 AssertRaises(gdb_rsp
.EofOnReplyException
,
91 lambda: connection
.RspRequest('vCont;c'))
97 connection
= gdb_rsp
.GdbRspConnection(('localhost', port
))
98 if name
== 'continue':
99 TestContinue(connection
)
100 elif name
== 'breakpoint':
101 TestBreakpoint(connection
)
103 raise AssertionError('Unknown test name: %r' % name
)
106 if __name__
== '__main__':