[PowerPC] Collect some CallLowering arguments into a struct. [NFC]
[llvm-project.git] / lldb / packages / Python / lldbsuite / test / macosx / queues / TestQueues.py
blob805ad21a41375e0043f2f633d5385c7e7abb4248
1 """Test queues inspection SB APIs."""
3 from __future__ import print_function
6 import unittest2
7 import os
8 import lldb
9 from lldbsuite.test.decorators import *
10 from lldbsuite.test.lldbtest import *
11 from lldbsuite.test import lldbutil
14 class TestQueues(TestBase):
16 mydir = TestBase.compute_mydir(__file__)
18 @skipUnlessDarwin
19 @add_test_categories(['pyapi'])
20 def test_with_python_api_queues(self):
21 """Test queues inspection SB APIs."""
22 self.build()
23 self.queues()
25 @skipUnlessDarwin
26 @add_test_categories(['pyapi'])
27 def test_with_python_api_queues_with_backtrace(self):
28 """Test queues inspection SB APIs."""
29 self.build()
30 self.queues_with_libBacktraceRecording()
32 def setUp(self):
33 # Call super's setUp().
34 TestBase.setUp(self)
35 # Find the line numbers that we will step to in main:
36 self.main_source = "main.c"
38 def check_queue_for_valid_queue_id(self, queue):
39 self.assertTrue(
40 queue.GetQueueID() != 0, "Check queue %s for valid QueueID (got 0x%x)" %
41 (queue.GetName(), queue.GetQueueID()))
43 def check_running_and_pending_items_on_queue(
44 self, queue, expected_running, expected_pending):
45 self.assertTrue(
46 queue.GetNumPendingItems() == expected_pending,
47 "queue %s should have %d pending items, instead has %d pending items" %
48 (queue.GetName(),
49 expected_pending,
50 (queue.GetNumPendingItems())))
51 self.assertTrue(
52 queue.GetNumRunningItems() == expected_running,
53 "queue %s should have %d running items, instead has %d running items" %
54 (queue.GetName(),
55 expected_running,
56 (queue.GetNumRunningItems())))
58 def describe_threads(self):
59 desc = []
60 for x in self.inferior_process:
61 id = x.GetIndexID()
62 reason_str = lldbutil.stop_reason_to_str(x.GetStopReason())
64 location = "\t".join([lldbutil.get_description(
65 x.GetFrameAtIndex(i)) for i in range(x.GetNumFrames())])
66 desc.append(
67 "thread %d: %s (queue id: %s) at\n\t%s" %
68 (id, reason_str, x.GetQueueID(), location))
69 print('\n'.join(desc))
71 def check_number_of_threads_owned_by_queue(self, queue, number_threads):
72 if (queue.GetNumThreads() != number_threads):
73 self.describe_threads()
75 self.assertTrue(
76 queue.GetNumThreads() == number_threads,
77 "queue %s should have %d thread executing, but has %d" %
78 (queue.GetName(),
79 number_threads,
80 queue.GetNumThreads()))
82 def check_queue_kind(self, queue, kind):
83 expected_kind_string = "Unknown"
84 if kind == lldb.eQueueKindSerial:
85 expected_kind_string = "Serial queue"
86 if kind == lldb.eQueueKindConcurrent:
87 expected_kind_string = "Concurrent queue"
88 actual_kind_string = "Unknown"
89 if queue.GetKind() == lldb.eQueueKindSerial:
90 actual_kind_string = "Serial queue"
91 if queue.GetKind() == lldb.eQueueKindConcurrent:
92 actual_kind_string = "Concurrent queue"
93 self.assertTrue(
94 queue.GetKind() == kind,
95 "queue %s is expected to be a %s but it is actually a %s" %
96 (queue.GetName(),
97 expected_kind_string,
98 actual_kind_string))
100 def check_queues_threads_match_queue(self, queue):
101 for idx in range(0, queue.GetNumThreads()):
102 t = queue.GetThreadAtIndex(idx)
103 self.assertTrue(
104 t.IsValid(), "Queue %s's thread #%d must be valid" %
105 (queue.GetName(), idx))
106 self.assertTrue(
107 t.GetQueueID() == queue.GetQueueID(),
108 "Queue %s has a QueueID of %d but its thread #%d has a QueueID of %d" %
109 (queue.GetName(),
110 queue.GetQueueID(),
111 idx,
112 t.GetQueueID()))
113 self.assertTrue(
114 t.GetQueueName() == queue.GetName(),
115 "Queue %s has a QueueName of %s but its thread #%d has a QueueName of %s" %
116 (queue.GetName(),
117 queue.GetName(),
118 idx,
119 t.GetQueueName()))
120 self.assertTrue(
121 t.GetQueue().GetQueueID() == queue.GetQueueID(),
122 "Thread #%d's Queue's QueueID of %d is not the same as the QueueID of its owning queue %d" %
123 (idx,
124 t.GetQueue().GetQueueID(),
125 queue.GetQueueID()))
127 def queues(self):
128 """Test queues inspection SB APIs without libBacktraceRecording."""
129 exe = self.getBuildArtifact("a.out")
131 target = self.dbg.CreateTarget(exe)
132 self.assertTrue(target, VALID_TARGET)
133 self.main_source_spec = lldb.SBFileSpec(self.main_source)
134 break1 = target.BreakpointCreateByName("stopper", 'a.out')
135 self.assertTrue(break1, VALID_BREAKPOINT)
136 process = target.LaunchSimple(
137 [], None, self.get_process_working_directory())
138 self.assertTrue(process, PROCESS_IS_VALID)
139 threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1)
140 if len(threads) != 1:
141 self.fail("Failed to stop at breakpoint 1.")
143 self.inferior_process = process
145 queue_submittor_1 = lldb.SBQueue()
146 queue_performer_1 = lldb.SBQueue()
147 queue_performer_2 = lldb.SBQueue()
148 queue_performer_3 = lldb.SBQueue()
149 for idx in range(0, process.GetNumQueues()):
150 q = process.GetQueueAtIndex(idx)
151 if q.GetName() == "com.apple.work_submittor_1":
152 queue_submittor_1 = q
153 if q.GetName() == "com.apple.work_performer_1":
154 queue_performer_1 = q
155 if q.GetName() == "com.apple.work_performer_2":
156 queue_performer_2 = q
157 if q.GetName() == "com.apple.work_performer_3":
158 queue_performer_3 = q
160 self.assertTrue(
161 queue_submittor_1.IsValid() and queue_performer_1.IsValid() and queue_performer_2.IsValid() and queue_performer_3.IsValid(),
162 "Got all four expected queues: %s %s %s %s" %
163 (queue_submittor_1.IsValid(),
164 queue_performer_1.IsValid(),
165 queue_performer_2.IsValid(),
166 queue_performer_3.IsValid()))
168 self.check_queue_for_valid_queue_id(queue_submittor_1)
169 self.check_queue_for_valid_queue_id(queue_performer_1)
170 self.check_queue_for_valid_queue_id(queue_performer_2)
171 self.check_queue_for_valid_queue_id(queue_performer_3)
173 self.check_number_of_threads_owned_by_queue(queue_submittor_1, 1)
174 self.check_number_of_threads_owned_by_queue(queue_performer_1, 1)
175 self.check_number_of_threads_owned_by_queue(queue_performer_2, 1)
176 self.check_number_of_threads_owned_by_queue(queue_performer_3, 4)
178 self.check_queue_kind(queue_submittor_1, lldb.eQueueKindSerial)
179 self.check_queue_kind(queue_performer_1, lldb.eQueueKindSerial)
180 self.check_queue_kind(queue_performer_2, lldb.eQueueKindSerial)
181 self.check_queue_kind(queue_performer_3, lldb.eQueueKindConcurrent)
183 self.check_queues_threads_match_queue(queue_submittor_1)
184 self.check_queues_threads_match_queue(queue_performer_1)
185 self.check_queues_threads_match_queue(queue_performer_2)
186 self.check_queues_threads_match_queue(queue_performer_3)
188 # We have threads running with all the different dispatch QoS service
189 # levels - find those threads and check that we can get the correct
190 # QoS name for each of them.
192 user_initiated_thread = lldb.SBThread()
193 user_interactive_thread = lldb.SBThread()
194 utility_thread = lldb.SBThread()
195 unspecified_thread = lldb.SBThread()
196 background_thread = lldb.SBThread()
197 for th in process.threads:
198 if th.GetName() == "user initiated QoS":
199 user_initiated_thread = th
200 if th.GetName() == "user interactive QoS":
201 user_interactive_thread = th
202 if th.GetName() == "utility QoS":
203 utility_thread = th
204 if th.GetName() == "unspecified QoS":
205 unspecified_thread = th
206 if th.GetName() == "background QoS":
207 background_thread = th
209 self.assertTrue(
210 user_initiated_thread.IsValid(),
211 "Found user initiated QoS thread")
212 self.assertTrue(
213 user_interactive_thread.IsValid(),
214 "Found user interactive QoS thread")
215 self.assertTrue(utility_thread.IsValid(), "Found utility QoS thread")
216 self.assertTrue(
217 unspecified_thread.IsValid(),
218 "Found unspecified QoS thread")
219 self.assertTrue(
220 background_thread.IsValid(),
221 "Found background QoS thread")
223 stream = lldb.SBStream()
224 self.assertTrue(
225 user_initiated_thread.GetInfoItemByPathAsString(
226 "requested_qos.printable_name",
227 stream),
228 "Get QoS printable string for user initiated QoS thread")
229 self.assertTrue(
230 stream.GetData() == "User Initiated",
231 "user initiated QoS thread name is valid")
232 stream.Clear()
233 self.assertTrue(
234 user_interactive_thread.GetInfoItemByPathAsString(
235 "requested_qos.printable_name",
236 stream),
237 "Get QoS printable string for user interactive QoS thread")
238 self.assertTrue(
239 stream.GetData() == "User Interactive",
240 "user interactive QoS thread name is valid")
241 stream.Clear()
242 self.assertTrue(
243 utility_thread.GetInfoItemByPathAsString(
244 "requested_qos.printable_name",
245 stream),
246 "Get QoS printable string for utility QoS thread")
247 self.assertTrue(
248 stream.GetData() == "Utility",
249 "utility QoS thread name is valid")
250 stream.Clear()
251 self.assertTrue(
252 unspecified_thread.GetInfoItemByPathAsString(
253 "requested_qos.printable_name",
254 stream),
255 "Get QoS printable string for unspecified QoS thread")
256 qosName = stream.GetData()
257 self.assertTrue(
258 qosName == "User Initiated" or qosName == "Default",
259 "unspecified QoS thread name is valid")
260 stream.Clear()
261 self.assertTrue(
262 background_thread.GetInfoItemByPathAsString(
263 "requested_qos.printable_name",
264 stream),
265 "Get QoS printable string for background QoS thread")
266 self.assertTrue(
267 stream.GetData() == "Background",
268 "background QoS thread name is valid")
270 @skipIfDarwin # rdar://50379398
271 def queues_with_libBacktraceRecording(self):
272 """Test queues inspection SB APIs with libBacktraceRecording present."""
273 exe = self.getBuildArtifact("a.out")
275 if not os.path.isfile(
276 '/Applications/Xcode.app/Contents/Developer/usr/lib/libBacktraceRecording.dylib'):
277 self.skipTest(
278 "Skipped because libBacktraceRecording.dylib was present on the system.")
280 if not os.path.isfile(
281 '/usr/lib/system/introspection/libdispatch.dylib'):
282 self.skipTest(
283 "Skipped because introspection libdispatch dylib is not present.")
285 target = self.dbg.CreateTarget(exe)
286 self.assertTrue(target, VALID_TARGET)
288 self.main_source_spec = lldb.SBFileSpec(self.main_source)
290 break1 = target.BreakpointCreateByName("stopper", 'a.out')
291 self.assertTrue(break1, VALID_BREAKPOINT)
293 # Now launch the process, and do not stop at entry point.
294 libbtr_path = "/Applications/Xcode.app/Contents/Developer/usr/lib/libBacktraceRecording.dylib"
295 if self.getArchitecture() in ['arm', 'arm64', 'arm64e', 'arm64_32', 'armv7', 'armv7k']:
296 libbtr_path = "/Developer/usr/lib/libBacktraceRecording.dylib"
298 process = target.LaunchSimple(
301 'DYLD_INSERT_LIBRARIES=%s' % (libbtr_path),
302 'DYLD_LIBRARY_PATH=/usr/lib/system/introspection'],
303 self.get_process_working_directory())
305 self.assertTrue(process, PROCESS_IS_VALID)
307 # The stop reason of the thread should be breakpoint.
308 threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1)
309 if len(threads) != 1:
310 self.fail("Failed to stop at breakpoint 1.")
312 self.inferior_process = process
314 libbtr_module_filespec = lldb.SBFileSpec("libBacktraceRecording.dylib")
315 libbtr_module = target.FindModule(libbtr_module_filespec)
316 if not libbtr_module.IsValid():
317 self.skipTest(
318 "Skipped because libBacktraceRecording.dylib was not loaded into the process.")
320 self.assertTrue(
321 process.GetNumQueues() >= 4,
322 "Found the correct number of queues.")
324 queue_submittor_1 = lldb.SBQueue()
325 queue_performer_1 = lldb.SBQueue()
326 queue_performer_2 = lldb.SBQueue()
327 queue_performer_3 = lldb.SBQueue()
328 for idx in range(0, process.GetNumQueues()):
329 q = process.GetQueueAtIndex(idx)
330 if "LLDB_COMMAND_TRACE" in os.environ:
331 print("Queue with id %s has name %s" % (q.GetQueueID(), q.GetName()))
332 if q.GetName() == "com.apple.work_submittor_1":
333 queue_submittor_1 = q
334 if q.GetName() == "com.apple.work_performer_1":
335 queue_performer_1 = q
336 if q.GetName() == "com.apple.work_performer_2":
337 queue_performer_2 = q
338 if q.GetName() == "com.apple.work_performer_3":
339 queue_performer_3 = q
340 if q.GetName() == "com.apple.main-thread":
341 if q.GetNumThreads() == 0:
342 print("Cannot get thread <=> queue associations")
343 return
345 self.assertTrue(
346 queue_submittor_1.IsValid() and queue_performer_1.IsValid() and queue_performer_2.IsValid() and queue_performer_3.IsValid(),
347 "Got all four expected queues: %s %s %s %s" %
348 (queue_submittor_1.IsValid(),
349 queue_performer_1.IsValid(),
350 queue_performer_2.IsValid(),
351 queue_performer_3.IsValid()))
353 self.check_queue_for_valid_queue_id(queue_submittor_1)
354 self.check_queue_for_valid_queue_id(queue_performer_1)
355 self.check_queue_for_valid_queue_id(queue_performer_2)
356 self.check_queue_for_valid_queue_id(queue_performer_3)
358 self.check_running_and_pending_items_on_queue(queue_submittor_1, 1, 0)
359 self.check_running_and_pending_items_on_queue(queue_performer_1, 1, 3)
360 self.check_running_and_pending_items_on_queue(
361 queue_performer_2, 1, 9999)
362 self.check_running_and_pending_items_on_queue(queue_performer_3, 4, 0)
364 self.check_number_of_threads_owned_by_queue(queue_submittor_1, 1)
365 self.check_number_of_threads_owned_by_queue(queue_performer_1, 1)
366 self.check_number_of_threads_owned_by_queue(queue_performer_2, 1)
367 self.check_number_of_threads_owned_by_queue(queue_performer_3, 4)
369 self.check_queue_kind(queue_submittor_1, lldb.eQueueKindSerial)
370 self.check_queue_kind(queue_performer_1, lldb.eQueueKindSerial)
371 self.check_queue_kind(queue_performer_2, lldb.eQueueKindSerial)
372 self.check_queue_kind(queue_performer_3, lldb.eQueueKindConcurrent)
374 self.check_queues_threads_match_queue(queue_submittor_1)
375 self.check_queues_threads_match_queue(queue_performer_1)
376 self.check_queues_threads_match_queue(queue_performer_2)
377 self.check_queues_threads_match_queue(queue_performer_3)
379 self.assertTrue(queue_performer_2.GetPendingItemAtIndex(
380 0).IsValid(), "queue 2's pending item #0 is valid")
381 self.assertTrue(queue_performer_2.GetPendingItemAtIndex(0).GetAddress().GetSymbol(
382 ).GetName() == "doing_the_work_2", "queue 2's pending item #0 should be doing_the_work_2")
383 self.assertTrue(
384 queue_performer_2.GetNumPendingItems() == 9999,
385 "verify that queue 2 still has 9999 pending items")
386 self.assertTrue(queue_performer_2.GetPendingItemAtIndex(
387 9998).IsValid(), "queue 2's pending item #9998 is valid")
388 self.assertTrue(queue_performer_2.GetPendingItemAtIndex(9998).GetAddress().GetSymbol(
389 ).GetName() == "doing_the_work_2", "queue 2's pending item #0 should be doing_the_work_2")
390 self.assertTrue(queue_performer_2.GetPendingItemAtIndex(
391 9999).IsValid() == False, "queue 2's pending item #9999 is invalid")