1""" 2This tests that we do not lose control of the inferior, while doing an instruction-level step 3over a thread creation instruction. 4""" 5 6 7import lldb 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10from lldbsuite.test import lldbutil 11 12 13class CreateDuringInstructionStepTestCase(TestBase): 14 NO_DEBUG_INFO_TESTCASE = True 15 16 @skipUnlessPlatform(["linux"]) 17 @expectedFailureAndroid("llvm.org/pr24737", archs=["arm"]) 18 @skipIf(oslist=["linux"], archs=["arm", "aarch64"], bugnumber="llvm.org/pr24737") 19 def test_step_inst(self): 20 self.build() 21 exe = self.getBuildArtifact("a.out") 22 target = self.dbg.CreateTarget(exe) 23 self.assertTrue(target and target.IsValid(), "Target is valid") 24 25 # This should create a breakpoint in the stepping thread. 26 breakpoint = target.BreakpointCreateByName("main") 27 self.assertTrue(breakpoint and breakpoint.IsValid(), "Breakpoint is valid") 28 29 # Run the program. 30 process = target.LaunchSimple(None, None, self.get_process_working_directory()) 31 self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID) 32 33 # The stop reason of the thread should be breakpoint. 34 self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 35 36 threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint) 37 self.assertEqual(len(threads), 1, STOPPED_DUE_TO_BREAKPOINT) 38 39 thread = threads[0] 40 self.assertTrue(thread and thread.IsValid(), "Thread is valid") 41 42 # Make sure we see only one threads 43 self.assertEqual( 44 process.GetNumThreads(), 45 1, 46 "Number of expected threads and actual threads do not match.", 47 ) 48 49 # Keep stepping until we see the thread creation 50 while process.GetNumThreads() < 2: 51 thread.StepInstruction(False) 52 self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 53 self.assertEqual( 54 thread.GetStopReason(), 55 lldb.eStopReasonPlanComplete, 56 "Step operation succeeded", 57 ) 58 if self.TraceOn(): 59 self.runCmd("disassemble --pc") 60 61 if self.TraceOn(): 62 self.runCmd("thread list") 63 64 # We have successfully caught thread creation. Now just run to 65 # completion 66 process.Continue() 67 68 # At this point, the inferior process should have exited. 69 self.assertState(process.GetState(), lldb.eStateExited, PROCESS_EXITED) 70