blob: 474ae062059d7b18846843fbc3cc67e76350d857 [file] [log] [blame]
Johnny Chen37f99fd2011-03-01 02:20:14 +00001"""
Johnny Chen90aa5942011-03-01 18:51:47 +00002Test SBProcess APIs, including ReadMemory(), WriteMemory(), and others.
Johnny Chen37f99fd2011-03-01 02:20:14 +00003"""
4
5import os, time
6import unittest2
7import lldb
Johnny Chend61816b2011-03-03 01:41:57 +00008from lldbutil import get_stopped_thread
Johnny Chen37f99fd2011-03-01 02:20:14 +00009from lldbtest import *
10
Johnny Chen37f99fd2011-03-01 02:20:14 +000011class ProcessAPITestCase(TestBase):
12
13 mydir = os.path.join("python_api", "process")
14
Johnny Chen90aa5942011-03-01 18:51:47 +000015 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
Johnny Chen37f99fd2011-03-01 02:20:14 +000016 @python_api_test
Johnny Chen90aa5942011-03-01 18:51:47 +000017 def test_read_memory_with_dsym(self):
18 """Test Python SBProcess.ReadMemory() API."""
Johnny Chen37f99fd2011-03-01 02:20:14 +000019 self.buildDsym()
Johnny Chen90aa5942011-03-01 18:51:47 +000020 self.read_memory()
Johnny Chen37f99fd2011-03-01 02:20:14 +000021
22 @python_api_test
Johnny Chen90aa5942011-03-01 18:51:47 +000023 def test_read_memory_with_dwarf(self):
24 """Test Python SBProcess.ReadMemory() API."""
Johnny Chen37f99fd2011-03-01 02:20:14 +000025 self.buildDwarf()
Johnny Chen90aa5942011-03-01 18:51:47 +000026 self.read_memory()
27
28 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
29 @python_api_test
30 def test_write_memory_with_dsym(self):
31 """Test Python SBProcess.WriteMemory() API."""
32 self.buildDsym()
33 self.write_memory()
34
35 @python_api_test
36 def test_write_memory_with_dwarf(self):
37 """Test Python SBProcess.WriteMemory() API."""
38 self.buildDwarf()
39 self.write_memory()
Johnny Chen37f99fd2011-03-01 02:20:14 +000040
Johnny Chencf386e22011-03-01 22:56:31 +000041 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
42 @python_api_test
43 def test_access_my_int_with_dsym(self):
44 """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
45 self.buildDsym()
46 self.access_my_int()
47
48 @python_api_test
49 def test_access_my_int_with_dwarf(self):
50 """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
51 self.buildDwarf()
52 self.access_my_int()
53
Johnny Chen37f99fd2011-03-01 02:20:14 +000054 def setUp(self):
55 # Call super's setUp().
56 TestBase.setUp(self)
57 # Find the line number to break inside main().
58 self.line = line_number("main.cpp", "// Set break point at this line and check variable 'my_char'.")
59
Johnny Chen90aa5942011-03-01 18:51:47 +000060 def read_memory(self):
61 """Test Python SBProcess.ReadMemory() API."""
Johnny Chen37f99fd2011-03-01 02:20:14 +000062 exe = os.path.join(os.getcwd(), "a.out")
63 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
64
65 target = self.dbg.CreateTarget(exe)
66 self.assertTrue(target.IsValid(), VALID_TARGET)
67
68 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
69 self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT)
70
71 # Launch the process, and do not stop at the entry point.
72 error = lldb.SBError()
73 self.process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error)
74
Johnny Chend61816b2011-03-03 01:41:57 +000075 thread = get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
76 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
77 frame = thread.GetFrameAtIndex(0)
Johnny Chen37f99fd2011-03-01 02:20:14 +000078
79 # Get the SBValue for the global variable 'my_char'.
80 val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal)
Johnny Chen37f99fd2011-03-01 02:20:14 +000081 self.DebugSBValue(frame, val)
82
Johnny Chen90aa5942011-03-01 18:51:47 +000083 # If the variable does not have a load address, there's no sense continuing.
84 if not val.GetLocation(frame).startswith("0x"):
85 return
86
87 # OK, let's get the hex location of the variable.
88 location = int(val.GetLocation(frame), 16)
89
Johnny Chen37f99fd2011-03-01 02:20:14 +000090 # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
91 # expect to get a Python string as the result object!
92 content = self.process.ReadMemory(location, 1, error)
Johnny Chen90aa5942011-03-01 18:51:47 +000093 if not error.Success():
94 self.fail("SBProcess.ReadMemory() failed")
95 print "memory content:", content
Johnny Chen37f99fd2011-03-01 02:20:14 +000096
97 self.expect(content, "Result from SBProcess.ReadMemory() matches our expected output: 'x'",
98 exe=False,
99 startstr = 'x')
100
Johnny Chen90aa5942011-03-01 18:51:47 +0000101 def write_memory(self):
102 """Test Python SBProcess.WriteMemory() API."""
103 exe = os.path.join(os.getcwd(), "a.out")
104 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000105
Johnny Chen90aa5942011-03-01 18:51:47 +0000106 target = self.dbg.CreateTarget(exe)
107 self.assertTrue(target.IsValid(), VALID_TARGET)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000108
Johnny Chen90aa5942011-03-01 18:51:47 +0000109 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
110 self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000111
Johnny Chen90aa5942011-03-01 18:51:47 +0000112 # Launch the process, and do not stop at the entry point.
113 error = lldb.SBError()
114 self.process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000115
Johnny Chend61816b2011-03-03 01:41:57 +0000116 thread = get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
117 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
118 frame = thread.GetFrameAtIndex(0)
Johnny Chen90aa5942011-03-01 18:51:47 +0000119
120 # Get the SBValue for the global variable 'my_char'.
121 val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal)
122 self.DebugSBValue(frame, val)
123
124 # If the variable does not have a load address, there's no sense continuing.
125 if not val.GetLocation(frame).startswith("0x"):
126 return
127
128 # OK, let's get the hex location of the variable.
129 location = int(val.GetLocation(frame), 16)
130
131 # The program logic makes the 'my_char' variable to have memory content as 'x'.
132 # But we want to use the WriteMemory() API to assign 'a' to the variable.
133
134 # Now use WriteMemory() API to write 'a' into the global variable.
135 result = self.process.WriteMemory(location, 'a', error)
136 if not error.Success() or result != 1:
137 self.fail("SBProcess.WriteMemory() failed")
138
139 # Read from the memory location. This time it should be 'a'.
140 # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
141 # expect to get a Python string as the result object!
142 content = self.process.ReadMemory(location, 1, error)
143 if not error.Success():
144 self.fail("SBProcess.ReadMemory() failed")
145 print "memory content:", content
146
147 self.expect(content, "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
148 exe=False,
149 startstr = 'a')
Johnny Chen37f99fd2011-03-01 02:20:14 +0000150
Johnny Chencf386e22011-03-01 22:56:31 +0000151 def access_my_int(self):
152 """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
153 exe = os.path.join(os.getcwd(), "a.out")
154 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
155
156 target = self.dbg.CreateTarget(exe)
157 self.assertTrue(target.IsValid(), VALID_TARGET)
158
159 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
160 self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT)
161
162 # Launch the process, and do not stop at the entry point.
163 error = lldb.SBError()
164 self.process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error)
165
Johnny Chend61816b2011-03-03 01:41:57 +0000166 thread = get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
167 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
168 frame = thread.GetFrameAtIndex(0)
Johnny Chencf386e22011-03-01 22:56:31 +0000169
170 # Get the SBValue for the global variable 'my_int'.
171 val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
172 self.DebugSBValue(frame, val)
173
174 # If the variable does not have a load address, there's no sense continuing.
175 if not val.GetLocation(frame).startswith("0x"):
176 return
177
178 # OK, let's get the hex location of the variable.
179 location = int(val.GetLocation(frame), 16)
180
Johnny Chen4e90a7e2011-03-02 19:49:27 +0000181 # Note that the canonical from of the bytearray is little endian.
Johnny Chen43766d62011-03-02 01:36:45 +0000182 from lldbutil import int_to_bytearray, bytearray_to_int
Johnny Chen4e90a7e2011-03-02 19:49:27 +0000183
Johnny Chencf386e22011-03-01 22:56:31 +0000184 byteSize = val.GetByteSize()
Johnny Chen43766d62011-03-02 01:36:45 +0000185 bytes = int_to_bytearray(256, byteSize)
Johnny Chencf386e22011-03-01 22:56:31 +0000186
Johnny Chen43766d62011-03-02 01:36:45 +0000187 byteOrder = self.process.GetByteOrder()
Johnny Chencf386e22011-03-01 22:56:31 +0000188 if byteOrder == lldb.eByteOrderBig:
Johnny Chen43766d62011-03-02 01:36:45 +0000189 bytes.reverse()
Johnny Chencf386e22011-03-01 22:56:31 +0000190 elif byteOrder == lldb.eByteOrderLittle:
Johnny Chen43766d62011-03-02 01:36:45 +0000191 pass
Johnny Chencf386e22011-03-01 22:56:31 +0000192 else:
193 # Neither big endian nor little endian? Return for now.
Johnny Chen43766d62011-03-02 01:36:45 +0000194 # Add more logic here if we want to handle other types.
Johnny Chencf386e22011-03-01 22:56:31 +0000195 return
196
197 # The program logic makes the 'my_int' variable to have int type and value of 0.
198 # But we want to use the WriteMemory() API to assign 256 to the variable.
199
200 # Now use WriteMemory() API to write 256 into the global variable.
201 new_value = str(bytes)
202 result = self.process.WriteMemory(location, new_value, error)
203 if not error.Success() or result != byteSize:
204 self.fail("SBProcess.WriteMemory() failed")
205
206 # Get the SBValue for the global variable 'my_int' again, with its updated value.
207 val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
208 self.expect(val.GetValue(frame),
209 "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
210 exe=False,
211 startstr = '256')
212
213 # Now read the memory content. The bytearray should have (byte)1 as the second element.
214 content = self.process.ReadMemory(location, byteSize, error)
215 if not error.Success():
216 self.fail("SBProcess.ReadMemory() failed")
Johnny Chen4e90a7e2011-03-02 19:49:27 +0000217
218 # Use "ascii" as the encoding because each element of 'content' is in the range [0..255].
Johnny Chencf386e22011-03-01 22:56:31 +0000219 new_bytes = bytearray(content, "ascii")
Johnny Chen43766d62011-03-02 01:36:45 +0000220
221 # The bytearray_to_int utility function expects a little endian bytearray.
Johnny Chencf386e22011-03-01 22:56:31 +0000222 if byteOrder == lldb.eByteOrderBig:
Johnny Chen43766d62011-03-02 01:36:45 +0000223 new_bytes.reverse()
224
225 new_value = bytearray_to_int(new_bytes, byteSize)
226 if new_value != 256:
227 self.fail("Memory content read from 'my_int' does not match (int)256")
Johnny Chencf386e22011-03-01 22:56:31 +0000228
229 # Dump the memory content....
230 for i in new_bytes:
231 print "byte:", i
232
Johnny Chen37f99fd2011-03-01 02:20:14 +0000233
234if __name__ == '__main__':
235 import atexit
236 lldb.SBDebugger.Initialize()
237 atexit.register(lambda: lldb.SBDebugger.Terminate())
238 unittest2.main()