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
1699451b44SJordan Rupprecht    @skipUnlessPlatform(['linux'])
1799451b44SJordan Rupprecht    @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")
2799451b44SJordan Rupprecht        self.assertTrue(
2899451b44SJordan Rupprecht            breakpoint and breakpoint.IsValid(),
2999451b44SJordan Rupprecht            "Breakpoint is valid")
3099451b44SJordan Rupprecht
3199451b44SJordan Rupprecht        # Run the program.
3299451b44SJordan Rupprecht        process = target.LaunchSimple(
3399451b44SJordan Rupprecht            None, None, self.get_process_working_directory())
3499451b44SJordan Rupprecht        self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
3599451b44SJordan Rupprecht
3699451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint.
3799451b44SJordan Rupprecht        self.assertEqual(
3899451b44SJordan Rupprecht            process.GetState(),
3999451b44SJordan Rupprecht            lldb.eStateStopped,
4099451b44SJordan Rupprecht            PROCESS_STOPPED)
4199451b44SJordan Rupprecht
4299451b44SJordan Rupprecht        threads = lldbutil.get_threads_stopped_at_breakpoint(
4399451b44SJordan Rupprecht            process, breakpoint)
4499451b44SJordan Rupprecht        self.assertEqual(len(threads), 1, STOPPED_DUE_TO_BREAKPOINT)
4599451b44SJordan Rupprecht
4699451b44SJordan Rupprecht        thread = threads[0]
4799451b44SJordan Rupprecht        self.assertTrue(thread and thread.IsValid(), "Thread is valid")
4899451b44SJordan Rupprecht
4999451b44SJordan Rupprecht        # Make sure we see only one threads
5099451b44SJordan Rupprecht        self.assertEqual(
5199451b44SJordan Rupprecht            process.GetNumThreads(),
5299451b44SJordan Rupprecht            1,
5399451b44SJordan Rupprecht            'Number of expected threads and actual threads do not match.')
5499451b44SJordan Rupprecht
5599451b44SJordan Rupprecht        # Keep stepping until we see the thread creation
5699451b44SJordan Rupprecht        while process.GetNumThreads() < 2:
5799451b44SJordan Rupprecht            thread.StepInstruction(False)
5899451b44SJordan Rupprecht            self.assertEqual(
5999451b44SJordan Rupprecht                process.GetState(),
6099451b44SJordan Rupprecht                lldb.eStateStopped,
6199451b44SJordan Rupprecht                PROCESS_STOPPED)
6299451b44SJordan Rupprecht            self.assertEqual(
6399451b44SJordan Rupprecht                thread.GetStopReason(),
6499451b44SJordan Rupprecht                lldb.eStopReasonPlanComplete,
6599451b44SJordan Rupprecht                "Step operation succeeded")
6699451b44SJordan Rupprecht            if self.TraceOn():
6799451b44SJordan Rupprecht                self.runCmd("disassemble --pc")
6899451b44SJordan Rupprecht
6999451b44SJordan Rupprecht        if self.TraceOn():
7099451b44SJordan Rupprecht            self.runCmd("thread list")
7199451b44SJordan Rupprecht
7299451b44SJordan Rupprecht        # We have successfully caught thread creation. Now just run to
7399451b44SJordan Rupprecht        # completion
7499451b44SJordan Rupprecht        process.Continue()
7599451b44SJordan Rupprecht
7699451b44SJordan Rupprecht        # At this point, the inferior process should have exited.
77*1b8c7352SJonas Devlieghere        self.assertState(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
78