blob: 248ba23da4245fb0bb723c2eba419bc837cef3bb [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
Robert Flack13c7ad92015-03-30 14:12:17 +000015 @skipUnlessDarwin
Johnny Chenf667ab52010-12-21 02:06:56 +000016 @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
Pavel Labath8e9c2662015-06-02 12:50:25 +000025 @expectedFailureLinux("llvm.org/pr23730") # Flaky, fails ~1/10 cases
26 @skipIfLinux # skip to avoid crashes
Johnny Chen3a709ac2011-07-08 23:02:33 +000027 def test_listen_for_and_print_event_with_dwarf(self):
28 """Exercise SBEvent API."""
29 self.buildDwarf()
30 self.do_listen_for_and_print_event()
31
Robert Flack13c7ad92015-03-30 14:12:17 +000032 @skipUnlessDarwin
Johnny Chen3a709ac2011-07-08 23:02:33 +000033 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000034 @dsym_test
Johnny Chen3635eae2010-12-21 19:52:54 +000035 def test_wait_for_event_with_dsym(self):
Johnny Chenf2df1892010-12-22 00:32:54 +000036 """Exercise SBListener.WaitForEvent() API."""
Johnny Chenf667ab52010-12-21 02:06:56 +000037 self.buildDsym()
Johnny Chen3635eae2010-12-21 19:52:54 +000038 self.do_wait_for_event()
Johnny Chenf667ab52010-12-21 02:06:56 +000039
40 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000041 @dwarf_test
Johnny Chen3635eae2010-12-21 19:52:54 +000042 def test_wait_for_event_with_dwarf(self):
Johnny Chenf2df1892010-12-22 00:32:54 +000043 """Exercise SBListener.WaitForEvent() API."""
Johnny Chenf667ab52010-12-21 02:06:56 +000044 self.buildDwarf()
Johnny Chen3635eae2010-12-21 19:52:54 +000045 self.do_wait_for_event()
Johnny Chenf667ab52010-12-21 02:06:56 +000046
Robert Flack13c7ad92015-03-30 14:12:17 +000047 @skipUnlessDarwin
Johnny Chenf2df1892010-12-22 00:32:54 +000048 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000049 @dsym_test
50 def test_add_listener_to_broadcaster_with_dsym(self):
Johnny Chen77c46972010-12-22 00:56:47 +000051 """Exercise some SBBroadcaster APIs."""
Johnny Chenf2df1892010-12-22 00:32:54 +000052 self.buildDsym()
Johnny Chen77c46972010-12-22 00:56:47 +000053 self.do_add_listener_to_broadcaster()
Johnny Chenf2df1892010-12-22 00:32:54 +000054
Ed Maste2ec8e1b2014-10-29 20:02:54 +000055 @skipIfFreeBSD # llvm.org/pr21325
Johnny Chenf2df1892010-12-22 00:32:54 +000056 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000057 @dwarf_test
Tamas Berghammera98788d2015-05-21 14:04:17 +000058 @expectedFailureLinux("llvm.org/pr23617") # Flaky, fails ~1/10 cases
Johnny Chen24086bc2012-04-06 19:54:10 +000059 def test_add_listener_to_broadcaster_with_dwarf(self):
Johnny Chen77c46972010-12-22 00:56:47 +000060 """Exercise some SBBroadcaster APIs."""
Johnny Chenf2df1892010-12-22 00:32:54 +000061 self.buildDwarf()
Johnny Chen77c46972010-12-22 00:56:47 +000062 self.do_add_listener_to_broadcaster()
Johnny Chenf2df1892010-12-22 00:32:54 +000063
Johnny Chenf667ab52010-12-21 02:06:56 +000064 def setUp(self):
65 # Call super's setUp().
66 TestBase.setUp(self)
67 # Find the line number to of function 'c'.
68 self.line = line_number('main.c', '// Find the line number of function "c" here.')
69
Johnny Chen3a709ac2011-07-08 23:02:33 +000070 def do_listen_for_and_print_event(self):
71 """Create a listener and use SBEvent API to print the events received."""
72 exe = os.path.join(os.getcwd(), "a.out")
73
Greg Claytona6cffde2014-10-17 23:58:27 +000074 self.dbg.SetAsync(True)
75
Johnny Chen3a709ac2011-07-08 23:02:33 +000076 # Create a target by the debugger.
77 target = self.dbg.CreateTarget(exe)
78 self.assertTrue(target, VALID_TARGET)
79
80 # Now create a breakpoint on main.c by name 'c'.
81 breakpoint = target.BreakpointCreateByName('c', 'a.out')
82
Greg Claytona6cffde2014-10-17 23:58:27 +000083 listener = lldb.SBListener("my listener")
Johnny Chen3a709ac2011-07-08 23:02:33 +000084
Greg Claytona6cffde2014-10-17 23:58:27 +000085 # Now launch the process, and do not stop at the entry point.
86 error = lldb.SBError()
87 process = target.Launch (listener,
88 None, # argv
89 None, # envp
90 None, # stdin_path
91 None, # stdout_path
92 None, # stderr_path
93 None, # working directory
94 0, # launch flags
95 False, # Stop at entry
96 error) # error
97
98 self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
Johnny Chen3a709ac2011-07-08 23:02:33 +000099
100 # Create an empty event object.
101 event = lldb.SBEvent()
102
Johnny Chen3a709ac2011-07-08 23:02:33 +0000103 traceOn = self.TraceOn()
104 if traceOn:
105 lldbutil.print_stacktraces(process)
106
107 # Create MyListeningThread class to wait for any kind of event.
108 import threading
109 class MyListeningThread(threading.Thread):
110 def run(self):
111 count = 0
112 # Let's only try at most 4 times to retrieve any kind of event.
113 # After that, the thread exits.
114 while not count > 3:
115 if traceOn:
116 print "Try wait for event..."
Greg Claytona6cffde2014-10-17 23:58:27 +0000117 if listener.WaitForEvent(5, event):
Johnny Chen3a709ac2011-07-08 23:02:33 +0000118 if traceOn:
119 desc = lldbutil.get_description(event)
120 print "Event description:", desc
121 print "Event data flavor:", event.GetDataFlavor()
122 print "Process state:", lldbutil.state_type_to_str(process.GetState())
123 print
124 else:
125 if traceOn:
126 print "timeout occurred waiting for event..."
127 count = count + 1
128 return
129
130 # Let's start the listening thread to retrieve the events.
131 my_thread = MyListeningThread()
132 my_thread.start()
133
134 # Use Python API to continue the process. The listening thread should be
135 # able to receive the state changed events.
136 process.Continue()
137
138 # Use Python API to kill the process. The listening thread should be
139 # able to receive the state changed event, too.
140 process.Kill()
141
142 # Wait until the 'MyListeningThread' terminates.
143 my_thread.join()
144
Johnny Chen3635eae2010-12-21 19:52:54 +0000145 def do_wait_for_event(self):
146 """Get the listener associated with the debugger and exercise WaitForEvent API."""
Johnny Chenf667ab52010-12-21 02:06:56 +0000147 exe = os.path.join(os.getcwd(), "a.out")
148
Greg Claytona6cffde2014-10-17 23:58:27 +0000149 self.dbg.SetAsync(True)
150
Johnny Chenf667ab52010-12-21 02:06:56 +0000151 # Create a target by the debugger.
152 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000153 self.assertTrue(target, VALID_TARGET)
Johnny Chenf667ab52010-12-21 02:06:56 +0000154
155 # Now create a breakpoint on main.c by name 'c'.
156 breakpoint = target.BreakpointCreateByName('c', 'a.out')
157 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000158 self.assertTrue(breakpoint and
Johnny Chenf667ab52010-12-21 02:06:56 +0000159 breakpoint.GetNumLocations() == 1,
160 VALID_BREAKPOINT)
161
Johnny Chend762ff12011-02-03 23:15:53 +0000162 # Get the debugger listener.
163 listener = self.dbg.GetListener()
164
Johnny Chenf667ab52010-12-21 02:06:56 +0000165 # Now launch the process, and do not stop at entry point.
Greg Clayton6f907e62011-01-23 17:46:22 +0000166 error = lldb.SBError()
Greg Claytona6cffde2014-10-17 23:58:27 +0000167 process = target.Launch (listener,
168 None, # argv
169 None, # envp
170 None, # stdin_path
171 None, # stdout_path
172 None, # stderr_path
173 None, # working directory
174 0, # launch flags
175 False, # Stop at entry
176 error) # error
Johnny Chen2494f552011-07-20 00:14:20 +0000177 self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
Johnny Chenf667ab52010-12-21 02:06:56 +0000178
Johnny Chenf667ab52010-12-21 02:06:56 +0000179 # Create an empty event object.
180 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000181 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf667ab52010-12-21 02:06:56 +0000182
Johnny Chenf667ab52010-12-21 02:06:56 +0000183 # Create MyListeningThread to wait for any kind of event.
184 import threading
185 class MyListeningThread(threading.Thread):
186 def run(self):
Johnny Chenf667ab52010-12-21 02:06:56 +0000187 count = 0
188 # Let's only try at most 3 times to retrieve any kind of event.
189 while not count > 3:
190 if listener.WaitForEvent(5, event):
Johnny Chenf2df1892010-12-22 00:32:54 +0000191 #print "Got a valid event:", event
Johnny Chen3a709ac2011-07-08 23:02:33 +0000192 #print "Event data flavor:", event.GetDataFlavor()
193 #print "Event type:", lldbutil.state_type_to_str(event.GetType())
Johnny Chenf667ab52010-12-21 02:06:56 +0000194 return
195 count = count + 1
196 print "Timeout: listener.WaitForEvent"
197
198 return
199
Johnny Chen4f8caab2010-12-21 05:43:37 +0000200 # Use Python API to kill the process. The listening thread should be
201 # able to receive a state changed event.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000202 process.Kill()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000203
Johnny Chenf2df1892010-12-22 00:32:54 +0000204 # Let's start the listening thread to retrieve the event.
205 my_thread = MyListeningThread()
206 my_thread.start()
207
Johnny Chen4f8caab2010-12-21 05:43:37 +0000208 # Wait until the 'MyListeningThread' terminates.
Johnny Chenf667ab52010-12-21 02:06:56 +0000209 my_thread.join()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000210
Johnny Chen4ebd0192011-05-24 18:22:45 +0000211 self.assertTrue(event,
Johnny Chenf2df1892010-12-22 00:32:54 +0000212 "My listening thread successfully received an event")
Johnny Chen4f8caab2010-12-21 05:43:37 +0000213
Johnny Chen77c46972010-12-22 00:56:47 +0000214 def do_add_listener_to_broadcaster(self):
215 """Get the broadcaster associated with the process and wait for broadcaster events."""
Johnny Chenf2df1892010-12-22 00:32:54 +0000216 exe = os.path.join(os.getcwd(), "a.out")
217
Greg Claytona6cffde2014-10-17 23:58:27 +0000218 self.dbg.SetAsync(True)
219
Johnny Chenf2df1892010-12-22 00:32:54 +0000220 # Create a target by the debugger.
221 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000222 self.assertTrue(target, VALID_TARGET)
Johnny Chenf2df1892010-12-22 00:32:54 +0000223
224 # Now create a breakpoint on main.c by name 'c'.
225 breakpoint = target.BreakpointCreateByName('c', 'a.out')
226 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000227 self.assertTrue(breakpoint and
Johnny Chenf2df1892010-12-22 00:32:54 +0000228 breakpoint.GetNumLocations() == 1,
229 VALID_BREAKPOINT)
230
Greg Claytona6cffde2014-10-17 23:58:27 +0000231 listener = lldb.SBListener("my listener")
Johnny Chenf2df1892010-12-22 00:32:54 +0000232
Greg Claytona6cffde2014-10-17 23:58:27 +0000233 # Now launch the process, and do not stop at the entry point.
234 error = lldb.SBError()
235 process = target.Launch (listener,
236 None, # argv
237 None, # envp
238 None, # stdin_path
239 None, # stdout_path
240 None, # stderr_path
241 None, # working directory
242 0, # launch flags
243 False, # Stop at entry
244 error) # error
Johnny Chenf2df1892010-12-22 00:32:54 +0000245
246 # Create an empty event object.
247 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000248 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf2df1892010-12-22 00:32:54 +0000249
Johnny Chenf2df1892010-12-22 00:32:54 +0000250
251 # The finite state machine for our custom listening thread, with an
Bruce Mitchenere171da52015-07-22 00:16:02 +0000252 # initial state of None, which means no event has been received.
Siva Chandra8a1f7692015-05-08 00:43:28 +0000253 # It changes to 'connected' after 'connected' event is received (for remote platforms)
254 # It changes to 'running' after 'running' event is received (should happen only if the
255 # currentstate is either 'None' or 'connected')
256 # It changes to 'stopped' if a 'stopped' event is received (should happen only if the
257 # current state is 'running'.)
258 self.state = None
Johnny Chenf2df1892010-12-22 00:32:54 +0000259
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;
Siva Chandra8a1f7692015-05-08 00:43:28 +0000279 if match.group(1) == 'connected':
280 # When debugging remote targets with lldb-server, we
281 # first get the 'connected' event.
282 self.context.assertTrue(self.context.state == None)
283 self.context.state = 'connected'
Johnny Chenf2df1892010-12-22 00:32:54 +0000284 continue
Siva Chandra8a1f7692015-05-08 00:43:28 +0000285 elif match.group(1) == 'running':
286 self.context.assertTrue(self.context.state == None or self.context.state == 'connected')
287 self.context.state = 'running'
288 continue
289 elif match.group(1) == 'stopped':
290 self.context.assertTrue(self.context.state == 'running')
Johnny Chenf2df1892010-12-22 00:32:54 +0000291 # Whoopee, both events have been received!
Siva Chandra8a1f7692015-05-08 00:43:28 +0000292 self.context.state = 'stopped'
Johnny Chenf2df1892010-12-22 00:32:54 +0000293 break
294 else:
295 break
296 print "Timeout: listener.WaitForEvent"
297 count = count + 1
298 if count > 6:
299 break
300
301 return
302
303 # Use Python API to continue the process. The listening thread should be
304 # able to receive the state changed events.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000305 process.Continue()
Johnny Chenf2df1892010-12-22 00:32:54 +0000306
307 # Start the listening thread to receive the "running" followed by the
308 # "stopped" events.
309 my_thread = MyListeningThread()
310 # Supply the enclosing context so that our listening thread can access
311 # the 'state' variable.
312 my_thread.context = self
313 my_thread.start()
314
315 # Wait until the 'MyListeningThread' terminates.
316 my_thread.join()
317
Johnny Chenf2df1892010-12-22 00:32:54 +0000318 # The final judgement. :-)
Siva Chandra8a1f7692015-05-08 00:43:28 +0000319 self.assertTrue(self.state == 'stopped',
Johnny Chenf2df1892010-12-22 00:32:54 +0000320 "Both expected state changed events received")
Johnny Chenf667ab52010-12-21 02:06:56 +0000321
322
323if __name__ == '__main__':
324 import atexit
325 lldb.SBDebugger.Initialize()
326 atexit.register(lambda: lldb.SBDebugger.Terminate())
327 unittest2.main()