blob: cc7440815181d4c96e2dbfc38e82b23478a7127e [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
Johnny Chenf667ab52010-12-21 02:06:56 +000015 def setUp(self):
16 # Call super's setUp().
17 TestBase.setUp(self)
18 # Find the line number to of function 'c'.
19 self.line = line_number('main.c', '// Find the line number of function "c" here.')
20
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000021 @python_api_test
22 @expectedFailureLinux("llvm.org/pr23730") # Flaky, fails ~1/10 cases
23 @skipIfLinux # skip to avoid crashes
24 def test_listen_for_and_print_event(self):
25 """Exercise SBEvent API."""
26 self.build()
Johnny Chen3a709ac2011-07-08 23:02:33 +000027 exe = os.path.join(os.getcwd(), "a.out")
28
Greg Claytona6cffde2014-10-17 23:58:27 +000029 self.dbg.SetAsync(True)
30
Johnny Chen3a709ac2011-07-08 23:02:33 +000031 # Create a target by the debugger.
32 target = self.dbg.CreateTarget(exe)
33 self.assertTrue(target, VALID_TARGET)
34
35 # Now create a breakpoint on main.c by name 'c'.
36 breakpoint = target.BreakpointCreateByName('c', 'a.out')
37
Greg Claytona6cffde2014-10-17 23:58:27 +000038 listener = lldb.SBListener("my listener")
Johnny Chen3a709ac2011-07-08 23:02:33 +000039
Greg Claytona6cffde2014-10-17 23:58:27 +000040 # Now launch the process, and do not stop at the entry point.
41 error = lldb.SBError()
42 process = target.Launch (listener,
43 None, # argv
44 None, # envp
45 None, # stdin_path
46 None, # stdout_path
47 None, # stderr_path
48 None, # working directory
49 0, # launch flags
50 False, # Stop at entry
51 error) # error
52
53 self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
Johnny Chen3a709ac2011-07-08 23:02:33 +000054
55 # Create an empty event object.
56 event = lldb.SBEvent()
57
Johnny Chen3a709ac2011-07-08 23:02:33 +000058 traceOn = self.TraceOn()
59 if traceOn:
60 lldbutil.print_stacktraces(process)
61
62 # Create MyListeningThread class to wait for any kind of event.
63 import threading
64 class MyListeningThread(threading.Thread):
65 def run(self):
66 count = 0
67 # Let's only try at most 4 times to retrieve any kind of event.
68 # After that, the thread exits.
69 while not count > 3:
70 if traceOn:
71 print "Try wait for event..."
Greg Claytona6cffde2014-10-17 23:58:27 +000072 if listener.WaitForEvent(5, event):
Johnny Chen3a709ac2011-07-08 23:02:33 +000073 if traceOn:
74 desc = lldbutil.get_description(event)
75 print "Event description:", desc
76 print "Event data flavor:", event.GetDataFlavor()
77 print "Process state:", lldbutil.state_type_to_str(process.GetState())
78 print
79 else:
80 if traceOn:
81 print "timeout occurred waiting for event..."
82 count = count + 1
83 return
84
85 # Let's start the listening thread to retrieve the events.
86 my_thread = MyListeningThread()
87 my_thread.start()
88
89 # Use Python API to continue the process. The listening thread should be
90 # able to receive the state changed events.
91 process.Continue()
92
93 # Use Python API to kill the process. The listening thread should be
94 # able to receive the state changed event, too.
95 process.Kill()
96
97 # Wait until the 'MyListeningThread' terminates.
98 my_thread.join()
99
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000100 @python_api_test
101 def test_wait_for_event(self):
102 """Exercise SBListener.WaitForEvent() API."""
103 self.build()
Johnny Chenf667ab52010-12-21 02:06:56 +0000104 exe = os.path.join(os.getcwd(), "a.out")
105
Greg Claytona6cffde2014-10-17 23:58:27 +0000106 self.dbg.SetAsync(True)
107
Johnny Chenf667ab52010-12-21 02:06:56 +0000108 # Create a target by the debugger.
109 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000110 self.assertTrue(target, VALID_TARGET)
Johnny Chenf667ab52010-12-21 02:06:56 +0000111
112 # Now create a breakpoint on main.c by name 'c'.
113 breakpoint = target.BreakpointCreateByName('c', 'a.out')
114 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000115 self.assertTrue(breakpoint and
Johnny Chenf667ab52010-12-21 02:06:56 +0000116 breakpoint.GetNumLocations() == 1,
117 VALID_BREAKPOINT)
118
Johnny Chend762ff12011-02-03 23:15:53 +0000119 # Get the debugger listener.
120 listener = self.dbg.GetListener()
121
Johnny Chenf667ab52010-12-21 02:06:56 +0000122 # Now launch the process, and do not stop at entry point.
Greg Clayton6f907e62011-01-23 17:46:22 +0000123 error = lldb.SBError()
Greg Claytona6cffde2014-10-17 23:58:27 +0000124 process = target.Launch (listener,
125 None, # argv
126 None, # envp
127 None, # stdin_path
128 None, # stdout_path
129 None, # stderr_path
130 None, # working directory
131 0, # launch flags
132 False, # Stop at entry
133 error) # error
Johnny Chen2494f552011-07-20 00:14:20 +0000134 self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
Johnny Chenf667ab52010-12-21 02:06:56 +0000135
Johnny Chenf667ab52010-12-21 02:06:56 +0000136 # Create an empty event object.
137 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000138 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf667ab52010-12-21 02:06:56 +0000139
Johnny Chenf667ab52010-12-21 02:06:56 +0000140 # Create MyListeningThread to wait for any kind of event.
141 import threading
142 class MyListeningThread(threading.Thread):
143 def run(self):
Johnny Chenf667ab52010-12-21 02:06:56 +0000144 count = 0
145 # Let's only try at most 3 times to retrieve any kind of event.
146 while not count > 3:
147 if listener.WaitForEvent(5, event):
Johnny Chenf2df1892010-12-22 00:32:54 +0000148 #print "Got a valid event:", event
Johnny Chen3a709ac2011-07-08 23:02:33 +0000149 #print "Event data flavor:", event.GetDataFlavor()
150 #print "Event type:", lldbutil.state_type_to_str(event.GetType())
Johnny Chenf667ab52010-12-21 02:06:56 +0000151 return
152 count = count + 1
153 print "Timeout: listener.WaitForEvent"
154
155 return
156
Johnny Chen4f8caab2010-12-21 05:43:37 +0000157 # Use Python API to kill the process. The listening thread should be
158 # able to receive a state changed event.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000159 process.Kill()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000160
Johnny Chenf2df1892010-12-22 00:32:54 +0000161 # Let's start the listening thread to retrieve the event.
162 my_thread = MyListeningThread()
163 my_thread.start()
164
Johnny Chen4f8caab2010-12-21 05:43:37 +0000165 # Wait until the 'MyListeningThread' terminates.
Johnny Chenf667ab52010-12-21 02:06:56 +0000166 my_thread.join()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000167
Johnny Chen4ebd0192011-05-24 18:22:45 +0000168 self.assertTrue(event,
Johnny Chenf2df1892010-12-22 00:32:54 +0000169 "My listening thread successfully received an event")
Johnny Chen4f8caab2010-12-21 05:43:37 +0000170
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000171 @skipIfFreeBSD # llvm.org/pr21325
172 @python_api_test
173 @expectedFlakeyLinux("llvm.org/pr23617") # Flaky, fails ~1/10 cases
174 @expectedFailureWindows("llvm.org/pr24778")
175 def test_add_listener_to_broadcaster(self):
176 """Exercise some SBBroadcaster APIs."""
177 self.build()
Johnny Chenf2df1892010-12-22 00:32:54 +0000178 exe = os.path.join(os.getcwd(), "a.out")
179
Greg Claytona6cffde2014-10-17 23:58:27 +0000180 self.dbg.SetAsync(True)
181
Johnny Chenf2df1892010-12-22 00:32:54 +0000182 # Create a target by the debugger.
183 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000184 self.assertTrue(target, VALID_TARGET)
Johnny Chenf2df1892010-12-22 00:32:54 +0000185
186 # Now create a breakpoint on main.c by name 'c'.
187 breakpoint = target.BreakpointCreateByName('c', 'a.out')
188 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000189 self.assertTrue(breakpoint and
Johnny Chenf2df1892010-12-22 00:32:54 +0000190 breakpoint.GetNumLocations() == 1,
191 VALID_BREAKPOINT)
192
Greg Claytona6cffde2014-10-17 23:58:27 +0000193 listener = lldb.SBListener("my listener")
Johnny Chenf2df1892010-12-22 00:32:54 +0000194
Greg Claytona6cffde2014-10-17 23:58:27 +0000195 # Now launch the process, and do not stop at the entry point.
196 error = lldb.SBError()
197 process = target.Launch (listener,
198 None, # argv
199 None, # envp
200 None, # stdin_path
201 None, # stdout_path
202 None, # stderr_path
203 None, # working directory
204 0, # launch flags
205 False, # Stop at entry
206 error) # error
Johnny Chenf2df1892010-12-22 00:32:54 +0000207
208 # Create an empty event object.
209 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000210 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf2df1892010-12-22 00:32:54 +0000211
Johnny Chenf2df1892010-12-22 00:32:54 +0000212
213 # The finite state machine for our custom listening thread, with an
Bruce Mitchenere171da52015-07-22 00:16:02 +0000214 # initial state of None, which means no event has been received.
Siva Chandra8a1f7692015-05-08 00:43:28 +0000215 # It changes to 'connected' after 'connected' event is received (for remote platforms)
216 # It changes to 'running' after 'running' event is received (should happen only if the
217 # currentstate is either 'None' or 'connected')
218 # It changes to 'stopped' if a 'stopped' event is received (should happen only if the
219 # current state is 'running'.)
220 self.state = None
Johnny Chenf2df1892010-12-22 00:32:54 +0000221
222 # Create MyListeningThread to wait for state changed events.
223 # By design, a "running" event is expected following by a "stopped" event.
224 import threading
225 class MyListeningThread(threading.Thread):
226 def run(self):
227 #print "Running MyListeningThread:", self
228
229 # Regular expression pattern for the event description.
230 pattern = re.compile("data = {.*, state = (.*)}$")
231
232 # Let's only try at most 6 times to retrieve our events.
233 count = 0
234 while True:
Greg Claytona6cffde2014-10-17 23:58:27 +0000235 if listener.WaitForEvent(5, event):
Johnny Chen9ae98202011-04-23 00:34:56 +0000236 desc = lldbutil.get_description(event)
237 #print "Event description:", desc
238 match = pattern.search(desc)
Johnny Chenf2df1892010-12-22 00:32:54 +0000239 if not match:
240 break;
Siva Chandra8a1f7692015-05-08 00:43:28 +0000241 if match.group(1) == 'connected':
242 # When debugging remote targets with lldb-server, we
243 # first get the 'connected' event.
244 self.context.assertTrue(self.context.state == None)
245 self.context.state = 'connected'
Johnny Chenf2df1892010-12-22 00:32:54 +0000246 continue
Siva Chandra8a1f7692015-05-08 00:43:28 +0000247 elif match.group(1) == 'running':
248 self.context.assertTrue(self.context.state == None or self.context.state == 'connected')
249 self.context.state = 'running'
250 continue
251 elif match.group(1) == 'stopped':
252 self.context.assertTrue(self.context.state == 'running')
Johnny Chenf2df1892010-12-22 00:32:54 +0000253 # Whoopee, both events have been received!
Siva Chandra8a1f7692015-05-08 00:43:28 +0000254 self.context.state = 'stopped'
Johnny Chenf2df1892010-12-22 00:32:54 +0000255 break
256 else:
257 break
258 print "Timeout: listener.WaitForEvent"
259 count = count + 1
260 if count > 6:
261 break
262
263 return
264
265 # Use Python API to continue the process. The listening thread should be
266 # able to receive the state changed events.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000267 process.Continue()
Johnny Chenf2df1892010-12-22 00:32:54 +0000268
269 # Start the listening thread to receive the "running" followed by the
270 # "stopped" events.
271 my_thread = MyListeningThread()
272 # Supply the enclosing context so that our listening thread can access
273 # the 'state' variable.
274 my_thread.context = self
275 my_thread.start()
276
277 # Wait until the 'MyListeningThread' terminates.
278 my_thread.join()
279
Johnny Chenf2df1892010-12-22 00:32:54 +0000280 # The final judgement. :-)
Siva Chandra8a1f7692015-05-08 00:43:28 +0000281 self.assertTrue(self.state == 'stopped',
Johnny Chenf2df1892010-12-22 00:32:54 +0000282 "Both expected state changed events received")
Johnny Chenf667ab52010-12-21 02:06:56 +0000283
Johnny Chenf667ab52010-12-21 02:06:56 +0000284if __name__ == '__main__':
285 import atexit
286 lldb.SBDebugger.Initialize()
287 atexit.register(lambda: lldb.SBDebugger.Terminate())
288 unittest2.main()