blob: 615668b115e942ad63fd852f1777711359ed54f4 [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
Johnny Chen43766d62011-03-02 01:36:45 +0000177 from lldbutil import int_to_bytearray, bytearray_to_int
Johnny Chencf386e22011-03-01 22:56:31 +0000178 byteSize = val.GetByteSize()
Johnny Chen43766d62011-03-02 01:36:45 +0000179 bytes = int_to_bytearray(256, byteSize)
Johnny Chencf386e22011-03-01 22:56:31 +0000180
Johnny Chen43766d62011-03-02 01:36:45 +0000181 byteOrder = self.process.GetByteOrder()
Johnny Chencf386e22011-03-01 22:56:31 +0000182 if byteOrder == lldb.eByteOrderBig:
Johnny Chen43766d62011-03-02 01:36:45 +0000183 bytes.reverse()
Johnny Chencf386e22011-03-01 22:56:31 +0000184 elif byteOrder == lldb.eByteOrderLittle:
Johnny Chen43766d62011-03-02 01:36:45 +0000185 pass
Johnny Chencf386e22011-03-01 22:56:31 +0000186 else:
187 # Neither big endian nor little endian? Return for now.
Johnny Chen43766d62011-03-02 01:36:45 +0000188 # Add more logic here if we want to handle other types.
Johnny Chencf386e22011-03-01 22:56:31 +0000189 return
190
191 # The program logic makes the 'my_int' variable to have int type and value of 0.
192 # But we want to use the WriteMemory() API to assign 256 to the variable.
193
194 # Now use WriteMemory() API to write 256 into the global variable.
195 new_value = str(bytes)
196 result = self.process.WriteMemory(location, new_value, error)
197 if not error.Success() or result != byteSize:
198 self.fail("SBProcess.WriteMemory() failed")
199
200 # Get the SBValue for the global variable 'my_int' again, with its updated value.
201 val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
202 self.expect(val.GetValue(frame),
203 "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
204 exe=False,
205 startstr = '256')
206
207 # Now read the memory content. The bytearray should have (byte)1 as the second element.
208 content = self.process.ReadMemory(location, byteSize, error)
209 if not error.Success():
210 self.fail("SBProcess.ReadMemory() failed")
211 new_bytes = bytearray(content, "ascii")
Johnny Chen43766d62011-03-02 01:36:45 +0000212
213 # The bytearray_to_int utility function expects a little endian bytearray.
Johnny Chencf386e22011-03-01 22:56:31 +0000214 if byteOrder == lldb.eByteOrderBig:
Johnny Chen43766d62011-03-02 01:36:45 +0000215 new_bytes.reverse()
216
217 new_value = bytearray_to_int(new_bytes, byteSize)
218 if new_value != 256:
219 self.fail("Memory content read from 'my_int' does not match (int)256")
Johnny Chencf386e22011-03-01 22:56:31 +0000220
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()