199451b44SJordan Rupprecht"""Test that we get thread names when interrupting a process.""" 299451b44SJordan Rupprecht 399451b44SJordan Rupprecht 499451b44SJordan Rupprechtimport time 599451b44SJordan Rupprechtimport lldb 699451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 799451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 899451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 999451b44SJordan Rupprecht 1099451b44SJordan Rupprecht 1199451b44SJordan Rupprechtclass TestInterruptThreadNames(TestBase): 1299451b44SJordan Rupprecht 1399451b44SJordan Rupprecht @skipUnlessDarwin 1499451b44SJordan Rupprecht @add_test_categories(['pyapi']) 1599451b44SJordan Rupprecht def test_with_python_api(self): 1699451b44SJordan Rupprecht """Test that we get thread names when interrupting a process.""" 1799451b44SJordan Rupprecht self.build() 1899451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 1999451b44SJordan Rupprecht 2099451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 2199451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 2299451b44SJordan Rupprecht 2386aa8e63SJonas Devlieghere launch_info = target.GetLaunchInfo() 2499451b44SJordan Rupprecht error = lldb.SBError() 2599451b44SJordan Rupprecht self.dbg.SetAsync(True) 2699451b44SJordan Rupprecht process = target.Launch(launch_info, error) 2799451b44SJordan Rupprecht self.assertTrue(process, PROCESS_IS_VALID) 2899451b44SJordan Rupprecht 2999451b44SJordan Rupprecht listener = self.dbg.GetListener() 3099451b44SJordan Rupprecht broadcaster = process.GetBroadcaster() 3199451b44SJordan Rupprecht rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged) 32b3a0c4d7SRaphael Isemann self.assertNotEqual(rc, 0, "Unable to add listener to process") 3399451b44SJordan Rupprecht self.assertTrue(self.wait_for_running(process, listener), "Check that process is up and running") 3499451b44SJordan Rupprecht 3599451b44SJordan Rupprecht inferior_set_up = self.wait_until_program_setup_complete(process, listener) 3699451b44SJordan Rupprecht 37b3a0c4d7SRaphael Isemann # Check that the program was able to create its threads within the allotted time 38b3a0c4d7SRaphael Isemann self.assertTrue(inferior_set_up.IsValid()) 39b3a0c4d7SRaphael Isemann self.assertEquals(inferior_set_up.GetValueAsSigned(), 1) 4099451b44SJordan Rupprecht 4199451b44SJordan Rupprecht self.check_number_of_threads(process) 4299451b44SJordan Rupprecht 4399451b44SJordan Rupprecht main_thread = lldb.SBThread() 4499451b44SJordan Rupprecht second_thread = lldb.SBThread() 4599451b44SJordan Rupprecht third_thread = lldb.SBThread() 4699451b44SJordan Rupprecht for idx in range(0, process.GetNumThreads()): 4799451b44SJordan Rupprecht t = process.GetThreadAtIndex(idx) 4899451b44SJordan Rupprecht if t.GetName() == "main thread": 4999451b44SJordan Rupprecht main_thread = t 5099451b44SJordan Rupprecht if t.GetName() == "second thread": 5199451b44SJordan Rupprecht second_thread = t 5299451b44SJordan Rupprecht if t.GetName() == "third thread": 5399451b44SJordan Rupprecht third_thread = t 5499451b44SJordan Rupprecht 5599451b44SJordan Rupprecht self.check_expected_threads_present(main_thread, second_thread, third_thread) 5699451b44SJordan Rupprecht 5799451b44SJordan Rupprecht process.Kill() 5899451b44SJordan Rupprecht 5999451b44SJordan Rupprecht 6099451b44SJordan Rupprecht # The process will set a global variable 'threads_up_and_running' to 1 when 6199451b44SJordan Rupprecht # it has has completed its setup. Sleep for one second, pause the program, 6299451b44SJordan Rupprecht # check to see if the global has that value, and continue if it does not. 6399451b44SJordan Rupprecht def wait_until_program_setup_complete(self, process, listener): 6499451b44SJordan Rupprecht inferior_set_up = lldb.SBValue() 6599451b44SJordan Rupprecht retry = 5 6699451b44SJordan Rupprecht while retry > 0: 6799451b44SJordan Rupprecht arch = self.getArchitecture() 6899451b44SJordan Rupprecht # when running the testsuite against a remote arm device, it may take 6999451b44SJordan Rupprecht # a little longer for the process to start up. Use a "can't possibly take 7099451b44SJordan Rupprecht # longer than this" value. 7199451b44SJordan Rupprecht if arch == 'arm64' or arch == 'armv7': 7299451b44SJordan Rupprecht time.sleep(10) 7399451b44SJordan Rupprecht else: 7499451b44SJordan Rupprecht time.sleep(1) 7599451b44SJordan Rupprecht process.SendAsyncInterrupt() 7699451b44SJordan Rupprecht self.assertTrue(self.wait_for_stop(process, listener), "Check that process is paused") 7799451b44SJordan Rupprecht inferior_set_up = process.GetTarget().CreateValueFromExpression("threads_up_and_running", "threads_up_and_running") 7899451b44SJordan Rupprecht if inferior_set_up.IsValid() and inferior_set_up.GetValueAsSigned() == 1: 7999451b44SJordan Rupprecht retry = 0 8099451b44SJordan Rupprecht else: 8199451b44SJordan Rupprecht process.Continue() 8299451b44SJordan Rupprecht retry = retry - 1 8399451b44SJordan Rupprecht return inferior_set_up 8499451b44SJordan Rupprecht 8599451b44SJordan Rupprecht # Listen to the process events until we get an event saying that the process is 8699451b44SJordan Rupprecht # running. Retry up to five times in case we get other events that are not 8799451b44SJordan Rupprecht # what we're looking for. 8899451b44SJordan Rupprecht def wait_for_running(self, process, listener): 8999451b44SJordan Rupprecht retry_count = 5 9099451b44SJordan Rupprecht if process.GetState() == lldb.eStateRunning: 9199451b44SJordan Rupprecht return True 9299451b44SJordan Rupprecht 9399451b44SJordan Rupprecht while retry_count > 0: 9499451b44SJordan Rupprecht event = lldb.SBEvent() 9599451b44SJordan Rupprecht listener.WaitForEvent(2, event) 9699451b44SJordan Rupprecht if event.GetType() == lldb.SBProcess.eBroadcastBitStateChanged: 9799451b44SJordan Rupprecht if process.GetState() == lldb.eStateRunning: 9899451b44SJordan Rupprecht return True 9999451b44SJordan Rupprecht retry_count = retry_count - 1 10099451b44SJordan Rupprecht 10199451b44SJordan Rupprecht return False 10299451b44SJordan Rupprecht 10399451b44SJordan Rupprecht # Listen to the process events until we get an event saying the process is 10499451b44SJordan Rupprecht # stopped. Retry up to five times in case we get other events that we are 10599451b44SJordan Rupprecht # not looking for. 10699451b44SJordan Rupprecht def wait_for_stop(self, process, listener): 10799451b44SJordan Rupprecht retry_count = 5 10899451b44SJordan Rupprecht if process.GetState() == lldb.eStateStopped or process.GetState() == lldb.eStateCrashed or process.GetState() == lldb.eStateDetached or process.GetState() == lldb.eStateExited: 10999451b44SJordan Rupprecht return True 11099451b44SJordan Rupprecht 11199451b44SJordan Rupprecht while retry_count > 0: 11299451b44SJordan Rupprecht event = lldb.SBEvent() 11399451b44SJordan Rupprecht listener.WaitForEvent(2, event) 11499451b44SJordan Rupprecht if event.GetType() == lldb.SBProcess.eBroadcastBitStateChanged: 11599451b44SJordan Rupprecht if process.GetState() == lldb.eStateStopped or process.GetState() == lldb.eStateCrashed or process.GetState() == lldb.eStateDetached or process.GetState() == lldb.eStateExited: 11699451b44SJordan Rupprecht return True 11799451b44SJordan Rupprecht if process.GetState() == lldb.eStateCrashed or process.GetState() == lldb.eStateDetached or process.GetState() == lldb.eStateExited: 11899451b44SJordan Rupprecht return False 11999451b44SJordan Rupprecht retry_count = retry_count - 1 12099451b44SJordan Rupprecht 12199451b44SJordan Rupprecht return False 12299451b44SJordan Rupprecht 12399451b44SJordan Rupprecht 12499451b44SJordan Rupprecht 12599451b44SJordan Rupprecht def check_number_of_threads(self, process): 126*0ed758b2SDave Lee self.assertEqual( 127*0ed758b2SDave Lee process.GetNumThreads(), 3, 12899451b44SJordan Rupprecht "Check that the process has three threads when sitting at the stopper() breakpoint") 12999451b44SJordan Rupprecht 13099451b44SJordan Rupprecht def check_expected_threads_present(self, main_thread, second_thread, third_thread): 13199451b44SJordan Rupprecht self.assertTrue( 13299451b44SJordan Rupprecht main_thread.IsValid() and second_thread.IsValid() and third_thread.IsValid(), 13399451b44SJordan Rupprecht "Got all three expected threads") 134