blob: 7b21df16dd0573378732d2dac52aac187b6e8a05 [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 Chen3635eae2010-12-21 19:52:54 +000017 def test_wait_for_event_with_dsym(self):
Johnny Chenf2df1892010-12-22 00:32:54 +000018 """Exercise SBListener.WaitForEvent() API."""
Johnny Chenf667ab52010-12-21 02:06:56 +000019 self.buildDsym()
Johnny Chen3635eae2010-12-21 19:52:54 +000020 self.do_wait_for_event()
Johnny Chenf667ab52010-12-21 02:06:56 +000021
22 @python_api_test
Johnny Chen3635eae2010-12-21 19:52:54 +000023 def test_wait_for_event_with_dwarf(self):
Johnny Chenf2df1892010-12-22 00:32:54 +000024 """Exercise SBListener.WaitForEvent() API."""
Johnny Chenf667ab52010-12-21 02:06:56 +000025 self.buildDwarf()
Johnny Chen3635eae2010-12-21 19:52:54 +000026 self.do_wait_for_event()
Johnny Chenf667ab52010-12-21 02:06:56 +000027
Johnny Chenf2df1892010-12-22 00:32:54 +000028 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
29 @python_api_test
Johnny Chen77c46972010-12-22 00:56:47 +000030 def test_add_listener_to_broadcaster_dsym(self):
31 """Exercise some SBBroadcaster APIs."""
Johnny Chenf2df1892010-12-22 00:32:54 +000032 self.buildDsym()
Johnny Chen77c46972010-12-22 00:56:47 +000033 self.do_add_listener_to_broadcaster()
Johnny Chenf2df1892010-12-22 00:32:54 +000034
35 @python_api_test
Johnny Chen77c46972010-12-22 00:56:47 +000036 def test_add_listener_to_broadcaster_dwarf(self):
37 """Exercise some SBBroadcaster APIs."""
Johnny Chenf2df1892010-12-22 00:32:54 +000038 self.buildDwarf()
Johnny Chen77c46972010-12-22 00:56:47 +000039 self.do_add_listener_to_broadcaster()
Johnny Chenf2df1892010-12-22 00:32:54 +000040
Johnny Chenf667ab52010-12-21 02:06:56 +000041 def setUp(self):
42 # Call super's setUp().
43 TestBase.setUp(self)
44 # Find the line number to of function 'c'.
45 self.line = line_number('main.c', '// Find the line number of function "c" here.')
46
Johnny Chen3635eae2010-12-21 19:52:54 +000047 def do_wait_for_event(self):
48 """Get the listener associated with the debugger and exercise WaitForEvent API."""
Johnny Chenf667ab52010-12-21 02:06:56 +000049 exe = os.path.join(os.getcwd(), "a.out")
50
51 # Create a target by the debugger.
52 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +000053 self.assertTrue(target, VALID_TARGET)
Johnny Chenf667ab52010-12-21 02:06:56 +000054
55 # Now create a breakpoint on main.c by name 'c'.
56 breakpoint = target.BreakpointCreateByName('c', 'a.out')
57 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +000058 self.assertTrue(breakpoint and
Johnny Chenf667ab52010-12-21 02:06:56 +000059 breakpoint.GetNumLocations() == 1,
60 VALID_BREAKPOINT)
61
Johnny Chend762ff12011-02-03 23:15:53 +000062 # Get the debugger listener.
63 listener = self.dbg.GetListener()
64
Johnny Chenf667ab52010-12-21 02:06:56 +000065 # Now launch the process, and do not stop at entry point.
Greg Clayton6f907e62011-01-23 17:46:22 +000066 error = lldb.SBError()
Johnny Chend762ff12011-02-03 23:15:53 +000067 self.process = target.Launch (listener, None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error)
Johnny Chenf667ab52010-12-21 02:06:56 +000068
69 self.process = target.GetProcess()
Johnny Chen4ebd0192011-05-24 18:22:45 +000070 self.assertTrue(self.process, PROCESS_IS_VALID)
Johnny Chenf667ab52010-12-21 02:06:56 +000071
72 # Get a handle on the process's broadcaster.
73 broadcaster = self.process.GetBroadcaster()
Johnny Chen4ebd0192011-05-24 18:22:45 +000074 self.assertTrue(broadcaster, "Process with valid broadcaster")
Johnny Chenf667ab52010-12-21 02:06:56 +000075
76 # Create an empty event object.
77 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +000078 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf667ab52010-12-21 02:06:56 +000079
Johnny Chenf667ab52010-12-21 02:06:56 +000080 # Create MyListeningThread to wait for any kind of event.
81 import threading
82 class MyListeningThread(threading.Thread):
83 def run(self):
Johnny Chenf667ab52010-12-21 02:06:56 +000084 count = 0
85 # Let's only try at most 3 times to retrieve any kind of event.
86 while not count > 3:
87 if listener.WaitForEvent(5, event):
Johnny Chenf2df1892010-12-22 00:32:54 +000088 #print "Got a valid event:", event
Johnny Chenf667ab52010-12-21 02:06:56 +000089 return
90 count = count + 1
91 print "Timeout: listener.WaitForEvent"
92
93 return
94
Johnny Chen4f8caab2010-12-21 05:43:37 +000095 # Use Python API to kill the process. The listening thread should be
96 # able to receive a state changed event.
97 self.process.Kill()
98
Johnny Chenf2df1892010-12-22 00:32:54 +000099 # Let's start the listening thread to retrieve the event.
100 my_thread = MyListeningThread()
101 my_thread.start()
102
Johnny Chen4f8caab2010-12-21 05:43:37 +0000103 # Wait until the 'MyListeningThread' terminates.
Johnny Chenf667ab52010-12-21 02:06:56 +0000104 my_thread.join()
Johnny Chen4f8caab2010-12-21 05:43:37 +0000105
Johnny Chen4ebd0192011-05-24 18:22:45 +0000106 self.assertTrue(event,
Johnny Chenf2df1892010-12-22 00:32:54 +0000107 "My listening thread successfully received an event")
Johnny Chen4f8caab2010-12-21 05:43:37 +0000108
Johnny Chen77c46972010-12-22 00:56:47 +0000109 def do_add_listener_to_broadcaster(self):
110 """Get the broadcaster associated with the process and wait for broadcaster events."""
Johnny Chenf2df1892010-12-22 00:32:54 +0000111 exe = os.path.join(os.getcwd(), "a.out")
112
113 # Create a target by the debugger.
114 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000115 self.assertTrue(target, VALID_TARGET)
Johnny Chenf2df1892010-12-22 00:32:54 +0000116
117 # Now create a breakpoint on main.c by name 'c'.
118 breakpoint = target.BreakpointCreateByName('c', 'a.out')
119 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +0000120 self.assertTrue(breakpoint and
Johnny Chenf2df1892010-12-22 00:32:54 +0000121 breakpoint.GetNumLocations() == 1,
122 VALID_BREAKPOINT)
123
124 # Now launch the process, and do not stop at the entry point.
Johnny Chen272ae4d2011-04-19 19:25:37 +0000125 self.process = target.LaunchSimple(None, None, os.getcwd())
Johnny Chenf2df1892010-12-22 00:32:54 +0000126
127 self.process = target.GetProcess()
128 self.assertTrue(self.process.GetState() == lldb.eStateStopped,
129 PROCESS_STOPPED)
130
131 # Get a handle on the process's broadcaster.
132 broadcaster = self.process.GetBroadcaster()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000133 self.assertTrue(broadcaster, "Process with valid broadcaster")
Johnny Chenf2df1892010-12-22 00:32:54 +0000134
135 # Create an empty event object.
136 event = lldb.SBEvent()
Johnny Chen4ebd0192011-05-24 18:22:45 +0000137 self.assertFalse(event, "Event should not be valid initially")
Johnny Chenf2df1892010-12-22 00:32:54 +0000138
139 # Create a listener object and register with the broadcaster.
140 listener = lldb.SBListener("TestEvents.listener")
141 rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
142 self.assertTrue(rc, "AddListener successfully retruns")
143
144 # The finite state machine for our custom listening thread, with an
145 # initail state of 0, which means a "running" event is expected.
146 # It changes to 1 after "running" is received.
147 # It cahnges to 2 after "stopped" is received.
148 # 2 will be our final state and the test is complete.
149 self.state = 0
150
151 # Create MyListeningThread to wait for state changed events.
152 # By design, a "running" event is expected following by a "stopped" event.
153 import threading
154 class MyListeningThread(threading.Thread):
155 def run(self):
156 #print "Running MyListeningThread:", self
157
158 # Regular expression pattern for the event description.
159 pattern = re.compile("data = {.*, state = (.*)}$")
160
161 # Let's only try at most 6 times to retrieve our events.
162 count = 0
163 while True:
Johnny Chen77c46972010-12-22 00:56:47 +0000164 if listener.WaitForEventForBroadcasterWithType(5,
165 broadcaster,
166 lldb.SBProcess.eBroadcastBitStateChanged,
167 event):
Johnny Chen9ae98202011-04-23 00:34:56 +0000168 desc = lldbutil.get_description(event)
169 #print "Event description:", desc
170 match = pattern.search(desc)
Johnny Chenf2df1892010-12-22 00:32:54 +0000171 if not match:
172 break;
173 if self.context.state == 0 and match.group(1) == 'running':
174 self.context.state = 1
175 continue
176 elif self.context.state == 1 and match.group(1) == 'stopped':
177 # Whoopee, both events have been received!
178 self.context.state = 2
179 break
180 else:
181 break
182 print "Timeout: listener.WaitForEvent"
183 count = count + 1
184 if count > 6:
185 break
186
187 return
188
189 # Use Python API to continue the process. The listening thread should be
190 # able to receive the state changed events.
191 self.process.Continue()
192
193 # Start the listening thread to receive the "running" followed by the
194 # "stopped" events.
195 my_thread = MyListeningThread()
196 # Supply the enclosing context so that our listening thread can access
197 # the 'state' variable.
198 my_thread.context = self
199 my_thread.start()
200
201 # Wait until the 'MyListeningThread' terminates.
202 my_thread.join()
203
204 # We are no longer interested in receiving state changed events.
205 # Remove our custom listener before the inferior is killed.
206 broadcaster.RemoveListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
207
208 # The final judgement. :-)
209 self.assertTrue(self.state == 2,
210 "Both expected state changed events received")
Johnny Chenf667ab52010-12-21 02:06:56 +0000211
212
213if __name__ == '__main__':
214 import atexit
215 lldb.SBDebugger.Initialize()
216 atexit.register(lambda: lldb.SBDebugger.Terminate())
217 unittest2.main()