199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtThis tests that we do not lose control of the inferior, while doing an instruction-level step
399451b44SJordan Rupprechtover a thread creation instruction.
499451b44SJordan Rupprecht"""
599451b44SJordan Rupprecht
699451b44SJordan Rupprecht
799451b44SJordan Rupprechtimport lldb
899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1099451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1199451b44SJordan Rupprecht
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprechtclass CreateDuringInstructionStepTestCase(TestBase):
1499451b44SJordan Rupprecht    NO_DEBUG_INFO_TESTCASE = True
1599451b44SJordan Rupprecht
16*2238dcc3SJonas Devlieghere    @skipUnlessPlatform(["linux"])
17*2238dcc3SJonas Devlieghere    @expectedFailureAndroid("llvm.org/pr24737", archs=["arm"])
183936b753SMuhammad Omair Javaid    @skipIf(oslist=["linux"], archs=["arm", "aarch64"], bugnumber="llvm.org/pr24737")
1999451b44SJordan Rupprecht    def test_step_inst(self):
20d7dbe2c4SPavel Labath        self.build()
2199451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
2299451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
2399451b44SJordan Rupprecht        self.assertTrue(target and target.IsValid(), "Target is valid")
2499451b44SJordan Rupprecht
2599451b44SJordan Rupprecht        # This should create a breakpoint in the stepping thread.
2699451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateByName("main")
27*2238dcc3SJonas Devlieghere        self.assertTrue(breakpoint and breakpoint.IsValid(), "Breakpoint is valid")
2899451b44SJordan Rupprecht
2999451b44SJordan Rupprecht        # Run the program.
30*2238dcc3SJonas Devlieghere        process = target.LaunchSimple(None, None, self.get_process_working_directory())
3199451b44SJordan Rupprecht        self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
3299451b44SJordan Rupprecht
3399451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint.
34*2238dcc3SJonas Devlieghere        self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
3599451b44SJordan Rupprecht
36*2238dcc3SJonas Devlieghere        threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint)
3799451b44SJordan Rupprecht        self.assertEqual(len(threads), 1, STOPPED_DUE_TO_BREAKPOINT)
3899451b44SJordan Rupprecht
3999451b44SJordan Rupprecht        thread = threads[0]
4099451b44SJordan Rupprecht        self.assertTrue(thread and thread.IsValid(), "Thread is valid")
4199451b44SJordan Rupprecht
4299451b44SJordan Rupprecht        # Make sure we see only one threads
4399451b44SJordan Rupprecht        self.assertEqual(
4499451b44SJordan Rupprecht            process.GetNumThreads(),
4599451b44SJordan Rupprecht            1,
46*2238dcc3SJonas Devlieghere            "Number of expected threads and actual threads do not match.",
47*2238dcc3SJonas Devlieghere        )
4899451b44SJordan Rupprecht
4999451b44SJordan Rupprecht        # Keep stepping until we see the thread creation
5099451b44SJordan Rupprecht        while process.GetNumThreads() < 2:
5199451b44SJordan Rupprecht            thread.StepInstruction(False)
52*2238dcc3SJonas Devlieghere            self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
5399451b44SJordan Rupprecht            self.assertEqual(
5499451b44SJordan Rupprecht                thread.GetStopReason(),
5599451b44SJordan Rupprecht                lldb.eStopReasonPlanComplete,
56*2238dcc3SJonas Devlieghere                "Step operation succeeded",
57*2238dcc3SJonas Devlieghere            )
5899451b44SJordan Rupprecht            if self.TraceOn():
5999451b44SJordan Rupprecht                self.runCmd("disassemble --pc")
6099451b44SJordan Rupprecht
6199451b44SJordan Rupprecht        if self.TraceOn():
6299451b44SJordan Rupprecht            self.runCmd("thread list")
6399451b44SJordan Rupprecht
6499451b44SJordan Rupprecht        # We have successfully caught thread creation. Now just run to
6599451b44SJordan Rupprecht        # completion
6699451b44SJordan Rupprecht        process.Continue()
6799451b44SJordan Rupprecht
6899451b44SJordan Rupprecht        # At this point, the inferior process should have exited.
691b8c7352SJonas Devlieghere        self.assertState(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
70