blob: c720d73b616c6e01465613b7565f47ab46940fae [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 Chen6e55cd52011-12-15 23:30:05 +0000108 # Get the SBValue for the global variable 'my_cstring'.
109 val = frame.FindValue("my_cstring", lldb.eValueTypeVariableGlobal)
110 self.DebugSBValue(val)
111
112 # If the variable does not have a load address, there's no sense continuing.
113 if not val.GetLocation().startswith("0x"):
114 return
115
116 # OK, let's get the hex location of the variable.
117 location = int(val.GetLocation(), 16)
118
119 # Due to the typemap magic (see lldb.swig), we pass in 256 to read at most 256 bytes
120 # from the address, and expect to get a Python string as the result object!
121 cstring = process.ReadCStringFromMemory(location, 256, error)
122 if not error.Success():
123 self.fail("SBProcess.ReadCStringFromMemory() failed")
124 if self.TraceOn():
125 print "cstring read is:", cstring
126
127 self.expect(cstring, "Result from SBProcess.ReadCStringFromMemory() matches our expected output",
128 exe=False,
129 startstr = 'lldb.SBProcess.ReadCStringFromMemory() works!')
130
131 # Get the SBValue for the global variable 'my_uint32'.
132 val = frame.FindValue("my_uint32", lldb.eValueTypeVariableGlobal)
133 self.DebugSBValue(val)
134
135 # If the variable does not have a load address, there's no sense continuing.
136 if not val.GetLocation().startswith("0x"):
137 return
138
139 # OK, let's get the hex location of the variable.
140 location = int(val.GetLocation(), 16)
141
142 # Due to the typemap magic (see lldb.swig), we pass in 4 to read at 4 bytes
143 # from the address, and expect to get an int as the result!
144 my_uint32 = process.ReadUnsignedFromMemory(location, 4, error)
145 if not error.Success():
146 self.fail("SBProcess.ReadCStringFromMemory() failed")
147 if self.TraceOn():
148 print "uint32 read is:", my_uint32
149
150 if my_uint32 != 12345:
151 self.fail("Result from SBProcess.ReadUnsignedFromMemory() does not match our expected output")
152
Johnny Chen90aa5942011-03-01 18:51:47 +0000153 def write_memory(self):
154 """Test Python SBProcess.WriteMemory() API."""
155 exe = os.path.join(os.getcwd(), "a.out")
156 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000157
Johnny Chen90aa5942011-03-01 18:51:47 +0000158 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000159 self.assertTrue(target, VALID_TARGET)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000160
Johnny Chen90aa5942011-03-01 18:51:47 +0000161 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000162 self.assertTrue(breakpoint, VALID_BREAKPOINT)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000163
Johnny Chen90aa5942011-03-01 18:51:47 +0000164 # Launch the process, and do not stop at the entry point.
Johnny Chen1d3e8802011-07-11 23:38:23 +0000165 process = target.LaunchSimple(None, None, os.getcwd())
Johnny Chen37f99fd2011-03-01 02:20:14 +0000166
Johnny Chen5a0bee72011-06-15 22:14:12 +0000167 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Johnny Chend61816b2011-03-03 01:41:57 +0000168 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
169 frame = thread.GetFrameAtIndex(0)
Johnny Chen90aa5942011-03-01 18:51:47 +0000170
171 # Get the SBValue for the global variable 'my_char'.
172 val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal)
Johnny Chen9a07aba2011-07-11 20:06:28 +0000173 self.DebugSBValue(val)
Johnny Chen90aa5942011-03-01 18:51:47 +0000174
175 # If the variable does not have a load address, there's no sense continuing.
Greg Claytonfe42ac42011-08-03 22:57:10 +0000176 if not val.GetLocation().startswith("0x"):
Johnny Chen90aa5942011-03-01 18:51:47 +0000177 return
178
179 # OK, let's get the hex location of the variable.
Greg Claytonfe42ac42011-08-03 22:57:10 +0000180 location = int(val.GetLocation(), 16)
Johnny Chen90aa5942011-03-01 18:51:47 +0000181
182 # The program logic makes the 'my_char' variable to have memory content as 'x'.
183 # But we want to use the WriteMemory() API to assign 'a' to the variable.
184
185 # Now use WriteMemory() API to write 'a' into the global variable.
Johnny Chen1d3e8802011-07-11 23:38:23 +0000186 error = lldb.SBError()
Johnny Chen5a0bee72011-06-15 22:14:12 +0000187 result = process.WriteMemory(location, 'a', error)
Johnny Chen90aa5942011-03-01 18:51:47 +0000188 if not error.Success() or result != 1:
189 self.fail("SBProcess.WriteMemory() failed")
190
191 # Read from the memory location. This time it should be 'a'.
192 # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
193 # expect to get a Python string as the result object!
Johnny Chen5a0bee72011-06-15 22:14:12 +0000194 content = process.ReadMemory(location, 1, error)
Johnny Chen90aa5942011-03-01 18:51:47 +0000195 if not error.Success():
196 self.fail("SBProcess.ReadMemory() failed")
Johnny Chen90da3cc2011-04-19 19:49:09 +0000197 if self.TraceOn():
198 print "memory content:", content
Johnny Chen90aa5942011-03-01 18:51:47 +0000199
200 self.expect(content, "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
201 exe=False,
202 startstr = 'a')
Johnny Chen37f99fd2011-03-01 02:20:14 +0000203
Johnny Chencf386e22011-03-01 22:56:31 +0000204 def access_my_int(self):
205 """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
206 exe = os.path.join(os.getcwd(), "a.out")
207 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
208
209 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000210 self.assertTrue(target, VALID_TARGET)
Johnny Chencf386e22011-03-01 22:56:31 +0000211
212 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000213 self.assertTrue(breakpoint, VALID_BREAKPOINT)
Johnny Chencf386e22011-03-01 22:56:31 +0000214
215 # Launch the process, and do not stop at the entry point.
Johnny Chen1d3e8802011-07-11 23:38:23 +0000216 process = target.LaunchSimple(None, None, os.getcwd())
Johnny Chencf386e22011-03-01 22:56:31 +0000217
Johnny Chen5a0bee72011-06-15 22:14:12 +0000218 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Johnny Chend61816b2011-03-03 01:41:57 +0000219 self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
220 frame = thread.GetFrameAtIndex(0)
Johnny Chencf386e22011-03-01 22:56:31 +0000221
222 # Get the SBValue for the global variable 'my_int'.
223 val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
Johnny Chen9a07aba2011-07-11 20:06:28 +0000224 self.DebugSBValue(val)
Johnny Chencf386e22011-03-01 22:56:31 +0000225
226 # If the variable does not have a load address, there's no sense continuing.
Greg Claytonfe42ac42011-08-03 22:57:10 +0000227 if not val.GetLocation().startswith("0x"):
Johnny Chencf386e22011-03-01 22:56:31 +0000228 return
229
230 # OK, let's get the hex location of the variable.
Greg Claytonfe42ac42011-08-03 22:57:10 +0000231 location = int(val.GetLocation(), 16)
Johnny Chencf386e22011-03-01 22:56:31 +0000232
Johnny Chen4e90a7e2011-03-02 19:49:27 +0000233 # Note that the canonical from of the bytearray is little endian.
Johnny Chen43766d62011-03-02 01:36:45 +0000234 from lldbutil import int_to_bytearray, bytearray_to_int
Johnny Chen4e90a7e2011-03-02 19:49:27 +0000235
Johnny Chencf386e22011-03-01 22:56:31 +0000236 byteSize = val.GetByteSize()
Johnny Chen43766d62011-03-02 01:36:45 +0000237 bytes = int_to_bytearray(256, byteSize)
Johnny Chencf386e22011-03-01 22:56:31 +0000238
Johnny Chen5a0bee72011-06-15 22:14:12 +0000239 byteOrder = process.GetByteOrder()
Johnny Chencf386e22011-03-01 22:56:31 +0000240 if byteOrder == lldb.eByteOrderBig:
Johnny Chen43766d62011-03-02 01:36:45 +0000241 bytes.reverse()
Johnny Chencf386e22011-03-01 22:56:31 +0000242 elif byteOrder == lldb.eByteOrderLittle:
Johnny Chen43766d62011-03-02 01:36:45 +0000243 pass
Johnny Chencf386e22011-03-01 22:56:31 +0000244 else:
245 # Neither big endian nor little endian? Return for now.
Johnny Chen43766d62011-03-02 01:36:45 +0000246 # Add more logic here if we want to handle other types.
Johnny Chencf386e22011-03-01 22:56:31 +0000247 return
248
249 # The program logic makes the 'my_int' variable to have int type and value of 0.
250 # But we want to use the WriteMemory() API to assign 256 to the variable.
251
252 # Now use WriteMemory() API to write 256 into the global variable.
253 new_value = str(bytes)
Johnny Chen1d3e8802011-07-11 23:38:23 +0000254 error = lldb.SBError()
Johnny Chen5a0bee72011-06-15 22:14:12 +0000255 result = process.WriteMemory(location, new_value, error)
Johnny Chencf386e22011-03-01 22:56:31 +0000256 if not error.Success() or result != byteSize:
257 self.fail("SBProcess.WriteMemory() failed")
258
Jim Ingham78a685a2011-04-16 00:01:13 +0000259 # Make sure that the val we got originally updates itself to notice the change:
Greg Claytonfe42ac42011-08-03 22:57:10 +0000260 self.expect(val.GetValue(),
Jim Ingham78a685a2011-04-16 00:01:13 +0000261 "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
262 exe=False,
263 startstr = '256')
264
265 # 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 +0000266 val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
Greg Claytonfe42ac42011-08-03 22:57:10 +0000267 self.expect(val.GetValue(),
Johnny Chencf386e22011-03-01 22:56:31 +0000268 "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
269 exe=False,
270 startstr = '256')
271
272 # Now read the memory content. The bytearray should have (byte)1 as the second element.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000273 content = process.ReadMemory(location, byteSize, error)
Johnny Chencf386e22011-03-01 22:56:31 +0000274 if not error.Success():
275 self.fail("SBProcess.ReadMemory() failed")
Johnny Chen4e90a7e2011-03-02 19:49:27 +0000276
277 # Use "ascii" as the encoding because each element of 'content' is in the range [0..255].
Johnny Chencf386e22011-03-01 22:56:31 +0000278 new_bytes = bytearray(content, "ascii")
Johnny Chen43766d62011-03-02 01:36:45 +0000279
280 # The bytearray_to_int utility function expects a little endian bytearray.
Johnny Chencf386e22011-03-01 22:56:31 +0000281 if byteOrder == lldb.eByteOrderBig:
Johnny Chen43766d62011-03-02 01:36:45 +0000282 new_bytes.reverse()
283
284 new_value = bytearray_to_int(new_bytes, byteSize)
285 if new_value != 256:
286 self.fail("Memory content read from 'my_int' does not match (int)256")
Johnny Chencf386e22011-03-01 22:56:31 +0000287
288 # Dump the memory content....
Johnny Chen90da3cc2011-04-19 19:49:09 +0000289 if self.TraceOn():
290 for i in new_bytes:
291 print "byte:", i
Johnny Chencf386e22011-03-01 22:56:31 +0000292
Johnny Chen930e3ad2011-03-05 01:20:11 +0000293 def remote_launch_should_fail(self):
294 """Test SBProcess.RemoteLaunch() API with a process not in eStateConnected, and it should fail."""
295 exe = os.path.join(os.getcwd(), "a.out")
296 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
297
298 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000299 self.assertTrue(target, VALID_TARGET)
Johnny Chen930e3ad2011-03-05 01:20:11 +0000300
301 # Launch the process, and do not stop at the entry point.
Johnny Chen1d3e8802011-07-11 23:38:23 +0000302 process = target.LaunchSimple(None, None, os.getcwd())
Johnny Chen930e3ad2011-03-05 01:20:11 +0000303
Johnny Chen90da3cc2011-04-19 19:49:09 +0000304 if self.TraceOn():
Johnny Chende90f1d2011-04-27 17:43:07 +0000305 print "process state:", state_type_to_str(process.GetState())
Johnny Chen930e3ad2011-03-05 01:20:11 +0000306 self.assertTrue(process.GetState() != lldb.eStateConnected)
307
Johnny Chen1d3e8802011-07-11 23:38:23 +0000308 error = lldb.SBError()
Johnny Chen930e3ad2011-03-05 01:20:11 +0000309 success = process.RemoteLaunch(None, None, None, None, None, None, 0, False, error)
310 self.assertTrue(not success, "RemoteLaunch() should fail for process state != eStateConnected")
311
Johnny Chen37f99fd2011-03-01 02:20:14 +0000312
313if __name__ == '__main__':
314 import atexit
315 lldb.SBDebugger.Initialize()
316 atexit.register(lambda: lldb.SBDebugger.Terminate())
317 unittest2.main()