blob: a4a92bee26a6d01f189bd9dd83c6ef181b32ecda [file] [log] [blame]
Johnny Chenf667ab52010-12-21 02:06:56 +00001"""
2Test lldb Python event APIs.
3"""
4
5import os, time
6import re
7import unittest2
8import lldb, lldbutil
9from lldbtest import *
10
11class EventAPITestCase(TestBase):
12
Greg Clayton4570d3e2013-12-10 23:19:29 +000013 mydir = TestBase.compute_mydir(__file__)
Johnny Chenf667ab52010-12-21 02:06:56 +000014
15 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
16 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000017 @dsym_test
Johnny Chen3a709ac2011-07-08 23:02:33 +000018 def test_listen_for_and_print_event_with_dsym(self):
19 """Exercise SBEvent API."""
20 self.buildDsym()
21 self.do_listen_for_and_print_event()
22
23 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000024 @dwarf_test
Johnny Chen3a709ac2011-07-08 23:02:33 +000025 def test_listen_for_and_print_event_with_dwarf(self):
26 """Exercise SBEvent API."""
27 self.buildDwarf()
28 self.do_listen_for_and_print_event()
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 Chen3635eae2010-12-21 19:52:54 +000033 def test_wait_for_event_with_dsym(self):
Johnny Chenf2df1892010-12-22 00:32:54 +000034 """Exercise SBListener.WaitForEvent() API."""
Johnny Chenf667ab52010-12-21 02:06:56 +000035 self.buildDsym()
Johnny Chen3635eae2010-12-21 19:52:54 +000036 self.do_wait_for_event()
Johnny Chenf667ab52010-12-21 02:06:56 +000037
38 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000039 @dwarf_test
Johnny Chen3635eae2010-12-21 19:52:54 +000040 def test_wait_for_event_with_dwarf(self):
Johnny Chenf2df1892010-12-22 00:32:54 +000041 """Exercise SBListener.WaitForEvent() API."""
Johnny Chenf667ab52010-12-21 02:06:56 +000042 self.buildDwarf()
Johnny Chen3635eae2010-12-21 19:52:54 +000043 self.do_wait_for_event()
Johnny Chenf667ab52010-12-21 02:06:56 +000044
Johnny Chenf2df1892010-12-22 00:32:54 +000045 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
46 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000047 @dsym_test
48 def test_add_listener_to_broadcaster_with_dsym(self):
Johnny Chen77c46972010-12-22 00:56:47 +000049 """Exercise some SBBroadcaster APIs."""
Johnny Chenf2df1892010-12-22 00:32:54 +000050 self.buildDsym()
Johnny Chen77c46972010-12-22 00:56:47 +000051 self.do_add_listener_to_broadcaster()
Johnny Chenf2df1892010-12-22 00:32:54 +000052
53 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000054 @dwarf_test
55 def test_add_listener_to_broadcaster_with_dwarf(self):
Johnny Chen77c46972010-12-22 00:56:47 +000056 """Exercise some SBBroadcaster APIs."""
Johnny Chenf2df1892010-12-22 00:32:54 +000057 self.buildDwarf()
Johnny Chen77c46972010-12-22 00:56:47 +000058 self.do_add_listener_to_broadcaster()
Johnny Chenf2df1892010-12-22 00:32:54 +000059
Johnny Chenf667ab52010-12-21 02:06:56 +000060 def setUp(self):
61 # Call super's setUp().
62 TestBase.setUp(self)
63 # Find the line number to of function 'c'.
64 self.line = line_number('main.c', '// Find the line number of function "c" here.')
65
Johnny Chen3a709ac2011-07-08 23:02:33 +000066 def do_listen_for_and_print_event(self):
67 """Create a listener and use SBEvent API to print the events received."""
68 exe = os.path.join(os.getcwd(), "a.out")
69
Greg Claytona6cffde2014-10-17 23:58:27 +000070 self.dbg.SetAsync(True)
71
Johnny Chen3a709ac2011-07-08 23:02:33 +000072 # Create a target by the debugger.
73 target = self.dbg.CreateTarget(exe)
74 self.assertTrue(target, VALID_TARGET)
75
76 # Now create a breakpoint on main.c by name 'c'.
77 breakpoint = target.BreakpointCreateByName('c', 'a.out')
78
Greg Claytona6cffde2014-10-17 23:58:27 +000079 listener = lldb.SBListener("my listener")
Johnny Chen3a709ac2011-07-08 23:02:33 +000080
Greg Claytona6cffde2014-10-17 23:58:27 +000081 # Now launch the process, and do not stop at the entry point.
82 error = lldb.SBError()
83 process = target.Launch (listener,
84 None, # argv
85 None, # envp
86 None, # stdin_path
87 None, # stdout_path
88 None, # stderr_path
89 None, # working directory
90 0, # launch flags
91 False, # Stop at entry
92 error) # error
93
94 self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
Johnny Chen3a709ac2011-07-08 23:02:33 +000095
96 # Create an empty event object.
97 event = lldb.SBEvent()
98
Johnny Chen3a709ac2011-07-08 23:02:33 +000099 traceOn = self.TraceOn()
100 if traceOn:
101 lldbutil.print_stacktraces(process)
102
103 # Create MyListeningThread class to wait for any kind of event.
104 import threading
105 class MyListeningThread(threading.Thread):
106 def run(self):
107 count = 0
108 # Let's only try at most 4 times to retrieve any kind of event.
109 # After that, the thread exits.
110 while not count > 3:
111 if traceOn:
112 print "Try wait for event..."
Greg Claytona6cffde2014-10-17 23:58:27 +0000113 if listener.WaitForEvent(5, event):
Johnny Chen3a709ac2011-07-08 23:02:33 +0000114 if traceOn:
115 desc = lldbutil.get_description(event)
116 print "Event description:", desc
117 print "Event data flavor:", event.GetDataFlavor()
118 print "Process state:", lldbutil.state_type_to_str(process.GetState())
119 print
120 else:
121 if traceOn:
122 print "timeout occurred waiting for event..."
123 count = count + 1
124 return
125
126 # Let's start the listening thread to retrieve the events.
127 my_thread = MyListeningThread()
128 my_thread.start()
129
130 # Use Python API to continue the process. The listening thread should be
131 # able to receive the state changed events.
132 process.Continue()
133
134 # Use Python API to kill the process. The listening thread should be
135 # able to receive the state changed event, too.
136 process.Kill()
137
138 # Wait until the 'MyListeningThread' terminates.
139 my_thread.join()
140
Johnny Chen3635eae2010-12-21 19:52:54 +0000141 def do_wait_for_event(self):
142 """Get the listener associated with the debugger and exercise WaitForEvent API."""
Johnny Chenf667ab52010-12-21 02:06:56 +0000143 exe = os.path.join(os.getcwd(), "a.out")
144
Greg Claytona6cffde2014-10-17 23:58:27 +0000145 self.dbg.SetAsync(True)
146
Johnny Chenf667ab52010-12-21 02:06:56 +0000147 # Create a target by the debugger.
148 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000149 self.assertTrue(target, VALID_TARGET)
Johnny Chenf667ab52010-12-21 02:06:56 +0000150
151 # Now create a breakpoint on main.c by name 'c'.
152 breakpoint = target.BreakpointCreateByName('c', 'a.out')
153 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000154 self.assertTrue(breakpoint and
Johnny Chenf667ab52010-12-21 02:06:56 +0000155 breakpoint.GetNumLocations() == 1,
156 VALID_BREAKPOINT)
157
Johnny Chend762ff12011-02-03 23:15:53 +0000158 # Get the debugger listener.
159 listener = self.dbg.GetListener()
160
Johnny Chenf667ab52010-12-21 02:06:56 +0000161 # Now launch the process, and do not stop at entry point.
Greg Clayton6f907e62011-01-23 17:46:22 +0000162 error = lldb.SBError()
Greg Claytona6cffde2014-10-17 23:58:27 +0000163 process = target.Launch (listener,
164 None, # argv
165 None, # envp
166 None, # stdin_path
167 None, # stdout_path
168 None, # stderr_path
169 None, # working directory
170 0, # launch flags
171 False, # Stop at entry
172 error) # error
Johnny Chen2494f552011-07-20 00:14:20 +0000173 self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
Johnny Chenf667ab52010-12-21 02:06:56 +0000174
Johnny Chenf667ab52010-12-21 02:06:56 +0000175 # Create an empty event object.
176 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000177 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf667ab52010-12-21 02:06:56 +0000178
Johnny Chenf667ab52010-12-21 02:06:56 +0000179 # Create MyListeningThread to wait for any kind of event.
180 import threading
181 class MyListeningThread(threading.Thread):
182 def run(self):
Johnny Chenf667ab52010-12-21 02:06:56 +0000183 count = 0
184 # Let's only try at most 3 times to retrieve any kind of event.
185 while not count > 3:
186 if listener.WaitForEvent(5, event):
Johnny Chenf2df1892010-12-22 00:32:54 +0000187 #print "Got a valid event:", event
Johnny Chen3a709ac2011-07-08 23:02:33 +0000188 #print "Event data flavor:", event.GetDataFlavor()
189 #print "Event type:", lldbutil.state_type_to_str(event.GetType())
Johnny Chenf667ab52010-12-21 02:06:56 +0000190 return
191 count = count + 1
192 print "Timeout: listener.WaitForEvent"
193
194 return
195
Johnny Chen4f8caab2010-12-21 05:43:37 +0000196 # Use Python API to kill the process. The listening thread should be
197 # able to receive a state changed event.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000198 process.Kill()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000199
Johnny Chenf2df1892010-12-22 00:32:54 +0000200 # Let's start the listening thread to retrieve the event.
201 my_thread = MyListeningThread()
202 my_thread.start()
203
Johnny Chen4f8caab2010-12-21 05:43:37 +0000204 # Wait until the 'MyListeningThread' terminates.
Johnny Chenf667ab52010-12-21 02:06:56 +0000205 my_thread.join()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000206
Johnny Chen4ebd0192011-05-24 18:22:45 +0000207 self.assertTrue(event,
Johnny Chenf2df1892010-12-22 00:32:54 +0000208 "My listening thread successfully received an event")
Johnny Chen4f8caab2010-12-21 05:43:37 +0000209
Johnny Chen77c46972010-12-22 00:56:47 +0000210 def do_add_listener_to_broadcaster(self):
211 """Get the broadcaster associated with the process and wait for broadcaster events."""
Johnny Chenf2df1892010-12-22 00:32:54 +0000212 exe = os.path.join(os.getcwd(), "a.out")
213
Greg Claytona6cffde2014-10-17 23:58:27 +0000214 self.dbg.SetAsync(True)
215
Johnny Chenf2df1892010-12-22 00:32:54 +0000216 # Create a target by the debugger.
217 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000218 self.assertTrue(target, VALID_TARGET)
Johnny Chenf2df1892010-12-22 00:32:54 +0000219
220 # Now create a breakpoint on main.c by name 'c'.
221 breakpoint = target.BreakpointCreateByName('c', 'a.out')
222 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000223 self.assertTrue(breakpoint and
Johnny Chenf2df1892010-12-22 00:32:54 +0000224 breakpoint.GetNumLocations() == 1,
225 VALID_BREAKPOINT)
226
Greg Claytona6cffde2014-10-17 23:58:27 +0000227 listener = lldb.SBListener("my listener")
Johnny Chenf2df1892010-12-22 00:32:54 +0000228
Greg Claytona6cffde2014-10-17 23:58:27 +0000229 # Now launch the process, and do not stop at the entry point.
230 error = lldb.SBError()
231 process = target.Launch (listener,
232 None, # argv
233 None, # envp
234 None, # stdin_path
235 None, # stdout_path
236 None, # stderr_path
237 None, # working directory
238 0, # launch flags
239 False, # Stop at entry
240 error) # error
Johnny Chenf2df1892010-12-22 00:32:54 +0000241
242 # Create an empty event object.
243 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000244 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf2df1892010-12-22 00:32:54 +0000245
Johnny Chenf2df1892010-12-22 00:32:54 +0000246
247 # The finite state machine for our custom listening thread, with an
248 # initail state of 0, which means a "running" event is expected.
249 # It changes to 1 after "running" is received.
250 # It cahnges to 2 after "stopped" is received.
251 # 2 will be our final state and the test is complete.
252 self.state = 0
253
254 # Create MyListeningThread to wait for state changed events.
255 # By design, a "running" event is expected following by a "stopped" event.
256 import threading
257 class MyListeningThread(threading.Thread):
258 def run(self):
259 #print "Running MyListeningThread:", self
260
261 # Regular expression pattern for the event description.
262 pattern = re.compile("data = {.*, state = (.*)}$")
263
264 # Let's only try at most 6 times to retrieve our events.
265 count = 0
266 while True:
Greg Claytona6cffde2014-10-17 23:58:27 +0000267 if listener.WaitForEvent(5, event):
Johnny Chen9ae98202011-04-23 00:34:56 +0000268 desc = lldbutil.get_description(event)
269 #print "Event description:", desc
270 match = pattern.search(desc)
Johnny Chenf2df1892010-12-22 00:32:54 +0000271 if not match:
272 break;
273 if self.context.state == 0 and match.group(1) == 'running':
274 self.context.state = 1
275 continue
276 elif self.context.state == 1 and match.group(1) == 'stopped':
277 # Whoopee, both events have been received!
278 self.context.state = 2
279 break
280 else:
281 break
282 print "Timeout: listener.WaitForEvent"
283 count = count + 1
284 if count > 6:
285 break
286
287 return
288
289 # Use Python API to continue the process. The listening thread should be
290 # able to receive the state changed events.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000291 process.Continue()
Johnny Chenf2df1892010-12-22 00:32:54 +0000292
293 # Start the listening thread to receive the "running" followed by the
294 # "stopped" events.
295 my_thread = MyListeningThread()
296 # Supply the enclosing context so that our listening thread can access
297 # the 'state' variable.
298 my_thread.context = self
299 my_thread.start()
300
301 # Wait until the 'MyListeningThread' terminates.
302 my_thread.join()
303
Johnny Chenf2df1892010-12-22 00:32:54 +0000304 # The final judgement. :-)
305 self.assertTrue(self.state == 2,
306 "Both expected state changed events received")
Johnny Chenf667ab52010-12-21 02:06:56 +0000307
308
309if __name__ == '__main__':
310 import atexit
311 lldb.SBDebugger.Initialize()
312 atexit.register(lambda: lldb.SBDebugger.Terminate())
313 unittest2.main()