blob: d79ba333bb5dc249feb8e628088be7c358bac76e [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
Robert Flack13c7ad92015-03-30 14:12:17 +000023 @skipUnlessPlatform(["darwin", "macosx", "freebsd"])
Johnny Chen3a709ac2011-07-08 23:02:33 +000024 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000025 @dwarf_test
Johnny Chen3a709ac2011-07-08 23:02:33 +000026 def test_listen_for_and_print_event_with_dwarf(self):
27 """Exercise SBEvent API."""
28 self.buildDwarf()
29 self.do_listen_for_and_print_event()
30
Robert Flack13c7ad92015-03-30 14:12:17 +000031 @skipUnlessDarwin
Johnny Chen3a709ac2011-07-08 23:02:33 +000032 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000033 @dsym_test
Johnny Chen3635eae2010-12-21 19:52:54 +000034 def test_wait_for_event_with_dsym(self):
Johnny Chenf2df1892010-12-22 00:32:54 +000035 """Exercise SBListener.WaitForEvent() API."""
Johnny Chenf667ab52010-12-21 02:06:56 +000036 self.buildDsym()
Johnny Chen3635eae2010-12-21 19:52:54 +000037 self.do_wait_for_event()
Johnny Chenf667ab52010-12-21 02:06:56 +000038
Siva Chandraaaa3d472014-12-19 22:41:43 +000039 @skipIfLinux # non-core functionality, need to reenable and fix later (DES 2014.11.07)
Johnny Chenf667ab52010-12-21 02:06:56 +000040 @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
Siva Chandraaaa3d472014-12-19 22:41:43 +000056 @skipIfLinux # non-core functionality, need to reenable and fix later (DES 2014.11.07)
Johnny Chenf2df1892010-12-22 00:32:54 +000057 @python_api_test
Johnny Chen24086bc2012-04-06 19:54:10 +000058 @dwarf_test
59 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
252 # initail state of 0, which means a "running" event is expected.
253 # It changes to 1 after "running" is received.
254 # It cahnges to 2 after "stopped" is received.
255 # 2 will be our final state and the test is complete.
256 self.state = 0
257
258 # Create MyListeningThread to wait for state changed events.
259 # By design, a "running" event is expected following by a "stopped" event.
260 import threading
261 class MyListeningThread(threading.Thread):
262 def run(self):
263 #print "Running MyListeningThread:", self
264
265 # Regular expression pattern for the event description.
266 pattern = re.compile("data = {.*, state = (.*)}$")
267
268 # Let's only try at most 6 times to retrieve our events.
269 count = 0
270 while True:
Greg Claytona6cffde2014-10-17 23:58:27 +0000271 if listener.WaitForEvent(5, event):
Johnny Chen9ae98202011-04-23 00:34:56 +0000272 desc = lldbutil.get_description(event)
273 #print "Event description:", desc
274 match = pattern.search(desc)
Johnny Chenf2df1892010-12-22 00:32:54 +0000275 if not match:
276 break;
277 if self.context.state == 0 and match.group(1) == 'running':
278 self.context.state = 1
279 continue
280 elif self.context.state == 1 and match.group(1) == 'stopped':
281 # Whoopee, both events have been received!
282 self.context.state = 2
283 break
284 else:
285 break
286 print "Timeout: listener.WaitForEvent"
287 count = count + 1
288 if count > 6:
289 break
290
291 return
292
293 # Use Python API to continue the process. The listening thread should be
294 # able to receive the state changed events.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000295 process.Continue()
Johnny Chenf2df1892010-12-22 00:32:54 +0000296
297 # Start the listening thread to receive the "running" followed by the
298 # "stopped" events.
299 my_thread = MyListeningThread()
300 # Supply the enclosing context so that our listening thread can access
301 # the 'state' variable.
302 my_thread.context = self
303 my_thread.start()
304
305 # Wait until the 'MyListeningThread' terminates.
306 my_thread.join()
307
Johnny Chenf2df1892010-12-22 00:32:54 +0000308 # The final judgement. :-)
309 self.assertTrue(self.state == 2,
310 "Both expected state changed events received")
Johnny Chenf667ab52010-12-21 02:06:56 +0000311
312
313if __name__ == '__main__':
314 import atexit
315 lldb.SBDebugger.Initialize()
316 atexit.register(lambda: lldb.SBDebugger.Terminate())
317 unittest2.main()