blob: 4718b2786193f3e056d25ec24ed7a3368af691cb [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 Chen24086bc2012-04-06 19:54:10 +000017 @dsym_test
Johnny Chen90aa5942011-03-01 18:51:47 +000018 def test_read_memory_with_dsym(self):
19 """Test Python SBProcess.ReadMemory() API."""
Johnny Chen37f99fd2011-03-01 02:20:14 +000020 self.buildDsym()
Johnny Chen90aa5942011-03-01 18:51:47 +000021 self.read_memory()
Johnny Chen37f99fd2011-03-01 02:20:14 +000022
23 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000024 @dwarf_test
Johnny Chen90aa5942011-03-01 18:51:47 +000025 def test_read_memory_with_dwarf(self):
26 """Test Python SBProcess.ReadMemory() API."""
Johnny Chen37f99fd2011-03-01 02:20:14 +000027 self.buildDwarf()
Johnny Chen90aa5942011-03-01 18:51:47 +000028 self.read_memory()
29
30 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
31 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000032 @dsym_test
Johnny Chen90aa5942011-03-01 18:51:47 +000033 def test_write_memory_with_dsym(self):
34 """Test Python SBProcess.WriteMemory() API."""
35 self.buildDsym()
36 self.write_memory()
37
38 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000039 @dwarf_test
Johnny Chen90aa5942011-03-01 18:51:47 +000040 def test_write_memory_with_dwarf(self):
41 """Test Python SBProcess.WriteMemory() API."""
42 self.buildDwarf()
43 self.write_memory()
Johnny Chen37f99fd2011-03-01 02:20:14 +000044
Johnny Chencf386e22011-03-01 22:56:31 +000045 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
46 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000047 @dsym_test
Johnny Chencf386e22011-03-01 22:56:31 +000048 def test_access_my_int_with_dsym(self):
49 """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
50 self.buildDsym()
51 self.access_my_int()
52
53 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000054 @dwarf_test
Johnny Chencf386e22011-03-01 22:56:31 +000055 def test_access_my_int_with_dwarf(self):
56 """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
57 self.buildDwarf()
58 self.access_my_int()
59
Johnny Chen930e3ad2011-03-05 01:20:11 +000060 @python_api_test
61 def test_remote_launch(self):
62 """Test SBProcess.RemoteLaunch() API with a process not in eStateConnected, and it should fail."""
63 self.buildDefault()
64 self.remote_launch_should_fail()
65
Johnny Chenf9ef60d2012-05-23 22:34:34 +000066 @python_api_test
67 def test_get_num_supported_hardware_watchpoints(self):
68 """Test SBProcess.GetNumSupportedHardwareWatchpoints() API with a process."""
69 self.buildDefault()
70 self.get_num_supported_hardware_watchpoints()
71
Johnny Chen37f99fd2011-03-01 02:20:14 +000072 def setUp(self):
73 # Call super's setUp().
74 TestBase.setUp(self)
75 # Find the line number to break inside main().
76 self.line = line_number("main.cpp", "// Set break point at this line and check variable 'my_char'.")
77
Johnny Chen90aa5942011-03-01 18:51:47 +000078 def read_memory(self):
79 """Test Python SBProcess.ReadMemory() API."""
Johnny Chen37f99fd2011-03-01 02:20:14 +000080 exe = os.path.join(os.getcwd(), "a.out")
81 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
82
83 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +000084 self.assertTrue(target, VALID_TARGET)
Johnny Chen37f99fd2011-03-01 02:20:14 +000085
86 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
Johnny Chen4ebd0192011-05-24 18:22:45 +000087 self.assertTrue(breakpoint, VALID_BREAKPOINT)
Johnny Chen37f99fd2011-03-01 02:20:14 +000088
89 # Launch the process, and do not stop at the entry point.
Johnny Chen1d3e8802011-07-11 23:38:23 +000090 process = target.LaunchSimple(None, None, os.getcwd())
Johnny Chen37f99fd2011-03-01 02:20:14 +000091
Johnny Chen5a0bee72011-06-15 22:14:12 +000092 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Johnny Chend61816b2011-03-03 01:41:57 +000093 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
94 frame = thread.GetFrameAtIndex(0)
Johnny Chen37f99fd2011-03-01 02:20:14 +000095
96 # Get the SBValue for the global variable 'my_char'.
97 val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal)
Johnny Chen9a07aba2011-07-11 20:06:28 +000098 self.DebugSBValue(val)
Johnny Chen37f99fd2011-03-01 02:20:14 +000099
100 # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
101 # expect to get a Python string as the result object!
Johnny Chen1d3e8802011-07-11 23:38:23 +0000102 error = lldb.SBError()
Johnny Chen7cc3d312011-12-16 01:56:27 +0000103 self.assertFalse(val.TypeIsPointerType())
104 content = process.ReadMemory(val.AddressOf().GetValueAsUnsigned(), 1, error)
Johnny Chen90aa5942011-03-01 18:51:47 +0000105 if not error.Success():
106 self.fail("SBProcess.ReadMemory() failed")
Johnny Chen90da3cc2011-04-19 19:49:09 +0000107 if self.TraceOn():
108 print "memory content:", content
Johnny Chen37f99fd2011-03-01 02:20:14 +0000109
110 self.expect(content, "Result from SBProcess.ReadMemory() matches our expected output: 'x'",
111 exe=False,
112 startstr = 'x')
113
Johnny Chene7e8af82011-12-16 00:25:30 +0000114 # Read (char *)my_char_ptr.
115 val = frame.FindValue("my_char_ptr", lldb.eValueTypeVariableGlobal)
116 self.DebugSBValue(val)
117 cstring = process.ReadCStringFromMemory(val.GetValueAsUnsigned(), 256, error)
118 if not error.Success():
119 self.fail("SBProcess.ReadCStringFromMemory() failed")
120 if self.TraceOn():
121 print "cstring read is:", cstring
122
123 self.expect(cstring, "Result from SBProcess.ReadCStringFromMemory() matches our expected output",
124 exe=False,
125 startstr = 'Does it work?')
126
Johnny Chen6e55cd52011-12-15 23:30:05 +0000127 # Get the SBValue for the global variable 'my_cstring'.
128 val = frame.FindValue("my_cstring", lldb.eValueTypeVariableGlobal)
129 self.DebugSBValue(val)
130
Johnny Chen6e55cd52011-12-15 23:30:05 +0000131 # Due to the typemap magic (see lldb.swig), we pass in 256 to read at most 256 bytes
132 # from the address, and expect to get a Python string as the result object!
Johnny Chen7cc3d312011-12-16 01:56:27 +0000133 self.assertFalse(val.TypeIsPointerType())
134 cstring = process.ReadCStringFromMemory(val.AddressOf().GetValueAsUnsigned(), 256, error)
Johnny Chen6e55cd52011-12-15 23:30:05 +0000135 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
Johnny Chen7cc3d312011-12-16 01:56:27 +0000148 # Due to the typemap magic (see lldb.swig), we pass in 4 to read 4 bytes
Johnny Chen6e55cd52011-12-15 23:30:05 +0000149 # from the address, and expect to get an int as the result!
Johnny Chen7cc3d312011-12-16 01:56:27 +0000150 self.assertFalse(val.TypeIsPointerType())
151 my_uint32 = process.ReadUnsignedFromMemory(val.AddressOf().GetValueAsUnsigned(), 4, error)
Johnny Chen6e55cd52011-12-15 23:30:05 +0000152 if not error.Success():
153 self.fail("SBProcess.ReadCStringFromMemory() failed")
154 if self.TraceOn():
155 print "uint32 read is:", my_uint32
156
157 if my_uint32 != 12345:
158 self.fail("Result from SBProcess.ReadUnsignedFromMemory() does not match our expected output")
159
Johnny Chen90aa5942011-03-01 18:51:47 +0000160 def write_memory(self):
161 """Test Python SBProcess.WriteMemory() API."""
162 exe = os.path.join(os.getcwd(), "a.out")
163 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000164
Johnny Chen90aa5942011-03-01 18:51:47 +0000165 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000166 self.assertTrue(target, VALID_TARGET)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000167
Johnny Chen90aa5942011-03-01 18:51:47 +0000168 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000169 self.assertTrue(breakpoint, VALID_BREAKPOINT)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000170
Johnny Chen90aa5942011-03-01 18:51:47 +0000171 # Launch the process, and do not stop at the entry point.
Johnny Chen1d3e8802011-07-11 23:38:23 +0000172 process = target.LaunchSimple(None, None, os.getcwd())
Johnny Chen37f99fd2011-03-01 02:20:14 +0000173
Johnny Chen5a0bee72011-06-15 22:14:12 +0000174 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Johnny Chend61816b2011-03-03 01:41:57 +0000175 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
176 frame = thread.GetFrameAtIndex(0)
Johnny Chen90aa5942011-03-01 18:51:47 +0000177
178 # Get the SBValue for the global variable 'my_char'.
179 val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal)
Johnny Chen9a07aba2011-07-11 20:06:28 +0000180 self.DebugSBValue(val)
Johnny Chen90aa5942011-03-01 18:51:47 +0000181
182 # If the variable does not have a load address, there's no sense continuing.
Greg Claytonfe42ac42011-08-03 22:57:10 +0000183 if not val.GetLocation().startswith("0x"):
Johnny Chen90aa5942011-03-01 18:51:47 +0000184 return
185
186 # OK, let's get the hex location of the variable.
Greg Claytonfe42ac42011-08-03 22:57:10 +0000187 location = int(val.GetLocation(), 16)
Johnny Chen90aa5942011-03-01 18:51:47 +0000188
189 # The program logic makes the 'my_char' variable to have memory content as 'x'.
190 # But we want to use the WriteMemory() API to assign 'a' to the variable.
191
192 # Now use WriteMemory() API to write 'a' into the global variable.
Johnny Chen1d3e8802011-07-11 23:38:23 +0000193 error = lldb.SBError()
Johnny Chen5a0bee72011-06-15 22:14:12 +0000194 result = process.WriteMemory(location, 'a', error)
Johnny Chen90aa5942011-03-01 18:51:47 +0000195 if not error.Success() or result != 1:
196 self.fail("SBProcess.WriteMemory() failed")
197
198 # Read from the memory location. This time it should be 'a'.
199 # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
200 # expect to get a Python string as the result object!
Johnny Chen5a0bee72011-06-15 22:14:12 +0000201 content = process.ReadMemory(location, 1, error)
Johnny Chen90aa5942011-03-01 18:51:47 +0000202 if not error.Success():
203 self.fail("SBProcess.ReadMemory() failed")
Johnny Chen90da3cc2011-04-19 19:49:09 +0000204 if self.TraceOn():
205 print "memory content:", content
Johnny Chen90aa5942011-03-01 18:51:47 +0000206
207 self.expect(content, "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
208 exe=False,
209 startstr = 'a')
Johnny Chen37f99fd2011-03-01 02:20:14 +0000210
Johnny Chencf386e22011-03-01 22:56:31 +0000211 def access_my_int(self):
212 """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
213 exe = os.path.join(os.getcwd(), "a.out")
214 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
215
216 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000217 self.assertTrue(target, VALID_TARGET)
Johnny Chencf386e22011-03-01 22:56:31 +0000218
219 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000220 self.assertTrue(breakpoint, VALID_BREAKPOINT)
Johnny Chencf386e22011-03-01 22:56:31 +0000221
222 # Launch the process, and do not stop at the entry point.
Johnny Chen1d3e8802011-07-11 23:38:23 +0000223 process = target.LaunchSimple(None, None, os.getcwd())
Johnny Chencf386e22011-03-01 22:56:31 +0000224
Johnny Chen5a0bee72011-06-15 22:14:12 +0000225 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Johnny Chend61816b2011-03-03 01:41:57 +0000226 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
227 frame = thread.GetFrameAtIndex(0)
Johnny Chencf386e22011-03-01 22:56:31 +0000228
229 # Get the SBValue for the global variable 'my_int'.
230 val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
Johnny Chen9a07aba2011-07-11 20:06:28 +0000231 self.DebugSBValue(val)
Johnny Chencf386e22011-03-01 22:56:31 +0000232
233 # If the variable does not have a load address, there's no sense continuing.
Greg Claytonfe42ac42011-08-03 22:57:10 +0000234 if not val.GetLocation().startswith("0x"):
Johnny Chencf386e22011-03-01 22:56:31 +0000235 return
236
237 # OK, let's get the hex location of the variable.
Greg Claytonfe42ac42011-08-03 22:57:10 +0000238 location = int(val.GetLocation(), 16)
Johnny Chencf386e22011-03-01 22:56:31 +0000239
Johnny Chen4e90a7e2011-03-02 19:49:27 +0000240 # Note that the canonical from of the bytearray is little endian.
Johnny Chen43766d62011-03-02 01:36:45 +0000241 from lldbutil import int_to_bytearray, bytearray_to_int
Johnny Chen4e90a7e2011-03-02 19:49:27 +0000242
Johnny Chencf386e22011-03-01 22:56:31 +0000243 byteSize = val.GetByteSize()
Johnny Chen43766d62011-03-02 01:36:45 +0000244 bytes = int_to_bytearray(256, byteSize)
Johnny Chencf386e22011-03-01 22:56:31 +0000245
Johnny Chen5a0bee72011-06-15 22:14:12 +0000246 byteOrder = process.GetByteOrder()
Johnny Chencf386e22011-03-01 22:56:31 +0000247 if byteOrder == lldb.eByteOrderBig:
Johnny Chen43766d62011-03-02 01:36:45 +0000248 bytes.reverse()
Johnny Chencf386e22011-03-01 22:56:31 +0000249 elif byteOrder == lldb.eByteOrderLittle:
Johnny Chen43766d62011-03-02 01:36:45 +0000250 pass
Johnny Chencf386e22011-03-01 22:56:31 +0000251 else:
252 # Neither big endian nor little endian? Return for now.
Johnny Chen43766d62011-03-02 01:36:45 +0000253 # Add more logic here if we want to handle other types.
Johnny Chencf386e22011-03-01 22:56:31 +0000254 return
255
256 # The program logic makes the 'my_int' variable to have int type and value of 0.
257 # But we want to use the WriteMemory() API to assign 256 to the variable.
258
259 # Now use WriteMemory() API to write 256 into the global variable.
260 new_value = str(bytes)
Johnny Chen1d3e8802011-07-11 23:38:23 +0000261 error = lldb.SBError()
Johnny Chen5a0bee72011-06-15 22:14:12 +0000262 result = process.WriteMemory(location, new_value, error)
Johnny Chencf386e22011-03-01 22:56:31 +0000263 if not error.Success() or result != byteSize:
264 self.fail("SBProcess.WriteMemory() failed")
265
Jim Ingham78a685a2011-04-16 00:01:13 +0000266 # Make sure that the val we got originally updates itself to notice the change:
Greg Claytonfe42ac42011-08-03 22:57:10 +0000267 self.expect(val.GetValue(),
Jim Ingham78a685a2011-04-16 00:01:13 +0000268 "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
269 exe=False,
270 startstr = '256')
271
272 # 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 +0000273 val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
Greg Claytonfe42ac42011-08-03 22:57:10 +0000274 self.expect(val.GetValue(),
Johnny Chencf386e22011-03-01 22:56:31 +0000275 "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
276 exe=False,
277 startstr = '256')
278
279 # Now read the memory content. The bytearray should have (byte)1 as the second element.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000280 content = process.ReadMemory(location, byteSize, error)
Johnny Chencf386e22011-03-01 22:56:31 +0000281 if not error.Success():
282 self.fail("SBProcess.ReadMemory() failed")
Johnny Chen4e90a7e2011-03-02 19:49:27 +0000283
284 # Use "ascii" as the encoding because each element of 'content' is in the range [0..255].
Johnny Chencf386e22011-03-01 22:56:31 +0000285 new_bytes = bytearray(content, "ascii")
Johnny Chen43766d62011-03-02 01:36:45 +0000286
287 # The bytearray_to_int utility function expects a little endian bytearray.
Johnny Chencf386e22011-03-01 22:56:31 +0000288 if byteOrder == lldb.eByteOrderBig:
Johnny Chen43766d62011-03-02 01:36:45 +0000289 new_bytes.reverse()
290
291 new_value = bytearray_to_int(new_bytes, byteSize)
292 if new_value != 256:
293 self.fail("Memory content read from 'my_int' does not match (int)256")
Johnny Chencf386e22011-03-01 22:56:31 +0000294
295 # Dump the memory content....
Johnny Chen90da3cc2011-04-19 19:49:09 +0000296 if self.TraceOn():
297 for i in new_bytes:
298 print "byte:", i
Johnny Chencf386e22011-03-01 22:56:31 +0000299
Johnny Chen930e3ad2011-03-05 01:20:11 +0000300 def remote_launch_should_fail(self):
301 """Test SBProcess.RemoteLaunch() API with a process not in eStateConnected, and it should fail."""
302 exe = os.path.join(os.getcwd(), "a.out")
303 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
304
305 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000306 self.assertTrue(target, VALID_TARGET)
Johnny Chen930e3ad2011-03-05 01:20:11 +0000307
308 # Launch the process, and do not stop at the entry point.
Johnny Chen1d3e8802011-07-11 23:38:23 +0000309 process = target.LaunchSimple(None, None, os.getcwd())
Johnny Chen930e3ad2011-03-05 01:20:11 +0000310
Johnny Chen90da3cc2011-04-19 19:49:09 +0000311 if self.TraceOn():
Johnny Chende90f1d2011-04-27 17:43:07 +0000312 print "process state:", state_type_to_str(process.GetState())
Johnny Chen930e3ad2011-03-05 01:20:11 +0000313 self.assertTrue(process.GetState() != lldb.eStateConnected)
314
Johnny Chen1d3e8802011-07-11 23:38:23 +0000315 error = lldb.SBError()
Johnny Chen930e3ad2011-03-05 01:20:11 +0000316 success = process.RemoteLaunch(None, None, None, None, None, None, 0, False, error)
317 self.assertTrue(not success, "RemoteLaunch() should fail for process state != eStateConnected")
318
Johnny Chenf9ef60d2012-05-23 22:34:34 +0000319 def get_num_supported_hardware_watchpoints(self):
320 """Test SBProcess.GetNumSupportedHardwareWatchpoints() API with a process."""
321 exe = os.path.join(os.getcwd(), "a.out")
322 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
323
324 target = self.dbg.CreateTarget(exe)
325 self.assertTrue(target, VALID_TARGET)
326
327 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
328 self.assertTrue(breakpoint, VALID_BREAKPOINT)
329
330 # Launch the process, and do not stop at the entry point.
331 process = target.LaunchSimple(None, None, os.getcwd())
332
333 error = lldb.SBError();
334 num = process.GetNumSupportedHardwareWatchpoints(error)
335 if self.TraceOn() and error.Success():
336 print "Number of supported hardware watchpoints: %d" % num
337
Johnny Chen37f99fd2011-03-01 02:20:14 +0000338
339if __name__ == '__main__':
340 import atexit
341 lldb.SBDebugger.Initialize()
342 atexit.register(lambda: lldb.SBDebugger.Terminate())
343 unittest2.main()