blob: f2d52570d25d3a0cce62fabbbceafdb8fff38160 [file] [log] [blame]
Johnny Chenf667ab52010-12-21 02:06:56 +00001"""
2Test lldb Python event APIs.
3"""
4
Zachary Turner77db4a82015-10-22 20:06:20 +00005import lldb_shared
6
Johnny Chenf667ab52010-12-21 02:06:56 +00007import os, time
8import re
Johnny Chenf667ab52010-12-21 02:06:56 +00009import lldb, lldbutil
10from lldbtest import *
11
12class EventAPITestCase(TestBase):
13
Greg Clayton4570d3e2013-12-10 23:19:29 +000014 mydir = TestBase.compute_mydir(__file__)
Johnny Chenf667ab52010-12-21 02:06:56 +000015
Johnny Chenf667ab52010-12-21 02:06:56 +000016 def setUp(self):
17 # Call super's setUp().
18 TestBase.setUp(self)
19 # Find the line number to of function 'c'.
20 self.line = line_number('main.c', '// Find the line number of function "c" here.')
21
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000022 @python_api_test
23 @expectedFailureLinux("llvm.org/pr23730") # Flaky, fails ~1/10 cases
24 @skipIfLinux # skip to avoid crashes
25 def test_listen_for_and_print_event(self):
26 """Exercise SBEvent API."""
27 self.build()
Johnny Chen3a709ac2011-07-08 23:02:33 +000028 exe = os.path.join(os.getcwd(), "a.out")
29
Greg Claytona6cffde2014-10-17 23:58:27 +000030 self.dbg.SetAsync(True)
31
Johnny Chen3a709ac2011-07-08 23:02:33 +000032 # Create a target by the debugger.
33 target = self.dbg.CreateTarget(exe)
34 self.assertTrue(target, VALID_TARGET)
35
36 # Now create a breakpoint on main.c by name 'c'.
37 breakpoint = target.BreakpointCreateByName('c', 'a.out')
38
Greg Claytona6cffde2014-10-17 23:58:27 +000039 listener = lldb.SBListener("my listener")
Johnny Chen3a709ac2011-07-08 23:02:33 +000040
Greg Claytona6cffde2014-10-17 23:58:27 +000041 # Now launch the process, and do not stop at the entry point.
42 error = lldb.SBError()
43 process = target.Launch (listener,
44 None, # argv
45 None, # envp
46 None, # stdin_path
47 None, # stdout_path
48 None, # stderr_path
49 None, # working directory
50 0, # launch flags
51 False, # Stop at entry
52 error) # error
53
54 self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
Johnny Chen3a709ac2011-07-08 23:02:33 +000055
56 # Create an empty event object.
57 event = lldb.SBEvent()
58
Johnny Chen3a709ac2011-07-08 23:02:33 +000059 traceOn = self.TraceOn()
60 if traceOn:
61 lldbutil.print_stacktraces(process)
62
63 # Create MyListeningThread class to wait for any kind of event.
64 import threading
65 class MyListeningThread(threading.Thread):
66 def run(self):
67 count = 0
68 # Let's only try at most 4 times to retrieve any kind of event.
69 # After that, the thread exits.
70 while not count > 3:
71 if traceOn:
72 print "Try wait for event..."
Greg Claytona6cffde2014-10-17 23:58:27 +000073 if listener.WaitForEvent(5, event):
Johnny Chen3a709ac2011-07-08 23:02:33 +000074 if traceOn:
75 desc = lldbutil.get_description(event)
76 print "Event description:", desc
77 print "Event data flavor:", event.GetDataFlavor()
78 print "Process state:", lldbutil.state_type_to_str(process.GetState())
79 print
80 else:
81 if traceOn:
82 print "timeout occurred waiting for event..."
83 count = count + 1
84 return
85
86 # Let's start the listening thread to retrieve the events.
87 my_thread = MyListeningThread()
88 my_thread.start()
89
90 # Use Python API to continue the process. The listening thread should be
91 # able to receive the state changed events.
92 process.Continue()
93
94 # Use Python API to kill the process. The listening thread should be
95 # able to receive the state changed event, too.
96 process.Kill()
97
98 # Wait until the 'MyListeningThread' terminates.
99 my_thread.join()
100
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000101 @python_api_test
102 def test_wait_for_event(self):
103 """Exercise SBListener.WaitForEvent() API."""
104 self.build()
Johnny Chenf667ab52010-12-21 02:06:56 +0000105 exe = os.path.join(os.getcwd(), "a.out")
106
Greg Claytona6cffde2014-10-17 23:58:27 +0000107 self.dbg.SetAsync(True)
108
Johnny Chenf667ab52010-12-21 02:06:56 +0000109 # Create a target by the debugger.
110 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000111 self.assertTrue(target, VALID_TARGET)
Johnny Chenf667ab52010-12-21 02:06:56 +0000112
113 # Now create a breakpoint on main.c by name 'c'.
114 breakpoint = target.BreakpointCreateByName('c', 'a.out')
115 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000116 self.assertTrue(breakpoint and
Johnny Chenf667ab52010-12-21 02:06:56 +0000117 breakpoint.GetNumLocations() == 1,
118 VALID_BREAKPOINT)
119
Johnny Chend762ff12011-02-03 23:15:53 +0000120 # Get the debugger listener.
121 listener = self.dbg.GetListener()
122
Johnny Chenf667ab52010-12-21 02:06:56 +0000123 # Now launch the process, and do not stop at entry point.
Greg Clayton6f907e62011-01-23 17:46:22 +0000124 error = lldb.SBError()
Greg Claytona6cffde2014-10-17 23:58:27 +0000125 process = target.Launch (listener,
126 None, # argv
127 None, # envp
128 None, # stdin_path
129 None, # stdout_path
130 None, # stderr_path
131 None, # working directory
132 0, # launch flags
133 False, # Stop at entry
134 error) # error
Johnny Chen2494f552011-07-20 00:14:20 +0000135 self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
Johnny Chenf667ab52010-12-21 02:06:56 +0000136
Johnny Chenf667ab52010-12-21 02:06:56 +0000137 # Create an empty event object.
138 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000139 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf667ab52010-12-21 02:06:56 +0000140
Johnny Chenf667ab52010-12-21 02:06:56 +0000141 # Create MyListeningThread to wait for any kind of event.
142 import threading
143 class MyListeningThread(threading.Thread):
144 def run(self):
Johnny Chenf667ab52010-12-21 02:06:56 +0000145 count = 0
146 # Let's only try at most 3 times to retrieve any kind of event.
147 while not count > 3:
148 if listener.WaitForEvent(5, event):
Johnny Chenf2df1892010-12-22 00:32:54 +0000149 #print "Got a valid event:", event
Johnny Chen3a709ac2011-07-08 23:02:33 +0000150 #print "Event data flavor:", event.GetDataFlavor()
151 #print "Event type:", lldbutil.state_type_to_str(event.GetType())
Johnny Chenf667ab52010-12-21 02:06:56 +0000152 return
153 count = count + 1
154 print "Timeout: listener.WaitForEvent"
155
156 return
157
Johnny Chen4f8caab2010-12-21 05:43:37 +0000158 # Use Python API to kill the process. The listening thread should be
159 # able to receive a state changed event.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000160 process.Kill()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000161
Johnny Chenf2df1892010-12-22 00:32:54 +0000162 # Let's start the listening thread to retrieve the event.
163 my_thread = MyListeningThread()
164 my_thread.start()
165
Johnny Chen4f8caab2010-12-21 05:43:37 +0000166 # Wait until the 'MyListeningThread' terminates.
Johnny Chenf667ab52010-12-21 02:06:56 +0000167 my_thread.join()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000168
Johnny Chen4ebd0192011-05-24 18:22:45 +0000169 self.assertTrue(event,
Johnny Chenf2df1892010-12-22 00:32:54 +0000170 "My listening thread successfully received an event")
Johnny Chen4f8caab2010-12-21 05:43:37 +0000171
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000172 @skipIfFreeBSD # llvm.org/pr21325
173 @python_api_test
174 @expectedFlakeyLinux("llvm.org/pr23617") # Flaky, fails ~1/10 cases
175 @expectedFailureWindows("llvm.org/pr24778")
176 def test_add_listener_to_broadcaster(self):
177 """Exercise some SBBroadcaster APIs."""
178 self.build()
Johnny Chenf2df1892010-12-22 00:32:54 +0000179 exe = os.path.join(os.getcwd(), "a.out")
180
Greg Claytona6cffde2014-10-17 23:58:27 +0000181 self.dbg.SetAsync(True)
182
Johnny Chenf2df1892010-12-22 00:32:54 +0000183 # Create a target by the debugger.
184 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000185 self.assertTrue(target, VALID_TARGET)
Johnny Chenf2df1892010-12-22 00:32:54 +0000186
187 # Now create a breakpoint on main.c by name 'c'.
188 breakpoint = target.BreakpointCreateByName('c', 'a.out')
189 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000190 self.assertTrue(breakpoint and
Johnny Chenf2df1892010-12-22 00:32:54 +0000191 breakpoint.GetNumLocations() == 1,
192 VALID_BREAKPOINT)
193
Greg Claytona6cffde2014-10-17 23:58:27 +0000194 listener = lldb.SBListener("my listener")
Johnny Chenf2df1892010-12-22 00:32:54 +0000195
Greg Claytona6cffde2014-10-17 23:58:27 +0000196 # Now launch the process, and do not stop at the entry point.
197 error = lldb.SBError()
198 process = target.Launch (listener,
199 None, # argv
200 None, # envp
201 None, # stdin_path
202 None, # stdout_path
203 None, # stderr_path
204 None, # working directory
205 0, # launch flags
206 False, # Stop at entry
207 error) # error
Johnny Chenf2df1892010-12-22 00:32:54 +0000208
209 # Create an empty event object.
210 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000211 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf2df1892010-12-22 00:32:54 +0000212
Johnny Chenf2df1892010-12-22 00:32:54 +0000213
214 # The finite state machine for our custom listening thread, with an
Bruce Mitchenere171da52015-07-22 00:16:02 +0000215 # initial state of None, which means no event has been received.
Siva Chandra8a1f7692015-05-08 00:43:28 +0000216 # It changes to 'connected' after 'connected' event is received (for remote platforms)
217 # It changes to 'running' after 'running' event is received (should happen only if the
218 # currentstate is either 'None' or 'connected')
219 # It changes to 'stopped' if a 'stopped' event is received (should happen only if the
220 # current state is 'running'.)
221 self.state = None
Johnny Chenf2df1892010-12-22 00:32:54 +0000222
223 # Create MyListeningThread to wait for state changed events.
224 # By design, a "running" event is expected following by a "stopped" event.
225 import threading
226 class MyListeningThread(threading.Thread):
227 def run(self):
228 #print "Running MyListeningThread:", self
229
230 # Regular expression pattern for the event description.
231 pattern = re.compile("data = {.*, state = (.*)}$")
232
233 # Let's only try at most 6 times to retrieve our events.
234 count = 0
235 while True:
Greg Claytona6cffde2014-10-17 23:58:27 +0000236 if listener.WaitForEvent(5, event):
Johnny Chen9ae98202011-04-23 00:34:56 +0000237 desc = lldbutil.get_description(event)
238 #print "Event description:", desc
239 match = pattern.search(desc)
Johnny Chenf2df1892010-12-22 00:32:54 +0000240 if not match:
241 break;
Siva Chandra8a1f7692015-05-08 00:43:28 +0000242 if match.group(1) == 'connected':
243 # When debugging remote targets with lldb-server, we
244 # first get the 'connected' event.
245 self.context.assertTrue(self.context.state == None)
246 self.context.state = 'connected'
Johnny Chenf2df1892010-12-22 00:32:54 +0000247 continue
Siva Chandra8a1f7692015-05-08 00:43:28 +0000248 elif match.group(1) == 'running':
249 self.context.assertTrue(self.context.state == None or self.context.state == 'connected')
250 self.context.state = 'running'
251 continue
252 elif match.group(1) == 'stopped':
253 self.context.assertTrue(self.context.state == 'running')
Johnny Chenf2df1892010-12-22 00:32:54 +0000254 # Whoopee, both events have been received!
Siva Chandra8a1f7692015-05-08 00:43:28 +0000255 self.context.state = 'stopped'
Johnny Chenf2df1892010-12-22 00:32:54 +0000256 break
257 else:
258 break
259 print "Timeout: listener.WaitForEvent"
260 count = count + 1
261 if count > 6:
262 break
263
264 return
265
266 # Use Python API to continue the process. The listening thread should be
267 # able to receive the state changed events.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000268 process.Continue()
Johnny Chenf2df1892010-12-22 00:32:54 +0000269
270 # Start the listening thread to receive the "running" followed by the
271 # "stopped" events.
272 my_thread = MyListeningThread()
273 # Supply the enclosing context so that our listening thread can access
274 # the 'state' variable.
275 my_thread.context = self
276 my_thread.start()
277
278 # Wait until the 'MyListeningThread' terminates.
279 my_thread.join()
280
Johnny Chenf2df1892010-12-22 00:32:54 +0000281 # The final judgement. :-)
Siva Chandra8a1f7692015-05-08 00:43:28 +0000282 self.assertTrue(self.state == 'stopped',
Johnny Chenf2df1892010-12-22 00:32:54 +0000283 "Both expected state changed events received")