156 lines · python
1"""Test that we get thread names when interrupting a process."""2 3 4import time5import lldb6from lldbsuite.test.decorators import *7from lldbsuite.test.lldbtest import *8from lldbsuite.test import lldbutil9 10 11class TestInterruptThreadNames(TestBase):12 @skipUnlessDarwin13 @add_test_categories(["pyapi"])14 def test_with_python_api(self):15 """Test that we get thread names when interrupting a process."""16 self.build()17 exe = self.getBuildArtifact("a.out")18 19 target = self.dbg.CreateTarget(exe)20 self.assertTrue(target, VALID_TARGET)21 22 launch_info = target.GetLaunchInfo()23 error = lldb.SBError()24 self.dbg.SetAsync(True)25 process = target.Launch(launch_info, error)26 self.assertTrue(process, PROCESS_IS_VALID)27 28 listener = self.dbg.GetListener()29 broadcaster = process.GetBroadcaster()30 rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)31 self.assertNotEqual(rc, 0, "Unable to add listener to process")32 self.assertTrue(33 self.wait_for_running(process, listener),34 "Check that process is up and running",35 )36 37 inferior_set_up = self.wait_until_program_setup_complete(process, listener)38 39 # Check that the program was able to create its threads within the allotted time40 self.assertTrue(inferior_set_up.IsValid())41 self.assertEqual(inferior_set_up.GetValueAsSigned(), 1)42 43 self.check_number_of_threads(process)44 45 main_thread = lldb.SBThread()46 second_thread = lldb.SBThread()47 third_thread = lldb.SBThread()48 for idx in range(0, process.GetNumThreads()):49 t = process.GetThreadAtIndex(idx)50 if t.GetName() == "main thread":51 main_thread = t52 if t.GetName() == "second thread":53 second_thread = t54 if t.GetName() == "third thread":55 third_thread = t56 57 self.check_expected_threads_present(main_thread, second_thread, third_thread)58 59 process.Kill()60 61 # The process will set a global variable 'threads_up_and_running' to 1 when62 # it has has completed its setup. Sleep for one second, pause the program,63 # check to see if the global has that value, and continue if it does not.64 def wait_until_program_setup_complete(self, process, listener):65 inferior_set_up = lldb.SBValue()66 retry = 567 while retry > 0:68 arch = self.getArchitecture()69 # when running the testsuite against a remote arm device, it may take70 # a little longer for the process to start up. Use a "can't possibly take71 # longer than this" value.72 if arch == "arm64" or arch == "armv7":73 time.sleep(10)74 else:75 time.sleep(1)76 process.SendAsyncInterrupt()77 self.assertTrue(78 self.wait_for_stop(process, listener), "Check that process is paused"79 )80 inferior_set_up = process.GetTarget().CreateValueFromExpression(81 "threads_up_and_running", "threads_up_and_running"82 )83 if inferior_set_up.IsValid() and inferior_set_up.GetValueAsSigned() == 1:84 retry = 085 else:86 process.Continue()87 retry = retry - 188 return inferior_set_up89 90 # Listen to the process events until we get an event saying that the process is91 # running. Retry up to five times in case we get other events that are not92 # what we're looking for.93 def wait_for_running(self, process, listener):94 retry_count = 595 if process.GetState() == lldb.eStateRunning:96 return True97 98 while retry_count > 0:99 event = lldb.SBEvent()100 listener.WaitForEvent(2, event)101 if event.GetType() == lldb.SBProcess.eBroadcastBitStateChanged:102 if process.GetState() == lldb.eStateRunning:103 return True104 retry_count = retry_count - 1105 106 return False107 108 # Listen to the process events until we get an event saying the process is109 # stopped. Retry up to five times in case we get other events that we are110 # not looking for.111 def wait_for_stop(self, process, listener):112 retry_count = 5113 if (114 process.GetState() == lldb.eStateStopped115 or process.GetState() == lldb.eStateCrashed116 or process.GetState() == lldb.eStateDetached117 or process.GetState() == lldb.eStateExited118 ):119 return True120 121 while retry_count > 0:122 event = lldb.SBEvent()123 listener.WaitForEvent(2, event)124 if event.GetType() == lldb.SBProcess.eBroadcastBitStateChanged:125 if (126 process.GetState() == lldb.eStateStopped127 or process.GetState() == lldb.eStateCrashed128 or process.GetState() == lldb.eStateDetached129 or process.GetState() == lldb.eStateExited130 ):131 return True132 if (133 process.GetState() == lldb.eStateCrashed134 or process.GetState() == lldb.eStateDetached135 or process.GetState() == lldb.eStateExited136 ):137 return False138 retry_count = retry_count - 1139 140 return False141 142 def check_number_of_threads(self, process):143 self.assertEqual(144 process.GetNumThreads(),145 3,146 "Check that the process has three threads when sitting at the stopper() breakpoint",147 )148 149 def check_expected_threads_present(self, main_thread, second_thread, third_thread):150 self.assertTrue(151 main_thread.IsValid()152 and second_thread.IsValid()153 and third_thread.IsValid(),154 "Got all three expected threads",155 )156