xref: /llvm-project/lldb/test/API/functionalities/exec/TestExec.py (revision f658d84e01bcdd49e27dc9ef80e1a6cc5f9417fe)
199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest some lldb command abbreviations.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
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 ExecTestCase(TestBase):
1299451b44SJordan Rupprecht    NO_DEBUG_INFO_TESTCASE = True
1399451b44SJordan Rupprecht
142238dcc3SJonas Devlieghere    @expectedFailureAll(
152238dcc3SJonas Devlieghere        archs=["i386"], oslist=no_match(["freebsd"]), bugnumber="rdar://28656532"
162238dcc3SJonas Devlieghere    )
172238dcc3SJonas Devlieghere    @expectedFailureAll(
182238dcc3SJonas Devlieghere        oslist=["ios", "tvos", "watchos", "bridgeos"],
192238dcc3SJonas Devlieghere        bugnumber="rdar://problem/34559552",
202238dcc3SJonas Devlieghere    )  # this exec test has problems on ios systems
2199451b44SJordan Rupprecht    @expectedFailureNetBSD
2299451b44SJordan Rupprecht    @skipIfAsan  # rdar://problem/43756823
2399451b44SJordan Rupprecht    @skipIfWindows
2499451b44SJordan Rupprecht    def test_hitting_exec(self):
2599451b44SJordan Rupprecht        self.do_test(False)
2699451b44SJordan Rupprecht
272238dcc3SJonas Devlieghere    @expectedFailureAll(
282238dcc3SJonas Devlieghere        archs=["i386"], oslist=no_match(["freebsd"]), bugnumber="rdar://28656532"
292238dcc3SJonas Devlieghere    )
302238dcc3SJonas Devlieghere    @expectedFailureAll(
312238dcc3SJonas Devlieghere        oslist=["ios", "tvos", "watchos", "bridgeos"],
322238dcc3SJonas Devlieghere        bugnumber="rdar://problem/34559552",
332238dcc3SJonas Devlieghere    )  # this exec test has problems on ios systems
3499451b44SJordan Rupprecht    @expectedFailureNetBSD
3599451b44SJordan Rupprecht    @skipIfAsan  # rdar://problem/43756823
3699451b44SJordan Rupprecht    @skipIfWindows
3799451b44SJordan Rupprecht    def test_skipping_exec(self):
3899451b44SJordan Rupprecht        self.do_test(True)
3999451b44SJordan Rupprecht
4099451b44SJordan Rupprecht    def do_test(self, skip_exec):
4199451b44SJordan Rupprecht        self.build()
4299451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
4399451b44SJordan Rupprecht        secondprog = self.getBuildArtifact("secondprog")
4499451b44SJordan Rupprecht
4599451b44SJordan Rupprecht        # Create the target
4699451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
4799451b44SJordan Rupprecht
48*f658d84eSDmitry Vasilyev        lldbutil.install_to_target(self, secondprog)
49*f658d84eSDmitry Vasilyev
5099451b44SJordan Rupprecht        # Create any breakpoints we need
5199451b44SJordan Rupprecht        breakpoint1 = target.BreakpointCreateBySourceRegex(
522238dcc3SJonas Devlieghere            "Set breakpoint 1 here", lldb.SBFileSpec("main.c", False)
532238dcc3SJonas Devlieghere        )
5499451b44SJordan Rupprecht        self.assertTrue(breakpoint1, VALID_BREAKPOINT)
5599451b44SJordan Rupprecht        breakpoint2 = target.BreakpointCreateBySourceRegex(
562238dcc3SJonas Devlieghere            "Set breakpoint 2 here", lldb.SBFileSpec("secondprog.cpp", False)
572238dcc3SJonas Devlieghere        )
5899451b44SJordan Rupprecht        self.assertTrue(breakpoint2, VALID_BREAKPOINT)
5999451b44SJordan Rupprecht
6099451b44SJordan Rupprecht        # Launch the process
612238dcc3SJonas Devlieghere        process = target.LaunchSimple(None, None, self.get_process_working_directory())
6299451b44SJordan Rupprecht        self.assertTrue(process, PROCESS_IS_VALID)
6399451b44SJordan Rupprecht
6499451b44SJordan Rupprecht        if self.TraceOn():
6599451b44SJordan Rupprecht            self.runCmd("settings show target.process.stop-on-exec", check=False)
6699451b44SJordan Rupprecht        if skip_exec:
6799451b44SJordan Rupprecht            self.dbg.HandleCommand("settings set target.process.stop-on-exec false")
682238dcc3SJonas Devlieghere
6999451b44SJordan Rupprecht            def cleanup():
702238dcc3SJonas Devlieghere                self.runCmd(
712238dcc3SJonas Devlieghere                    "settings set target.process.stop-on-exec false", check=False
722238dcc3SJonas Devlieghere                )
7399451b44SJordan Rupprecht
7499451b44SJordan Rupprecht            # Execute the cleanup function during test case tear down.
7599451b44SJordan Rupprecht            self.addTearDownHook(cleanup)
7699451b44SJordan Rupprecht
7799451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint.
782238dcc3SJonas Devlieghere        self.assertState(
792238dcc3SJonas Devlieghere            process.GetState(), lldb.eStateStopped, STOPPED_DUE_TO_BREAKPOINT
802238dcc3SJonas Devlieghere        )
8199451b44SJordan Rupprecht
822238dcc3SJonas Devlieghere        threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint1)
83619e2e09SDave Lee        self.assertEqual(len(threads), 1)
8499451b44SJordan Rupprecht
8599451b44SJordan Rupprecht        # We had a deadlock tearing down the TypeSystemMap on exec, but only if some
8699451b44SJordan Rupprecht        # expression had been evaluated.  So make sure we do that here so the teardown
8799451b44SJordan Rupprecht        # is not trivial.
8899451b44SJordan Rupprecht
8999451b44SJordan Rupprecht        thread = threads[0]
9099451b44SJordan Rupprecht        value = thread.frames[0].EvaluateExpression("1 + 2")
912238dcc3SJonas Devlieghere        self.assertTrue(value.IsValid(), "Expression evaluated successfully")
9299451b44SJordan Rupprecht        int_value = value.GetValueAsSigned()
93619e2e09SDave Lee        self.assertEqual(int_value, 3, "Expression got the right result.")
9499451b44SJordan Rupprecht
9599451b44SJordan Rupprecht        # Run and we should stop due to exec
9699451b44SJordan Rupprecht        process.Continue()
9799451b44SJordan Rupprecht
9899451b44SJordan Rupprecht        if not skip_exec:
992238dcc3SJonas Devlieghere            self.assertNotEqual(
1002238dcc3SJonas Devlieghere                process.GetState(), lldb.eStateExited, "Process should not have exited!"
1012238dcc3SJonas Devlieghere            )
1022238dcc3SJonas Devlieghere            self.assertState(
1032238dcc3SJonas Devlieghere                process.GetState(),
1042238dcc3SJonas Devlieghere                lldb.eStateStopped,
1052238dcc3SJonas Devlieghere                "Process should be stopped at __dyld_start",
1062238dcc3SJonas Devlieghere            )
10799451b44SJordan Rupprecht
1082238dcc3SJonas Devlieghere            threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonExec)
1092238dcc3SJonas Devlieghere            self.assertEqual(len(threads), 1, "We got a thread stopped for exec.")
11099451b44SJordan Rupprecht
11199451b44SJordan Rupprecht            # Run and we should stop at breakpoint in main after exec
11299451b44SJordan Rupprecht            process.Continue()
11399451b44SJordan Rupprecht
114773d9c36SDave Lee        self.assertState(process.GetState(), lldb.eStateStopped)
115773d9c36SDave Lee        for t in process.threads:
116773d9c36SDave Lee            if t.stop_reason != lldb.eStopReasonNone:
1172238dcc3SJonas Devlieghere                self.assertStopReason(
1182238dcc3SJonas Devlieghere                    t.stop_reason, lldb.eStopReasonBreakpoint, "Unexpected stop reason"
1192238dcc3SJonas Devlieghere                )
120773d9c36SDave Lee                if self.TraceOn():
121773d9c36SDave Lee                    print(t)
122773d9c36SDave Lee                    if t.stop_reason != lldb.eStopReasonBreakpoint:
123773d9c36SDave Lee                        self.runCmd("bt")
124773d9c36SDave Lee
1252238dcc3SJonas Devlieghere        threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint2)
1262238dcc3SJonas Devlieghere        self.assertEqual(len(threads), 1, "Stopped at breakpoint in exec'ed process.")
1274bb62448SWalter Erquinigo
1282238dcc3SJonas Devlieghere    @expectedFailureAll(
1292238dcc3SJonas Devlieghere        archs=["i386"], oslist=no_match(["freebsd"]), bugnumber="rdar://28656532"
1302238dcc3SJonas Devlieghere    )
1312238dcc3SJonas Devlieghere    @expectedFailureAll(
1322238dcc3SJonas Devlieghere        oslist=["ios", "tvos", "watchos", "bridgeos"],
1332238dcc3SJonas Devlieghere        bugnumber="rdar://problem/34559552",
1342238dcc3SJonas Devlieghere    )  # this exec test has problems on ios systems
1354bb62448SWalter Erquinigo    @expectedFailureNetBSD
1364bb62448SWalter Erquinigo    @skipIfAsan  # rdar://problem/43756823
1374bb62448SWalter Erquinigo    @skipIfWindows
1384bb62448SWalter Erquinigo    def test_correct_thread_plan_state_before_exec(self):
1392238dcc3SJonas Devlieghere        """
1404bb62448SWalter Erquinigo        In this test we make sure that the Thread* cache in the ThreadPlans
1414bb62448SWalter Erquinigo        is cleared correctly when performing exec
1422238dcc3SJonas Devlieghere        """
1434bb62448SWalter Erquinigo
1444bb62448SWalter Erquinigo        self.build()
1454bb62448SWalter Erquinigo        exe = self.getBuildArtifact("a.out")
1464bb62448SWalter Erquinigo        target = self.dbg.CreateTarget(exe)
1474bb62448SWalter Erquinigo
148*f658d84eSDmitry Vasilyev        lldbutil.install_to_target(self, self.getBuildArtifact("secondprog"))
149*f658d84eSDmitry Vasilyev
1504bb62448SWalter Erquinigo        (target, process, thread, breakpoint1) = lldbutil.run_to_source_breakpoint(
1512238dcc3SJonas Devlieghere            self, "Set breakpoint 1 here", lldb.SBFileSpec("main.c", False)
1522238dcc3SJonas Devlieghere        )
1534bb62448SWalter Erquinigo
1544bb62448SWalter Erquinigo        # The stop reason of the thread should be breakpoint.
1552238dcc3SJonas Devlieghere        self.assertState(
1562238dcc3SJonas Devlieghere            process.GetState(), lldb.eStateStopped, STOPPED_DUE_TO_BREAKPOINT
1572238dcc3SJonas Devlieghere        )
1584bb62448SWalter Erquinigo
1594bb62448SWalter Erquinigo        threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint1)
160619e2e09SDave Lee        self.assertEqual(len(threads), 1)
1614bb62448SWalter Erquinigo
1624bb62448SWalter Erquinigo        # We perform an instruction step, which effectively sets the cache of the base
1634bb62448SWalter Erquinigo        # thread plan, which should be cleared when a new thread list appears.
1644bb62448SWalter Erquinigo        #
1654bb62448SWalter Erquinigo        # Continuing after this instruction step will trigger a call to
1664bb62448SWalter Erquinigo        # ThreadPlan::ShouldReportRun, which sets the ThreadPlan's Thread cache to
1674bb62448SWalter Erquinigo        # the old Thread* value. In Process::UpdateThreadList we are clearing this
1684bb62448SWalter Erquinigo        # cache in preparation for the new ThreadList.
1694bb62448SWalter Erquinigo        #
1704bb62448SWalter Erquinigo        # Not doing this stepping will cause LLDB to first execute a private single step
1714bb62448SWalter Erquinigo        # past the current breakpoint, which eventually avoids the call to ShouldReportRun,
1724bb62448SWalter Erquinigo        # thus not setting the cache to its invalid value.
1734bb62448SWalter Erquinigo        thread.StepInstruction(False)
1744bb62448SWalter Erquinigo
1754bb62448SWalter Erquinigo        # Run and we should stop due to exec
1764bb62448SWalter Erquinigo        breakpoint2 = target.BreakpointCreateBySourceRegex(
1772238dcc3SJonas Devlieghere            "Set breakpoint 2 here", lldb.SBFileSpec("secondprog.cpp", False)
1782238dcc3SJonas Devlieghere        )
1794bb62448SWalter Erquinigo
1804bb62448SWalter Erquinigo        process.Continue()
1814bb62448SWalter Erquinigo
1822238dcc3SJonas Devlieghere        self.assertNotEqual(
1832238dcc3SJonas Devlieghere            process.GetState(), lldb.eStateExited, "Process should not have exited!"
1842238dcc3SJonas Devlieghere        )
1852238dcc3SJonas Devlieghere        self.assertState(
1862238dcc3SJonas Devlieghere            process.GetState(),
1872238dcc3SJonas Devlieghere            lldb.eStateStopped,
1882238dcc3SJonas Devlieghere            "Process should be stopped at __dyld_start",
1892238dcc3SJonas Devlieghere        )
1904bb62448SWalter Erquinigo
1912238dcc3SJonas Devlieghere        threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonExec)
1922238dcc3SJonas Devlieghere        self.assertEqual(len(threads), 1, "We got a thread stopped for exec.")
1934bb62448SWalter Erquinigo
1944bb62448SWalter Erquinigo        # Run and we should stop at breakpoint in main after exec
1954bb62448SWalter Erquinigo        process.Continue()
1964bb62448SWalter Erquinigo
1972238dcc3SJonas Devlieghere        threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint2)
1982238dcc3SJonas Devlieghere        self.assertEqual(len(threads), 1, "Stopped at breakpoint in exec'ed process.")
199