blob: 62c1f503dfc2550602eb060e80d9267f5ab30fc6 [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
Siva Chandraaaa3d472014-12-19 22:41:43 +000023 @unittest2.skipUnless((sys.platform.startswith("darwin") or
24 sys.platform.startswith("freebsd")),
25 "requires Darwin or FreeBSD")
Johnny Chen3a709ac2011-07-08 23:02:33 +000026 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000027 @dwarf_test
Johnny Chen3a709ac2011-07-08 23:02:33 +000028 def test_listen_for_and_print_event_with_dwarf(self):
29 """Exercise SBEvent API."""
30 self.buildDwarf()
31 self.do_listen_for_and_print_event()
32
33 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
34 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000035 @dsym_test
Johnny Chen3635eae2010-12-21 19:52:54 +000036 def test_wait_for_event_with_dsym(self):
Johnny Chenf2df1892010-12-22 00:32:54 +000037 """Exercise SBListener.WaitForEvent() API."""
Johnny Chenf667ab52010-12-21 02:06:56 +000038 self.buildDsym()
Johnny Chen3635eae2010-12-21 19:52:54 +000039 self.do_wait_for_event()
Johnny Chenf667ab52010-12-21 02:06:56 +000040
Siva Chandraaaa3d472014-12-19 22:41:43 +000041 @skipIfLinux # non-core functionality, need to reenable and fix later (DES 2014.11.07)
Johnny Chenf667ab52010-12-21 02:06:56 +000042 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000043 @dwarf_test
Johnny Chen3635eae2010-12-21 19:52:54 +000044 def test_wait_for_event_with_dwarf(self):
Johnny Chenf2df1892010-12-22 00:32:54 +000045 """Exercise SBListener.WaitForEvent() API."""
Johnny Chenf667ab52010-12-21 02:06:56 +000046 self.buildDwarf()
Johnny Chen3635eae2010-12-21 19:52:54 +000047 self.do_wait_for_event()
Johnny Chenf667ab52010-12-21 02:06:56 +000048
Johnny Chenf2df1892010-12-22 00:32:54 +000049 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
50 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000051 @dsym_test
52 def test_add_listener_to_broadcaster_with_dsym(self):
Johnny Chen77c46972010-12-22 00:56:47 +000053 """Exercise some SBBroadcaster APIs."""
Johnny Chenf2df1892010-12-22 00:32:54 +000054 self.buildDsym()
Johnny Chen77c46972010-12-22 00:56:47 +000055 self.do_add_listener_to_broadcaster()
Johnny Chenf2df1892010-12-22 00:32:54 +000056
Ed Maste2ec8e1b2014-10-29 20:02:54 +000057 @skipIfFreeBSD # llvm.org/pr21325
Siva Chandraaaa3d472014-12-19 22:41:43 +000058 @skipIfLinux # non-core functionality, need to reenable and fix later (DES 2014.11.07)
Johnny Chenf2df1892010-12-22 00:32:54 +000059 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000060 @dwarf_test
61 def test_add_listener_to_broadcaster_with_dwarf(self):
Johnny Chen77c46972010-12-22 00:56:47 +000062 """Exercise some SBBroadcaster APIs."""
Johnny Chenf2df1892010-12-22 00:32:54 +000063 self.buildDwarf()
Johnny Chen77c46972010-12-22 00:56:47 +000064 self.do_add_listener_to_broadcaster()
Johnny Chenf2df1892010-12-22 00:32:54 +000065
Johnny Chenf667ab52010-12-21 02:06:56 +000066 def setUp(self):
67 # Call super's setUp().
68 TestBase.setUp(self)
69 # Find the line number to of function 'c'.
70 self.line = line_number('main.c', '// Find the line number of function "c" here.')
71
Johnny Chen3a709ac2011-07-08 23:02:33 +000072 def do_listen_for_and_print_event(self):
73 """Create a listener and use SBEvent API to print the events received."""
74 exe = os.path.join(os.getcwd(), "a.out")
75
Greg Claytona6cffde2014-10-17 23:58:27 +000076 self.dbg.SetAsync(True)
77
Johnny Chen3a709ac2011-07-08 23:02:33 +000078 # Create a target by the debugger.
79 target = self.dbg.CreateTarget(exe)
80 self.assertTrue(target, VALID_TARGET)
81
82 # Now create a breakpoint on main.c by name 'c'.
83 breakpoint = target.BreakpointCreateByName('c', 'a.out')
84
Greg Claytona6cffde2014-10-17 23:58:27 +000085 listener = lldb.SBListener("my listener")
Johnny Chen3a709ac2011-07-08 23:02:33 +000086
Greg Claytona6cffde2014-10-17 23:58:27 +000087 # Now launch the process, and do not stop at the entry point.
88 error = lldb.SBError()
89 process = target.Launch (listener,
90 None, # argv
91 None, # envp
92 None, # stdin_path
93 None, # stdout_path
94 None, # stderr_path
95 None, # working directory
96 0, # launch flags
97 False, # Stop at entry
98 error) # error
99
100 self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
Johnny Chen3a709ac2011-07-08 23:02:33 +0000101
102 # Create an empty event object.
103 event = lldb.SBEvent()
104
Johnny Chen3a709ac2011-07-08 23:02:33 +0000105 traceOn = self.TraceOn()
106 if traceOn:
107 lldbutil.print_stacktraces(process)
108
109 # Create MyListeningThread class to wait for any kind of event.
110 import threading
111 class MyListeningThread(threading.Thread):
112 def run(self):
113 count = 0
114 # Let's only try at most 4 times to retrieve any kind of event.
115 # After that, the thread exits.
116 while not count > 3:
117 if traceOn:
118 print "Try wait for event..."
Greg Claytona6cffde2014-10-17 23:58:27 +0000119 if listener.WaitForEvent(5, event):
Johnny Chen3a709ac2011-07-08 23:02:33 +0000120 if traceOn:
121 desc = lldbutil.get_description(event)
122 print "Event description:", desc
123 print "Event data flavor:", event.GetDataFlavor()
124 print "Process state:", lldbutil.state_type_to_str(process.GetState())
125 print
126 else:
127 if traceOn:
128 print "timeout occurred waiting for event..."
129 count = count + 1
130 return
131
132 # Let's start the listening thread to retrieve the events.
133 my_thread = MyListeningThread()
134 my_thread.start()
135
136 # Use Python API to continue the process. The listening thread should be
137 # able to receive the state changed events.
138 process.Continue()
139
140 # Use Python API to kill the process. The listening thread should be
141 # able to receive the state changed event, too.
142 process.Kill()
143
144 # Wait until the 'MyListeningThread' terminates.
145 my_thread.join()
146
Johnny Chen3635eae2010-12-21 19:52:54 +0000147 def do_wait_for_event(self):
148 """Get the listener associated with the debugger and exercise WaitForEvent API."""
Johnny Chenf667ab52010-12-21 02:06:56 +0000149 exe = os.path.join(os.getcwd(), "a.out")
150
Greg Claytona6cffde2014-10-17 23:58:27 +0000151 self.dbg.SetAsync(True)
152
Johnny Chenf667ab52010-12-21 02:06:56 +0000153 # Create a target by the debugger.
154 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000155 self.assertTrue(target, VALID_TARGET)
Johnny Chenf667ab52010-12-21 02:06:56 +0000156
157 # Now create a breakpoint on main.c by name 'c'.
158 breakpoint = target.BreakpointCreateByName('c', 'a.out')
159 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000160 self.assertTrue(breakpoint and
Johnny Chenf667ab52010-12-21 02:06:56 +0000161 breakpoint.GetNumLocations() == 1,
162 VALID_BREAKPOINT)
163
Johnny Chend762ff12011-02-03 23:15:53 +0000164 # Get the debugger listener.
165 listener = self.dbg.GetListener()
166
Johnny Chenf667ab52010-12-21 02:06:56 +0000167 # Now launch the process, and do not stop at entry point.
Greg Clayton6f907e62011-01-23 17:46:22 +0000168 error = lldb.SBError()
Greg Claytona6cffde2014-10-17 23:58:27 +0000169 process = target.Launch (listener,
170 None, # argv
171 None, # envp
172 None, # stdin_path
173 None, # stdout_path
174 None, # stderr_path
175 None, # working directory
176 0, # launch flags
177 False, # Stop at entry
178 error) # error
Johnny Chen2494f552011-07-20 00:14:20 +0000179 self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
Johnny Chenf667ab52010-12-21 02:06:56 +0000180
Johnny Chenf667ab52010-12-21 02:06:56 +0000181 # Create an empty event object.
182 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000183 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf667ab52010-12-21 02:06:56 +0000184
Johnny Chenf667ab52010-12-21 02:06:56 +0000185 # Create MyListeningThread to wait for any kind of event.
186 import threading
187 class MyListeningThread(threading.Thread):
188 def run(self):
Johnny Chenf667ab52010-12-21 02:06:56 +0000189 count = 0
190 # Let's only try at most 3 times to retrieve any kind of event.
191 while not count > 3:
192 if listener.WaitForEvent(5, event):
Johnny Chenf2df1892010-12-22 00:32:54 +0000193 #print "Got a valid event:", event
Johnny Chen3a709ac2011-07-08 23:02:33 +0000194 #print "Event data flavor:", event.GetDataFlavor()
195 #print "Event type:", lldbutil.state_type_to_str(event.GetType())
Johnny Chenf667ab52010-12-21 02:06:56 +0000196 return
197 count = count + 1
198 print "Timeout: listener.WaitForEvent"
199
200 return
201
Johnny Chen4f8caab2010-12-21 05:43:37 +0000202 # Use Python API to kill the process. The listening thread should be
203 # able to receive a state changed event.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000204 process.Kill()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000205
Johnny Chenf2df1892010-12-22 00:32:54 +0000206 # Let's start the listening thread to retrieve the event.
207 my_thread = MyListeningThread()
208 my_thread.start()
209
Johnny Chen4f8caab2010-12-21 05:43:37 +0000210 # Wait until the 'MyListeningThread' terminates.
Johnny Chenf667ab52010-12-21 02:06:56 +0000211 my_thread.join()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000212
Johnny Chen4ebd0192011-05-24 18:22:45 +0000213 self.assertTrue(event,
Johnny Chenf2df1892010-12-22 00:32:54 +0000214 "My listening thread successfully received an event")
Johnny Chen4f8caab2010-12-21 05:43:37 +0000215
Johnny Chen77c46972010-12-22 00:56:47 +0000216 def do_add_listener_to_broadcaster(self):
217 """Get the broadcaster associated with the process and wait for broadcaster events."""
Johnny Chenf2df1892010-12-22 00:32:54 +0000218 exe = os.path.join(os.getcwd(), "a.out")
219
Greg Claytona6cffde2014-10-17 23:58:27 +0000220 self.dbg.SetAsync(True)
221
Johnny Chenf2df1892010-12-22 00:32:54 +0000222 # Create a target by the debugger.
223 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000224 self.assertTrue(target, VALID_TARGET)
Johnny Chenf2df1892010-12-22 00:32:54 +0000225
226 # Now create a breakpoint on main.c by name 'c'.
227 breakpoint = target.BreakpointCreateByName('c', 'a.out')
228 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000229 self.assertTrue(breakpoint and
Johnny Chenf2df1892010-12-22 00:32:54 +0000230 breakpoint.GetNumLocations() == 1,
231 VALID_BREAKPOINT)
232
Greg Claytona6cffde2014-10-17 23:58:27 +0000233 listener = lldb.SBListener("my listener")
Johnny Chenf2df1892010-12-22 00:32:54 +0000234
Greg Claytona6cffde2014-10-17 23:58:27 +0000235 # Now launch the process, and do not stop at the entry point.
236 error = lldb.SBError()
237 process = target.Launch (listener,
238 None, # argv
239 None, # envp
240 None, # stdin_path
241 None, # stdout_path
242 None, # stderr_path
243 None, # working directory
244 0, # launch flags
245 False, # Stop at entry
246 error) # error
Johnny Chenf2df1892010-12-22 00:32:54 +0000247
248 # Create an empty event object.
249 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000250 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf2df1892010-12-22 00:32:54 +0000251
Johnny Chenf2df1892010-12-22 00:32:54 +0000252
253 # The finite state machine for our custom listening thread, with an
254 # initail state of 0, which means a "running" event is expected.
255 # It changes to 1 after "running" is received.
256 # It cahnges to 2 after "stopped" is received.
257 # 2 will be our final state and the test is complete.
258 self.state = 0
259
260 # Create MyListeningThread to wait for state changed events.
261 # By design, a "running" event is expected following by a "stopped" event.
262 import threading
263 class MyListeningThread(threading.Thread):
264 def run(self):
265 #print "Running MyListeningThread:", self
266
267 # Regular expression pattern for the event description.
268 pattern = re.compile("data = {.*, state = (.*)}$")
269
270 # Let's only try at most 6 times to retrieve our events.
271 count = 0
272 while True:
Greg Claytona6cffde2014-10-17 23:58:27 +0000273 if listener.WaitForEvent(5, event):
Johnny Chen9ae98202011-04-23 00:34:56 +0000274 desc = lldbutil.get_description(event)
275 #print "Event description:", desc
276 match = pattern.search(desc)
Johnny Chenf2df1892010-12-22 00:32:54 +0000277 if not match:
278 break;
279 if self.context.state == 0 and match.group(1) == 'running':
280 self.context.state = 1
281 continue
282 elif self.context.state == 1 and match.group(1) == 'stopped':
283 # Whoopee, both events have been received!
284 self.context.state = 2
285 break
286 else:
287 break
288 print "Timeout: listener.WaitForEvent"
289 count = count + 1
290 if count > 6:
291 break
292
293 return
294
295 # Use Python API to continue the process. The listening thread should be
296 # able to receive the state changed events.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000297 process.Continue()
Johnny Chenf2df1892010-12-22 00:32:54 +0000298
299 # Start the listening thread to receive the "running" followed by the
300 # "stopped" events.
301 my_thread = MyListeningThread()
302 # Supply the enclosing context so that our listening thread can access
303 # the 'state' variable.
304 my_thread.context = self
305 my_thread.start()
306
307 # Wait until the 'MyListeningThread' terminates.
308 my_thread.join()
309
Johnny Chenf2df1892010-12-22 00:32:54 +0000310 # The final judgement. :-)
311 self.assertTrue(self.state == 2,
312 "Both expected state changed events received")
Johnny Chenf667ab52010-12-21 02:06:56 +0000313
314
315if __name__ == '__main__':
316 import atexit
317 lldb.SBDebugger.Initialize()
318 atexit.register(lambda: lldb.SBDebugger.Terminate())
319 unittest2.main()