blob: 1e92fa309d328685fa9469aed27dc7608cc3d7f9 [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
8from lldbtest import *
9
Johnny Chen37f99fd2011-03-01 02:20:14 +000010class ProcessAPITestCase(TestBase):
11
12 mydir = os.path.join("python_api", "process")
13
Johnny Chen90aa5942011-03-01 18:51:47 +000014 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
Johnny Chen37f99fd2011-03-01 02:20:14 +000015 @python_api_test
Johnny Chen90aa5942011-03-01 18:51:47 +000016 def test_read_memory_with_dsym(self):
17 """Test Python SBProcess.ReadMemory() API."""
Johnny Chen37f99fd2011-03-01 02:20:14 +000018 self.buildDsym()
Johnny Chen90aa5942011-03-01 18:51:47 +000019 self.read_memory()
Johnny Chen37f99fd2011-03-01 02:20:14 +000020
21 @python_api_test
Johnny Chen90aa5942011-03-01 18:51:47 +000022 def test_read_memory_with_dwarf(self):
23 """Test Python SBProcess.ReadMemory() API."""
Johnny Chen37f99fd2011-03-01 02:20:14 +000024 self.buildDwarf()
Johnny Chen90aa5942011-03-01 18:51:47 +000025 self.read_memory()
26
27 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
28 @python_api_test
29 def test_write_memory_with_dsym(self):
30 """Test Python SBProcess.WriteMemory() API."""
31 self.buildDsym()
32 self.write_memory()
33
34 @python_api_test
35 def test_write_memory_with_dwarf(self):
36 """Test Python SBProcess.WriteMemory() API."""
37 self.buildDwarf()
38 self.write_memory()
Johnny Chen37f99fd2011-03-01 02:20:14 +000039
Johnny Chencf386e22011-03-01 22:56:31 +000040 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
41 @python_api_test
42 def test_access_my_int_with_dsym(self):
43 """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
44 self.buildDsym()
45 self.access_my_int()
46
47 @python_api_test
48 def test_access_my_int_with_dwarf(self):
49 """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
50 self.buildDwarf()
51 self.access_my_int()
52
Johnny Chen37f99fd2011-03-01 02:20:14 +000053 def setUp(self):
54 # Call super's setUp().
55 TestBase.setUp(self)
56 # Find the line number to break inside main().
57 self.line = line_number("main.cpp", "// Set break point at this line and check variable 'my_char'.")
58
Johnny Chen90aa5942011-03-01 18:51:47 +000059 def read_memory(self):
60 """Test Python SBProcess.ReadMemory() API."""
Johnny Chen37f99fd2011-03-01 02:20:14 +000061 exe = os.path.join(os.getcwd(), "a.out")
62 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
63
64 target = self.dbg.CreateTarget(exe)
65 self.assertTrue(target.IsValid(), VALID_TARGET)
66
67 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
68 self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT)
69
70 # Launch the process, and do not stop at the entry point.
71 error = lldb.SBError()
72 self.process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error)
73
74 thread = self.process.GetThreadAtIndex(0);
75 frame = thread.GetFrameAtIndex(0);
76
77 # Get the SBValue for the global variable 'my_char'.
78 val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal)
Johnny Chen37f99fd2011-03-01 02:20:14 +000079 self.DebugSBValue(frame, val)
80
Johnny Chen90aa5942011-03-01 18:51:47 +000081 # If the variable does not have a load address, there's no sense continuing.
82 if not val.GetLocation(frame).startswith("0x"):
83 return
84
85 # OK, let's get the hex location of the variable.
86 location = int(val.GetLocation(frame), 16)
87
Johnny Chen37f99fd2011-03-01 02:20:14 +000088 # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
89 # expect to get a Python string as the result object!
90 content = self.process.ReadMemory(location, 1, error)
Johnny Chen90aa5942011-03-01 18:51:47 +000091 if not error.Success():
92 self.fail("SBProcess.ReadMemory() failed")
93 print "memory content:", content
Johnny Chen37f99fd2011-03-01 02:20:14 +000094
95 self.expect(content, "Result from SBProcess.ReadMemory() matches our expected output: 'x'",
96 exe=False,
97 startstr = 'x')
98
Johnny Chen90aa5942011-03-01 18:51:47 +000099 def write_memory(self):
100 """Test Python SBProcess.WriteMemory() API."""
101 exe = os.path.join(os.getcwd(), "a.out")
102 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000103
Johnny Chen90aa5942011-03-01 18:51:47 +0000104 target = self.dbg.CreateTarget(exe)
105 self.assertTrue(target.IsValid(), VALID_TARGET)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000106
Johnny Chen90aa5942011-03-01 18:51:47 +0000107 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
108 self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT)
Johnny Chen37f99fd2011-03-01 02:20:14 +0000109
Johnny Chen90aa5942011-03-01 18:51:47 +0000110 # Launch the process, and do not stop at the entry point.
111 error = lldb.SBError()
112 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 +0000113
Johnny Chen90aa5942011-03-01 18:51:47 +0000114 thread = self.process.GetThreadAtIndex(0);
115 frame = thread.GetFrameAtIndex(0);
116
117 # Get the SBValue for the global variable 'my_char'.
118 val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal)
119 self.DebugSBValue(frame, val)
120
121 # If the variable does not have a load address, there's no sense continuing.
122 if not val.GetLocation(frame).startswith("0x"):
123 return
124
125 # OK, let's get the hex location of the variable.
126 location = int(val.GetLocation(frame), 16)
127
128 # The program logic makes the 'my_char' variable to have memory content as 'x'.
129 # But we want to use the WriteMemory() API to assign 'a' to the variable.
130
131 # Now use WriteMemory() API to write 'a' into the global variable.
132 result = self.process.WriteMemory(location, 'a', error)
133 if not error.Success() or result != 1:
134 self.fail("SBProcess.WriteMemory() failed")
135
136 # Read from the memory location. This time it should be 'a'.
137 # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
138 # expect to get a Python string as the result object!
139 content = self.process.ReadMemory(location, 1, error)
140 if not error.Success():
141 self.fail("SBProcess.ReadMemory() failed")
142 print "memory content:", content
143
144 self.expect(content, "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
145 exe=False,
146 startstr = 'a')
Johnny Chen37f99fd2011-03-01 02:20:14 +0000147
Johnny Chencf386e22011-03-01 22:56:31 +0000148 def access_my_int(self):
149 """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
150 exe = os.path.join(os.getcwd(), "a.out")
151 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
152
153 target = self.dbg.CreateTarget(exe)
154 self.assertTrue(target.IsValid(), VALID_TARGET)
155
156 breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
157 self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT)
158
159 # Launch the process, and do not stop at the entry point.
160 error = lldb.SBError()
161 self.process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error)
162
163 thread = self.process.GetThreadAtIndex(0);
164 frame = thread.GetFrameAtIndex(0);
165
166 # Get the SBValue for the global variable 'my_int'.
167 val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
168 self.DebugSBValue(frame, val)
169
170 # If the variable does not have a load address, there's no sense continuing.
171 if not val.GetLocation(frame).startswith("0x"):
172 return
173
174 # OK, let's get the hex location of the variable.
175 location = int(val.GetLocation(frame), 16)
176
177 byteSize = val.GetByteSize()
178 byteOrder = self.process.GetByteOrder()
179 bytes = bytearray(byteSize)
180
181 if byteOrder == lldb.eByteOrderBig:
182 # 256 in big endian => 0x00000100
183 # the second byte counted from the end is to be 0b00000001
184 bytes[-2] = 0b00000001
185 elif byteOrder == lldb.eByteOrderLittle:
186 # 256 in little endian => 0x00010000
187 # the second byte counted from the start is to be 0b00000001
188 bytes[1] = 0b00000001
189 else:
190 # Neither big endian nor little endian? Return for now.
191 return
192
193 # The program logic makes the 'my_int' variable to have int type and value of 0.
194 # But we want to use the WriteMemory() API to assign 256 to the variable.
195
196 # Now use WriteMemory() API to write 256 into the global variable.
197 new_value = str(bytes)
198 result = self.process.WriteMemory(location, new_value, error)
199 if not error.Success() or result != byteSize:
200 self.fail("SBProcess.WriteMemory() failed")
201
202 # Get the SBValue for the global variable 'my_int' again, with its updated value.
203 val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
204 self.expect(val.GetValue(frame),
205 "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
206 exe=False,
207 startstr = '256')
208
209 # Now read the memory content. The bytearray should have (byte)1 as the second element.
210 content = self.process.ReadMemory(location, byteSize, error)
211 if not error.Success():
212 self.fail("SBProcess.ReadMemory() failed")
213 new_bytes = bytearray(content, "ascii")
214 if byteOrder == lldb.eByteOrderBig:
215 if new_bytes[-2] != 0b00000001:
216 self.fail("Memory content read from 'my_int' does not match (int)256")
217 elif byteOrder == lldb.eByteOrderLittle:
218 if new_bytes[1] != 0b00000001:
219 self.fail("Memory content read from 'my_int' does not match (int)256")
220
221 # Dump the memory content....
222 for i in new_bytes:
223 print "byte:", i
224
Johnny Chen37f99fd2011-03-01 02:20:14 +0000225
226if __name__ == '__main__':
227 import atexit
228 lldb.SBDebugger.Initialize()
229 atexit.register(lambda: lldb.SBDebugger.Terminate())
230 unittest2.main()