blob: f1243f29e325501e8f65a5af48ed000f91594e92 [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
13 mydir = os.path.join("python_api", "event")
14
15 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
16 @python_api_test
Johnny Chen3a709ac2011-07-08 23:02:33 +000017 def test_listen_for_and_print_event_with_dsym(self):
18 """Exercise SBEvent API."""
19 self.buildDsym()
20 self.do_listen_for_and_print_event()
21
22 @python_api_test
23 def test_listen_for_and_print_event_with_dwarf(self):
24 """Exercise SBEvent API."""
25 self.buildDwarf()
26 self.do_listen_for_and_print_event()
27
28 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
29 @python_api_test
Johnny Chen3635eae2010-12-21 19:52:54 +000030 def test_wait_for_event_with_dsym(self):
Johnny Chenf2df1892010-12-22 00:32:54 +000031 """Exercise SBListener.WaitForEvent() API."""
Johnny Chenf667ab52010-12-21 02:06:56 +000032 self.buildDsym()
Johnny Chen3635eae2010-12-21 19:52:54 +000033 self.do_wait_for_event()
Johnny Chenf667ab52010-12-21 02:06:56 +000034
35 @python_api_test
Johnny Chen3635eae2010-12-21 19:52:54 +000036 def test_wait_for_event_with_dwarf(self):
Johnny Chenf2df1892010-12-22 00:32:54 +000037 """Exercise SBListener.WaitForEvent() API."""
Johnny Chenf667ab52010-12-21 02:06:56 +000038 self.buildDwarf()
Johnny Chen3635eae2010-12-21 19:52:54 +000039 self.do_wait_for_event()
Johnny Chenf667ab52010-12-21 02:06:56 +000040
Johnny Chenf2df1892010-12-22 00:32:54 +000041 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
42 @python_api_test
Johnny Chen77c46972010-12-22 00:56:47 +000043 def test_add_listener_to_broadcaster_dsym(self):
44 """Exercise some SBBroadcaster APIs."""
Johnny Chenf2df1892010-12-22 00:32:54 +000045 self.buildDsym()
Johnny Chen77c46972010-12-22 00:56:47 +000046 self.do_add_listener_to_broadcaster()
Johnny Chenf2df1892010-12-22 00:32:54 +000047
48 @python_api_test
Johnny Chen77c46972010-12-22 00:56:47 +000049 def test_add_listener_to_broadcaster_dwarf(self):
50 """Exercise some SBBroadcaster APIs."""
Johnny Chenf2df1892010-12-22 00:32:54 +000051 self.buildDwarf()
Johnny Chen77c46972010-12-22 00:56:47 +000052 self.do_add_listener_to_broadcaster()
Johnny Chenf2df1892010-12-22 00:32:54 +000053
Johnny Chenf667ab52010-12-21 02:06:56 +000054 def setUp(self):
55 # Call super's setUp().
56 TestBase.setUp(self)
57 # Find the line number to of function 'c'.
58 self.line = line_number('main.c', '// Find the line number of function "c" here.')
59
Johnny Chen3a709ac2011-07-08 23:02:33 +000060 def do_listen_for_and_print_event(self):
61 """Create a listener and use SBEvent API to print the events received."""
62 exe = os.path.join(os.getcwd(), "a.out")
63
64 # Create a target by the debugger.
65 target = self.dbg.CreateTarget(exe)
66 self.assertTrue(target, VALID_TARGET)
67
68 # Now create a breakpoint on main.c by name 'c'.
69 breakpoint = target.BreakpointCreateByName('c', 'a.out')
70
71 # Now launch the process, and do not stop at the entry point.
72 process = target.LaunchSimple(None, None, os.getcwd())
73 self.assertTrue(process.GetState() == lldb.eStateStopped,
74 PROCESS_STOPPED)
75
76 # Get a handle on the process's broadcaster.
77 broadcaster = process.GetBroadcaster()
78
79 # Create an empty event object.
80 event = lldb.SBEvent()
81
82 # Create a listener object and register with the broadcaster.
83 listener = lldb.SBListener("my listener")
84 rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
85 self.assertTrue(rc, "AddListener successfully retruns")
86
87 traceOn = self.TraceOn()
88 if traceOn:
89 lldbutil.print_stacktraces(process)
90
91 # Create MyListeningThread class to wait for any kind of event.
92 import threading
93 class MyListeningThread(threading.Thread):
94 def run(self):
95 count = 0
96 # Let's only try at most 4 times to retrieve any kind of event.
97 # After that, the thread exits.
98 while not count > 3:
99 if traceOn:
100 print "Try wait for event..."
101 if listener.WaitForEventForBroadcasterWithType(5,
102 broadcaster,
103 lldb.SBProcess.eBroadcastBitStateChanged,
104 event):
105 if traceOn:
106 desc = lldbutil.get_description(event)
107 print "Event description:", desc
108 print "Event data flavor:", event.GetDataFlavor()
109 print "Process state:", lldbutil.state_type_to_str(process.GetState())
110 print
111 else:
112 if traceOn:
113 print "timeout occurred waiting for event..."
114 count = count + 1
115 return
116
117 # Let's start the listening thread to retrieve the events.
118 my_thread = MyListeningThread()
119 my_thread.start()
120
121 # Use Python API to continue the process. The listening thread should be
122 # able to receive the state changed events.
123 process.Continue()
124
125 # Use Python API to kill the process. The listening thread should be
126 # able to receive the state changed event, too.
127 process.Kill()
128
129 # Wait until the 'MyListeningThread' terminates.
130 my_thread.join()
131
Johnny Chen3635eae2010-12-21 19:52:54 +0000132 def do_wait_for_event(self):
133 """Get the listener associated with the debugger and exercise WaitForEvent API."""
Johnny Chenf667ab52010-12-21 02:06:56 +0000134 exe = os.path.join(os.getcwd(), "a.out")
135
136 # Create a target by the debugger.
137 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000138 self.assertTrue(target, VALID_TARGET)
Johnny Chenf667ab52010-12-21 02:06:56 +0000139
140 # Now create a breakpoint on main.c by name 'c'.
141 breakpoint = target.BreakpointCreateByName('c', 'a.out')
142 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000143 self.assertTrue(breakpoint and
Johnny Chenf667ab52010-12-21 02:06:56 +0000144 breakpoint.GetNumLocations() == 1,
145 VALID_BREAKPOINT)
146
Johnny Chend762ff12011-02-03 23:15:53 +0000147 # Get the debugger listener.
148 listener = self.dbg.GetListener()
149
Johnny Chenf667ab52010-12-21 02:06:56 +0000150 # Now launch the process, and do not stop at entry point.
Greg Clayton6f907e62011-01-23 17:46:22 +0000151 error = lldb.SBError()
Johnny Chen1d3e8802011-07-11 23:38:23 +0000152 process = target.Launch (listener, None, None, None, None, None, None, 0, False, error)
Johnny Chen2494f552011-07-20 00:14:20 +0000153 self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
Johnny Chenf667ab52010-12-21 02:06:56 +0000154
155 # Get a handle on the process's broadcaster.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000156 broadcaster = process.GetBroadcaster()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000157 self.assertTrue(broadcaster, "Process with valid broadcaster")
Johnny Chenf667ab52010-12-21 02:06:56 +0000158
159 # Create an empty event object.
160 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000161 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf667ab52010-12-21 02:06:56 +0000162
Johnny Chenf667ab52010-12-21 02:06:56 +0000163 # Create MyListeningThread to wait for any kind of event.
164 import threading
165 class MyListeningThread(threading.Thread):
166 def run(self):
Johnny Chenf667ab52010-12-21 02:06:56 +0000167 count = 0
168 # Let's only try at most 3 times to retrieve any kind of event.
169 while not count > 3:
170 if listener.WaitForEvent(5, event):
Johnny Chenf2df1892010-12-22 00:32:54 +0000171 #print "Got a valid event:", event
Johnny Chen3a709ac2011-07-08 23:02:33 +0000172 #print "Event data flavor:", event.GetDataFlavor()
173 #print "Event type:", lldbutil.state_type_to_str(event.GetType())
Johnny Chenf667ab52010-12-21 02:06:56 +0000174 return
175 count = count + 1
176 print "Timeout: listener.WaitForEvent"
177
178 return
179
Johnny Chen4f8caab2010-12-21 05:43:37 +0000180 # Use Python API to kill the process. The listening thread should be
181 # able to receive a state changed event.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000182 process.Kill()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000183
Johnny Chenf2df1892010-12-22 00:32:54 +0000184 # Let's start the listening thread to retrieve the event.
185 my_thread = MyListeningThread()
186 my_thread.start()
187
Johnny Chen4f8caab2010-12-21 05:43:37 +0000188 # Wait until the 'MyListeningThread' terminates.
Johnny Chenf667ab52010-12-21 02:06:56 +0000189 my_thread.join()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000190
Johnny Chen4ebd0192011-05-24 18:22:45 +0000191 self.assertTrue(event,
Johnny Chenf2df1892010-12-22 00:32:54 +0000192 "My listening thread successfully received an event")
Johnny Chen4f8caab2010-12-21 05:43:37 +0000193
Johnny Chen77c46972010-12-22 00:56:47 +0000194 def do_add_listener_to_broadcaster(self):
195 """Get the broadcaster associated with the process and wait for broadcaster events."""
Johnny Chenf2df1892010-12-22 00:32:54 +0000196 exe = os.path.join(os.getcwd(), "a.out")
197
198 # Create a target by the debugger.
199 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000200 self.assertTrue(target, VALID_TARGET)
Johnny Chenf2df1892010-12-22 00:32:54 +0000201
202 # Now create a breakpoint on main.c by name 'c'.
203 breakpoint = target.BreakpointCreateByName('c', 'a.out')
204 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000205 self.assertTrue(breakpoint and
Johnny Chenf2df1892010-12-22 00:32:54 +0000206 breakpoint.GetNumLocations() == 1,
207 VALID_BREAKPOINT)
208
209 # Now launch the process, and do not stop at the entry point.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000210 process = target.LaunchSimple(None, None, os.getcwd())
211 self.assertTrue(process.GetState() == lldb.eStateStopped,
Johnny Chenf2df1892010-12-22 00:32:54 +0000212 PROCESS_STOPPED)
213
214 # Get a handle on the process's broadcaster.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000215 broadcaster = process.GetBroadcaster()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000216 self.assertTrue(broadcaster, "Process with valid broadcaster")
Johnny Chenf2df1892010-12-22 00:32:54 +0000217
218 # Create an empty event object.
219 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000220 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf2df1892010-12-22 00:32:54 +0000221
222 # Create a listener object and register with the broadcaster.
223 listener = lldb.SBListener("TestEvents.listener")
224 rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
225 self.assertTrue(rc, "AddListener successfully retruns")
226
227 # The finite state machine for our custom listening thread, with an
228 # initail state of 0, which means a "running" event is expected.
229 # It changes to 1 after "running" is received.
230 # It cahnges to 2 after "stopped" is received.
231 # 2 will be our final state and the test is complete.
232 self.state = 0
233
234 # Create MyListeningThread to wait for state changed events.
235 # By design, a "running" event is expected following by a "stopped" event.
236 import threading
237 class MyListeningThread(threading.Thread):
238 def run(self):
239 #print "Running MyListeningThread:", self
240
241 # Regular expression pattern for the event description.
242 pattern = re.compile("data = {.*, state = (.*)}$")
243
244 # Let's only try at most 6 times to retrieve our events.
245 count = 0
246 while True:
Johnny Chen77c46972010-12-22 00:56:47 +0000247 if listener.WaitForEventForBroadcasterWithType(5,
248 broadcaster,
249 lldb.SBProcess.eBroadcastBitStateChanged,
250 event):
Johnny Chen9ae98202011-04-23 00:34:56 +0000251 desc = lldbutil.get_description(event)
252 #print "Event description:", desc
253 match = pattern.search(desc)
Johnny Chenf2df1892010-12-22 00:32:54 +0000254 if not match:
255 break;
256 if self.context.state == 0 and match.group(1) == 'running':
257 self.context.state = 1
258 continue
259 elif self.context.state == 1 and match.group(1) == 'stopped':
260 # Whoopee, both events have been received!
261 self.context.state = 2
262 break
263 else:
264 break
265 print "Timeout: listener.WaitForEvent"
266 count = count + 1
267 if count > 6:
268 break
269
270 return
271
272 # Use Python API to continue the process. The listening thread should be
273 # able to receive the state changed events.
Johnny Chen5a0bee72011-06-15 22:14:12 +0000274 process.Continue()
Johnny Chenf2df1892010-12-22 00:32:54 +0000275
276 # Start the listening thread to receive the "running" followed by the
277 # "stopped" events.
278 my_thread = MyListeningThread()
279 # Supply the enclosing context so that our listening thread can access
280 # the 'state' variable.
281 my_thread.context = self
282 my_thread.start()
283
284 # Wait until the 'MyListeningThread' terminates.
285 my_thread.join()
286
287 # We are no longer interested in receiving state changed events.
288 # Remove our custom listener before the inferior is killed.
289 broadcaster.RemoveListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
290
291 # The final judgement. :-)
292 self.assertTrue(self.state == 2,
293 "Both expected state changed events received")
Johnny Chenf667ab52010-12-21 02:06:56 +0000294
295
296if __name__ == '__main__':
297 import atexit
298 lldb.SBDebugger.Initialize()
299 atexit.register(lambda: lldb.SBDebugger.Terminate())
300 unittest2.main()