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 @skipUnlessDarwin 132238dcc3SJonas Devlieghere @add_test_categories(["pyapi"]) 1499451b44SJordan Rupprecht def test_with_python_api(self): 1599451b44SJordan Rupprecht """Test that we get thread names when interrupting a process.""" 1699451b44SJordan Rupprecht self.build() 1799451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 1899451b44SJordan Rupprecht 1999451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 2099451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 2199451b44SJordan Rupprecht 2286aa8e63SJonas Devlieghere launch_info = target.GetLaunchInfo() 2399451b44SJordan Rupprecht error = lldb.SBError() 2499451b44SJordan Rupprecht self.dbg.SetAsync(True) 2599451b44SJordan Rupprecht process = target.Launch(launch_info, error) 2699451b44SJordan Rupprecht self.assertTrue(process, PROCESS_IS_VALID) 2799451b44SJordan Rupprecht 2899451b44SJordan Rupprecht listener = self.dbg.GetListener() 2999451b44SJordan Rupprecht broadcaster = process.GetBroadcaster() 3099451b44SJordan Rupprecht rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged) 31b3a0c4d7SRaphael Isemann self.assertNotEqual(rc, 0, "Unable to add listener to process") 322238dcc3SJonas Devlieghere self.assertTrue( 332238dcc3SJonas Devlieghere self.wait_for_running(process, listener), 342238dcc3SJonas Devlieghere "Check that process is up and running", 352238dcc3SJonas Devlieghere ) 3699451b44SJordan Rupprecht 3799451b44SJordan Rupprecht inferior_set_up = self.wait_until_program_setup_complete(process, listener) 3899451b44SJordan Rupprecht 39b3a0c4d7SRaphael Isemann # Check that the program was able to create its threads within the allotted time 40b3a0c4d7SRaphael Isemann self.assertTrue(inferior_set_up.IsValid()) 41*80fcecb1SJonas Devlieghere self.assertEqual(inferior_set_up.GetValueAsSigned(), 1) 4299451b44SJordan Rupprecht 4399451b44SJordan Rupprecht self.check_number_of_threads(process) 4499451b44SJordan Rupprecht 4599451b44SJordan Rupprecht main_thread = lldb.SBThread() 4699451b44SJordan Rupprecht second_thread = lldb.SBThread() 4799451b44SJordan Rupprecht third_thread = lldb.SBThread() 4899451b44SJordan Rupprecht for idx in range(0, process.GetNumThreads()): 4999451b44SJordan Rupprecht t = process.GetThreadAtIndex(idx) 5099451b44SJordan Rupprecht if t.GetName() == "main thread": 5199451b44SJordan Rupprecht main_thread = t 5299451b44SJordan Rupprecht if t.GetName() == "second thread": 5399451b44SJordan Rupprecht second_thread = t 5499451b44SJordan Rupprecht if t.GetName() == "third thread": 5599451b44SJordan Rupprecht third_thread = t 5699451b44SJordan Rupprecht 5799451b44SJordan Rupprecht self.check_expected_threads_present(main_thread, second_thread, third_thread) 5899451b44SJordan Rupprecht 5999451b44SJordan Rupprecht process.Kill() 6099451b44SJordan Rupprecht 6199451b44SJordan Rupprecht # The process will set a global variable 'threads_up_and_running' to 1 when 6299451b44SJordan Rupprecht # it has has completed its setup. Sleep for one second, pause the program, 6399451b44SJordan Rupprecht # check to see if the global has that value, and continue if it does not. 6499451b44SJordan Rupprecht def wait_until_program_setup_complete(self, process, listener): 6599451b44SJordan Rupprecht inferior_set_up = lldb.SBValue() 6699451b44SJordan Rupprecht retry = 5 6799451b44SJordan Rupprecht while retry > 0: 6899451b44SJordan Rupprecht arch = self.getArchitecture() 6999451b44SJordan Rupprecht # when running the testsuite against a remote arm device, it may take 7099451b44SJordan Rupprecht # a little longer for the process to start up. Use a "can't possibly take 7199451b44SJordan Rupprecht # longer than this" value. 722238dcc3SJonas Devlieghere if arch == "arm64" or arch == "armv7": 7399451b44SJordan Rupprecht time.sleep(10) 7499451b44SJordan Rupprecht else: 7599451b44SJordan Rupprecht time.sleep(1) 7699451b44SJordan Rupprecht process.SendAsyncInterrupt() 772238dcc3SJonas Devlieghere self.assertTrue( 782238dcc3SJonas Devlieghere self.wait_for_stop(process, listener), "Check that process is paused" 792238dcc3SJonas Devlieghere ) 802238dcc3SJonas Devlieghere inferior_set_up = process.GetTarget().CreateValueFromExpression( 812238dcc3SJonas Devlieghere "threads_up_and_running", "threads_up_and_running" 822238dcc3SJonas Devlieghere ) 8399451b44SJordan Rupprecht if inferior_set_up.IsValid() and inferior_set_up.GetValueAsSigned() == 1: 8499451b44SJordan Rupprecht retry = 0 8599451b44SJordan Rupprecht else: 8699451b44SJordan Rupprecht process.Continue() 8799451b44SJordan Rupprecht retry = retry - 1 8899451b44SJordan Rupprecht return inferior_set_up 8999451b44SJordan Rupprecht 9099451b44SJordan Rupprecht # Listen to the process events until we get an event saying that the process is 9199451b44SJordan Rupprecht # running. Retry up to five times in case we get other events that are not 9299451b44SJordan Rupprecht # what we're looking for. 9399451b44SJordan Rupprecht def wait_for_running(self, process, listener): 9499451b44SJordan Rupprecht retry_count = 5 9599451b44SJordan Rupprecht if process.GetState() == lldb.eStateRunning: 9699451b44SJordan Rupprecht return True 9799451b44SJordan Rupprecht 9899451b44SJordan Rupprecht while retry_count > 0: 9999451b44SJordan Rupprecht event = lldb.SBEvent() 10099451b44SJordan Rupprecht listener.WaitForEvent(2, event) 10199451b44SJordan Rupprecht if event.GetType() == lldb.SBProcess.eBroadcastBitStateChanged: 10299451b44SJordan Rupprecht if process.GetState() == lldb.eStateRunning: 10399451b44SJordan Rupprecht return True 10499451b44SJordan Rupprecht retry_count = retry_count - 1 10599451b44SJordan Rupprecht 10699451b44SJordan Rupprecht return False 10799451b44SJordan Rupprecht 10899451b44SJordan Rupprecht # Listen to the process events until we get an event saying the process is 10999451b44SJordan Rupprecht # stopped. Retry up to five times in case we get other events that we are 11099451b44SJordan Rupprecht # not looking for. 11199451b44SJordan Rupprecht def wait_for_stop(self, process, listener): 11299451b44SJordan Rupprecht retry_count = 5 1132238dcc3SJonas Devlieghere if ( 1142238dcc3SJonas Devlieghere process.GetState() == lldb.eStateStopped 1152238dcc3SJonas Devlieghere or process.GetState() == lldb.eStateCrashed 1162238dcc3SJonas Devlieghere or process.GetState() == lldb.eStateDetached 1172238dcc3SJonas Devlieghere or process.GetState() == lldb.eStateExited 1182238dcc3SJonas Devlieghere ): 11999451b44SJordan Rupprecht return True 12099451b44SJordan Rupprecht 12199451b44SJordan Rupprecht while retry_count > 0: 12299451b44SJordan Rupprecht event = lldb.SBEvent() 12399451b44SJordan Rupprecht listener.WaitForEvent(2, event) 12499451b44SJordan Rupprecht if event.GetType() == lldb.SBProcess.eBroadcastBitStateChanged: 1252238dcc3SJonas Devlieghere if ( 1262238dcc3SJonas Devlieghere process.GetState() == lldb.eStateStopped 1272238dcc3SJonas Devlieghere or process.GetState() == lldb.eStateCrashed 1282238dcc3SJonas Devlieghere or process.GetState() == lldb.eStateDetached 1292238dcc3SJonas Devlieghere or process.GetState() == lldb.eStateExited 1302238dcc3SJonas Devlieghere ): 13199451b44SJordan Rupprecht return True 1322238dcc3SJonas Devlieghere if ( 1332238dcc3SJonas Devlieghere process.GetState() == lldb.eStateCrashed 1342238dcc3SJonas Devlieghere or process.GetState() == lldb.eStateDetached 1352238dcc3SJonas Devlieghere or process.GetState() == lldb.eStateExited 1362238dcc3SJonas Devlieghere ): 13799451b44SJordan Rupprecht return False 13899451b44SJordan Rupprecht retry_count = retry_count - 1 13999451b44SJordan Rupprecht 14099451b44SJordan Rupprecht return False 14199451b44SJordan Rupprecht 14299451b44SJordan Rupprecht def check_number_of_threads(self, process): 1430ed758b2SDave Lee self.assertEqual( 1442238dcc3SJonas Devlieghere process.GetNumThreads(), 1452238dcc3SJonas Devlieghere 3, 1462238dcc3SJonas Devlieghere "Check that the process has three threads when sitting at the stopper() breakpoint", 1472238dcc3SJonas Devlieghere ) 14899451b44SJordan Rupprecht 14999451b44SJordan Rupprecht def check_expected_threads_present(self, main_thread, second_thread, third_thread): 15099451b44SJordan Rupprecht self.assertTrue( 1512238dcc3SJonas Devlieghere main_thread.IsValid() 1522238dcc3SJonas Devlieghere and second_thread.IsValid() 1532238dcc3SJonas Devlieghere and third_thread.IsValid(), 1542238dcc3SJonas Devlieghere "Got all three expected threads", 1552238dcc3SJonas Devlieghere ) 156