blob: 2c273e5b1ff2ff2533fd321c7e002fc77dd1ef38 [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 Chende90f1d2011-04-27 17:43:07 +00008from lldbutil import get_stopped_thread, state_type_to_str
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 Chen930e3ad2011-03-05 01:20:11 +000054 @python_api_test
55 def test_remote_launch(self):
56 """Test SBProcess.RemoteLaunch() API with a process not in eStateConnected, and it should fail."""
57 self.buildDefault()
58 self.remote_launch_should_fail()
59
Johnny Chen37f99fd2011-03-01 02:20:14 +000060 def setUp(self):
61 # Call super's setUp().
62 TestBase.setUp(self)
63 # Find the line number to break inside main().
64 self.line = line_number("main.cpp", "// Set break point at this line and check variable 'my_char'.")
65
Johnny Chen90aa5942011-03-01 18:51:47 +000066 def read_memory(self):
67 """Test Python SBProcess.ReadMemory() API."""
Johnny Chen37f99fd2011-03-01 02:20:14 +000068 exe = os.path.join(os.getcwd(), "a.out")
69 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
70
71 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +000072 self.assertTrue(target, VALID_TARGET)
Johnny Chen37f99fd2011-03-01 02:20:14 +000073
74 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
Johnny Chen4ebd0192011-05-24 18:22:45 +000075 self.assertTrue(breakpoint, VALID_BREAKPOINT)
Johnny Chen37f99fd2011-03-01 02:20:14 +000076
77 # Launch the process, and do not stop at the entry point.
Johnny Chen1d3e8802011-07-11 23:38:23 +000078 process = target.LaunchSimple(None, None, os.getcwd())
Johnny Chen37f99fd2011-03-01 02:20:14 +000079
Johnny Chen5a0bee72011-06-15 22:14:12 +000080 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Johnny Chend61816b2011-03-03 01:41:57 +000081 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
82 frame = thread.GetFrameAtIndex(0)
Johnny Chen37f99fd2011-03-01 02:20:14 +000083
84 # Get the SBValue for the global variable 'my_char'.
85 val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal)
Johnny Chen9a07aba2011-07-11 20:06:28 +000086 self.DebugSBValue(val)
Johnny Chen37f99fd2011-03-01 02:20:14 +000087
Johnny Chen90aa5942011-03-01 18:51:47 +000088 # If the variable does not have a load address, there's no sense continuing.
Greg Claytonfe42ac42011-08-03 22:57:10 +000089 if not val.GetLocation().startswith("0x"):
Johnny Chen90aa5942011-03-01 18:51:47 +000090 return
91
92 # OK, let's get the hex location of the variable.
Greg Claytonfe42ac42011-08-03 22:57:10 +000093 location = int(val.GetLocation(), 16)
Johnny Chen90aa5942011-03-01 18:51:47 +000094
Johnny Chen37f99fd2011-03-01 02:20:14 +000095 # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
96 # expect to get a Python string as the result object!
Johnny Chen1d3e8802011-07-11 23:38:23 +000097 error = lldb.SBError()
Johnny Chen5a0bee72011-06-15 22:14:12 +000098 content = process.ReadMemory(location, 1, error)
Johnny Chen90aa5942011-03-01 18:51:47 +000099 if not error.Success():
100 self.fail("SBProcess.ReadMemory() failed")
Johnny Chen90da3cc2011-04-19 19:49:09 +0000101 if self.TraceOn():
102 print "memory content:", content
Johnny Chen37f99fd2011-03-01 02:20:14 +0000103
104 self.expect(content, "Result from SBProcess.ReadMemory() matches our expected output: 'x'",
105 exe=False,
106 startstr = 'x')
107
Johnny Chene7e8af82011-12-16 00:25:30 +0000108 # Read (char *)my_char_ptr.
109 val = frame.FindValue("my_char_ptr", lldb.eValueTypeVariableGlobal)
110 self.DebugSBValue(val)
111 cstring = process.ReadCStringFromMemory(val.GetValueAsUnsigned(), 256, error)
112 if not error.Success():
113 self.fail("SBProcess.ReadCStringFromMemory() failed")
114 if self.TraceOn():
115 print "cstring read is:", cstring
116
117 self.expect(cstring, "Result from SBProcess.ReadCStringFromMemory() matches our expected output",
118 exe=False,
119 startstr = 'Does it work?')
120
Johnny Chen6e55cd52011-12-15 23:30:05 +0000121 # Get the SBValue for the global variable 'my_cstring'.
122 val = frame.FindValue("my_cstring", lldb.eValueTypeVariableGlobal)
123 self.DebugSBValue(val)
124
125 # If the variable does not have a load address, there's no sense continuing.
126 if not val.GetLocation().startswith("0x"):
127 return
128
129 # OK, let's get the hex location of the variable.
130 location = int(val.GetLocation(), 16)
131
132 # Due to the typemap magic (see lldb.swig), we pass in 256 to read at most 256 bytes
133 # from the address, and expect to get a Python string as the result object!
134 cstring = process.ReadCStringFromMemory(location, 256, error)
135 if not error.Success():
136 self.fail("SBProcess.ReadCStringFromMemory() failed")
137 if self.TraceOn():
138 print "cstring read is:", cstring
139
140 self.expect(cstring, "Result from SBProcess.ReadCStringFromMemory() matches our expected output",
141 exe=False,
142 startstr = 'lldb.SBProcess.ReadCStringFromMemory() works!')
143
144 # Get the SBValue for the global variable 'my_uint32'.
145 val = frame.FindValue("my_uint32", lldb.eValueTypeVariableGlobal)
146 self.DebugSBValue(val)
147
148 # If the variable does not have a load address, there's no sense continuing.
149 if not val.GetLocation().startswith("0x"):
150 return
151
152 # OK, let's get the hex location of the variable.
153 location = int(val.GetLocation(), 16)
154
155 # Due to the typemap magic (see lldb.swig), we pass in 4 to read at 4 bytes
156 # from the address, and expect to get an int as the result!
157 my_uint32 = process.ReadUnsignedFromMemory(location, 4, error)
158 if not error.Success():
159 self.fail("SBProcess.ReadCStringFromMemory() failed")
160 if self.TraceOn():
161 print "uint32 read is:", my_uint32
162
163 if my_uint32 != 12345:
164 self.fail("Result from SBProcess.ReadUnsignedFromMemory() does not match our expected output")
165
Johnny Chen90aa5942011-03-01 18:51:47 +0000166 def write_memory(self):
167 """Test Python SBProcess.WriteMemory() API."""
168 exe = os.path.join(os.getcwd(), "a.out")
169 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000170
Johnny Chen90aa5942011-03-01 18:51:47 +0000171 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000172 self.assertTrue(target, VALID_TARGET)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000173
Johnny Chen90aa5942011-03-01 18:51:47 +0000174 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000175 self.assertTrue(breakpoint, VALID_BREAKPOINT)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000176
Johnny Chen90aa5942011-03-01 18:51:47 +0000177 # Launch the process, and do not stop at the entry point.
Johnny Chen1d3e8802011-07-11 23:38:23 +0000178 process = target.LaunchSimple(None, None, os.getcwd())
Johnny Chen37f99fd2011-03-01 02:20:14 +0000179
Johnny Chen5a0bee72011-06-15 22:14:12 +0000180 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Johnny Chend61816b2011-03-03 01:41:57 +0000181 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
182 frame = thread.GetFrameAtIndex(0)
Johnny Chen90aa5942011-03-01 18:51:47 +0000183
184 # Get the SBValue for the global variable 'my_char'.
185 val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal)
Johnny Chen9a07aba2011-07-11 20:06:28 +0000186 self.DebugSBValue(val)
Johnny Chen90aa5942011-03-01 18:51:47 +0000187
188 # If the variable does not have a load address, there's no sense continuing.
Greg Claytonfe42ac42011-08-03 22:57:10 +0000189 if not val.GetLocation().startswith("0x"):
Johnny Chen90aa5942011-03-01 18:51:47 +0000190 return
191
192 # OK, let's get the hex location of the variable.
Greg Claytonfe42ac42011-08-03 22:57:10 +0000193 location = int(val.GetLocation(), 16)
Johnny Chen90aa5942011-03-01 18:51:47 +0000194
195 # The program logic makes the 'my_char' variable to have memory content as 'x'.
196 # But we want to use the WriteMemory() API to assign 'a' to the variable.
197
198 # Now use WriteMemory() API to write 'a' into the global variable.
Johnny Chen1d3e8802011-07-11 23:38:23 +0000199 error = lldb.SBError()
Johnny Chen5a0bee72011-06-15 22:14:12 +0000200 result = process.WriteMemory(location, 'a', error)
Johnny Chen90aa5942011-03-01 18:51:47 +0000201 if not error.Success() or result != 1:
202 self.fail("SBProcess.WriteMemory() failed")
203
204 # Read from the memory location. This time it should be 'a'.
205 # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
206 # expect to get a Python string as the result object!
Johnny Chen5a0bee72011-06-15 22:14:12 +0000207 content = process.ReadMemory(location, 1, error)
Johnny Chen90aa5942011-03-01 18:51:47 +0000208 if not error.Success():
209 self.fail("SBProcess.ReadMemory() failed")
Johnny Chen90da3cc2011-04-19 19:49:09 +0000210 if self.TraceOn():
211 print "memory content:", content
Johnny Chen90aa5942011-03-01 18:51:47 +0000212
213 self.expect(content, "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
214 exe=False,
215 startstr = 'a')
Johnny Chen37f99fd2011-03-01 02:20:14 +0000216
Johnny Chencf386e22011-03-01 22:56:31 +0000217 def access_my_int(self):
218 """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
219 exe = os.path.join(os.getcwd(), "a.out")
220 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
221
222 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000223 self.assertTrue(target, VALID_TARGET)
Johnny Chencf386e22011-03-01 22:56:31 +0000224
225 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000226 self.assertTrue(breakpoint, VALID_BREAKPOINT)
Johnny Chencf386e22011-03-01 22:56:31 +0000227
228 # Launch the process, and do not stop at the entry point.
Johnny Chen1d3e8802011-07-11 23:38:23 +0000229 process = target.LaunchSimple(None, None, os.getcwd())
Johnny Chencf386e22011-03-01 22:56:31 +0000230
Johnny Chen5a0bee72011-06-15 22:14:12 +0000231 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Johnny Chend61816b2011-03-03 01:41:57 +0000232 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
233 frame = thread.GetFrameAtIndex(0)
Johnny Chencf386e22011-03-01 22:56:31 +0000234
235 # Get the SBValue for the global variable 'my_int'.
236 val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
Johnny Chen9a07aba2011-07-11 20:06:28 +0000237 self.DebugSBValue(val)
Johnny Chencf386e22011-03-01 22:56:31 +0000238
239 # If the variable does not have a load address, there's no sense continuing.
Greg Claytonfe42ac42011-08-03 22:57:10 +0000240 if not val.GetLocation().startswith("0x"):
Johnny Chencf386e22011-03-01 22:56:31 +0000241 return
242
243 # OK, let's get the hex location of the variable.
Greg Claytonfe42ac42011-08-03 22:57:10 +0000244 location = int(val.GetLocation(), 16)
Johnny Chencf386e22011-03-01 22:56:31 +0000245
Johnny Chen4e90a7e2011-03-02 19:49:27 +0000246 # Note that the canonical from of the bytearray is little endian.
Johnny Chen43766d62011-03-02 01:36:45 +0000247 from lldbutil import int_to_bytearray, bytearray_to_int
Johnny Chen4e90a7e2011-03-02 19:49:27 +0000248
Johnny Chencf386e22011-03-01 22:56:31 +0000249 byteSize = val.GetByteSize()
Johnny Chen43766d62011-03-02 01:36:45 +0000250 bytes = int_to_bytearray(256, byteSize)
Johnny Chencf386e22011-03-01 22:56:31 +0000251
Johnny Chen5a0bee72011-06-15 22:14:12 +0000252 byteOrder = process.GetByteOrder()
Johnny Chencf386e22011-03-01 22:56:31 +0000253 if byteOrder == lldb.eByteOrderBig:
Johnny Chen43766d62011-03-02 01:36:45 +0000254 bytes.reverse()
Johnny Chencf386e22011-03-01 22:56:31 +0000255 elif byteOrder == lldb.eByteOrderLittle:
Johnny Chen43766d62011-03-02 01:36:45 +0000256 pass
Johnny Chencf386e22011-03-01 22:56:31 +0000257 else:
258 # Neither big endian nor little endian? Return for now.
Johnny Chen43766d62011-03-02 01:36:45 +0000259 # Add more logic here if we want to handle other types.
Johnny Chencf386e22011-03-01 22:56:31 +0000260 return
261
262 # The program logic makes the 'my_int' variable to have int type and value of 0.
263 # But we want to use the WriteMemory() API to assign 256 to the variable.
264
265 # Now use WriteMemory() API to write 256 into the global variable.
266 new_value = str(bytes)
Johnny Chen1d3e8802011-07-11 23:38:23 +0000267 error = lldb.SBError()
Johnny Chen5a0bee72011-06-15 22:14:12 +0000268 result = process.WriteMemory(location, new_value, error)
Johnny Chencf386e22011-03-01 22:56:31 +0000269 if not error.Success() or result != byteSize:
270 self.fail("SBProcess.WriteMemory() failed")
271
Jim Ingham78a685a2011-04-16 00:01:13 +0000272 # Make sure that the val we got originally updates itself to notice the change:
Greg Claytonfe42ac42011-08-03 22:57:10 +0000273 self.expect(val.GetValue(),
Jim Ingham78a685a2011-04-16 00:01:13 +0000274 "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
275 exe=False,
276 startstr = '256')
277
278 # And for grins, get the SBValue for the global variable 'my_int' again, to make sure that also tracks the new value:
Johnny Chencf386e22011-03-01 22:56:31 +0000279 val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
Greg Claytonfe42ac42011-08-03 22:57:10 +0000280 self.expect(val.GetValue(),
Johnny Chencf386e22011-03-01 22:56:31 +0000281 "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
282 exe=False,
283 startstr = '256')
284
285 # Now read the memory content. The bytearray should have (byte)1 as the second element.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000286 content = process.ReadMemory(location, byteSize, error)
Johnny Chencf386e22011-03-01 22:56:31 +0000287 if not error.Success():
288 self.fail("SBProcess.ReadMemory() failed")
Johnny Chen4e90a7e2011-03-02 19:49:27 +0000289
290 # Use "ascii" as the encoding because each element of 'content' is in the range [0..255].
Johnny Chencf386e22011-03-01 22:56:31 +0000291 new_bytes = bytearray(content, "ascii")
Johnny Chen43766d62011-03-02 01:36:45 +0000292
293 # The bytearray_to_int utility function expects a little endian bytearray.
Johnny Chencf386e22011-03-01 22:56:31 +0000294 if byteOrder == lldb.eByteOrderBig:
Johnny Chen43766d62011-03-02 01:36:45 +0000295 new_bytes.reverse()
296
297 new_value = bytearray_to_int(new_bytes, byteSize)
298 if new_value != 256:
299 self.fail("Memory content read from 'my_int' does not match (int)256")
Johnny Chencf386e22011-03-01 22:56:31 +0000300
301 # Dump the memory content....
Johnny Chen90da3cc2011-04-19 19:49:09 +0000302 if self.TraceOn():
303 for i in new_bytes:
304 print "byte:", i
Johnny Chencf386e22011-03-01 22:56:31 +0000305
Johnny Chen930e3ad2011-03-05 01:20:11 +0000306 def remote_launch_should_fail(self):
307 """Test SBProcess.RemoteLaunch() API with a process not in eStateConnected, and it should fail."""
308 exe = os.path.join(os.getcwd(), "a.out")
309 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
310
311 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000312 self.assertTrue(target, VALID_TARGET)
Johnny Chen930e3ad2011-03-05 01:20:11 +0000313
314 # Launch the process, and do not stop at the entry point.
Johnny Chen1d3e8802011-07-11 23:38:23 +0000315 process = target.LaunchSimple(None, None, os.getcwd())
Johnny Chen930e3ad2011-03-05 01:20:11 +0000316
Johnny Chen90da3cc2011-04-19 19:49:09 +0000317 if self.TraceOn():
Johnny Chende90f1d2011-04-27 17:43:07 +0000318 print "process state:", state_type_to_str(process.GetState())
Johnny Chen930e3ad2011-03-05 01:20:11 +0000319 self.assertTrue(process.GetState() != lldb.eStateConnected)
320
Johnny Chen1d3e8802011-07-11 23:38:23 +0000321 error = lldb.SBError()
Johnny Chen930e3ad2011-03-05 01:20:11 +0000322 success = process.RemoteLaunch(None, None, None, None, None, None, 0, False, error)
323 self.assertTrue(not success, "RemoteLaunch() should fail for process state != eStateConnected")
324
Johnny Chen37f99fd2011-03-01 02:20:14 +0000325
326if __name__ == '__main__':
327 import atexit
328 lldb.SBDebugger.Initialize()
329 atexit.register(lambda: lldb.SBDebugger.Terminate())
330 unittest2.main()