199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest some lldb command abbreviations.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprechtfrom __future__ import print_function
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 ExecTestCase(TestBase):
1499451b44SJordan Rupprecht
1599451b44SJordan Rupprecht    NO_DEBUG_INFO_TESTCASE = True
1699451b44SJordan Rupprecht
1799451b44SJordan Rupprecht    mydir = TestBase.compute_mydir(__file__)
1899451b44SJordan Rupprecht
1997a2eac3SMichał Górny    @expectedFailureAll(archs=['i386'],
2097a2eac3SMichał Górny                        oslist=no_match(["freebsd"]),
2197a2eac3SMichał Górny                        bugnumber="rdar://28656532")
2299451b44SJordan Rupprecht    @expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://problem/34559552") # this exec test has problems on ios systems
2399451b44SJordan Rupprecht    @expectedFailureNetBSD
2499451b44SJordan Rupprecht    @skipIfAsan # rdar://problem/43756823
2599451b44SJordan Rupprecht    @skipIfWindows
2699451b44SJordan Rupprecht    def test_hitting_exec (self):
2799451b44SJordan Rupprecht        self.do_test(False)
2899451b44SJordan Rupprecht
2997a2eac3SMichał Górny    @expectedFailureAll(archs=['i386'],
3097a2eac3SMichał Górny                        oslist=no_match(["freebsd"]),
3197a2eac3SMichał Górny                        bugnumber="rdar://28656532")
3299451b44SJordan Rupprecht    @expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://problem/34559552") # this exec test has problems on ios systems
3399451b44SJordan Rupprecht    @expectedFailureNetBSD
3499451b44SJordan Rupprecht    @skipIfAsan # rdar://problem/43756823
3599451b44SJordan Rupprecht    @skipIfWindows
3699451b44SJordan Rupprecht    def test_skipping_exec (self):
3799451b44SJordan Rupprecht        self.do_test(True)
3899451b44SJordan Rupprecht
3999451b44SJordan Rupprecht    def do_test(self, skip_exec):
4099451b44SJordan Rupprecht        self.build()
4199451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
4299451b44SJordan Rupprecht        secondprog = self.getBuildArtifact("secondprog")
4399451b44SJordan Rupprecht
4499451b44SJordan Rupprecht        # Create the target
4599451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
4699451b44SJordan Rupprecht
4799451b44SJordan Rupprecht        # Create any breakpoints we need
4899451b44SJordan Rupprecht        breakpoint1 = target.BreakpointCreateBySourceRegex(
4999451b44SJordan Rupprecht            'Set breakpoint 1 here', lldb.SBFileSpec("main.cpp", False))
5099451b44SJordan Rupprecht        self.assertTrue(breakpoint1, VALID_BREAKPOINT)
5199451b44SJordan Rupprecht        breakpoint2 = target.BreakpointCreateBySourceRegex(
5299451b44SJordan Rupprecht            'Set breakpoint 2 here', lldb.SBFileSpec("secondprog.cpp", False))
5399451b44SJordan Rupprecht        self.assertTrue(breakpoint2, VALID_BREAKPOINT)
5499451b44SJordan Rupprecht
5599451b44SJordan Rupprecht        # Launch the process
5699451b44SJordan Rupprecht        process = target.LaunchSimple(
5799451b44SJordan Rupprecht            None, None, self.get_process_working_directory())
5899451b44SJordan Rupprecht        self.assertTrue(process, PROCESS_IS_VALID)
5999451b44SJordan Rupprecht
6099451b44SJordan Rupprecht        if self.TraceOn():
6199451b44SJordan Rupprecht            self.runCmd("settings show target.process.stop-on-exec", check=False)
6299451b44SJordan Rupprecht        if skip_exec:
6399451b44SJordan Rupprecht            self.dbg.HandleCommand("settings set target.process.stop-on-exec false")
6499451b44SJordan Rupprecht            def cleanup():
6599451b44SJordan Rupprecht                self.runCmd("settings set target.process.stop-on-exec false",
6699451b44SJordan Rupprecht                            check=False)
6799451b44SJordan Rupprecht
6899451b44SJordan Rupprecht            # Execute the cleanup function during test case tear down.
6999451b44SJordan Rupprecht            self.addTearDownHook(cleanup)
7099451b44SJordan Rupprecht
7199451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint.
72*619e2e09SDave Lee        self.assertEqual(process.GetState(), lldb.eStateStopped,
7399451b44SJordan Rupprecht                        STOPPED_DUE_TO_BREAKPOINT)
7499451b44SJordan Rupprecht
7599451b44SJordan Rupprecht        threads = lldbutil.get_threads_stopped_at_breakpoint(
7699451b44SJordan Rupprecht        process, breakpoint1)
77*619e2e09SDave Lee        self.assertEqual(len(threads), 1)
7899451b44SJordan Rupprecht
7999451b44SJordan Rupprecht        # We had a deadlock tearing down the TypeSystemMap on exec, but only if some
8099451b44SJordan Rupprecht        # expression had been evaluated.  So make sure we do that here so the teardown
8199451b44SJordan Rupprecht        # is not trivial.
8299451b44SJordan Rupprecht
8399451b44SJordan Rupprecht        thread = threads[0]
8499451b44SJordan Rupprecht        value = thread.frames[0].EvaluateExpression("1 + 2")
8599451b44SJordan Rupprecht        self.assertTrue(
8699451b44SJordan Rupprecht            value.IsValid(),
8799451b44SJordan Rupprecht            "Expression evaluated successfully")
8899451b44SJordan Rupprecht        int_value = value.GetValueAsSigned()
89*619e2e09SDave Lee        self.assertEqual(int_value, 3, "Expression got the right result.")
9099451b44SJordan Rupprecht
9199451b44SJordan Rupprecht        # Run and we should stop due to exec
9299451b44SJordan Rupprecht        process.Continue()
9399451b44SJordan Rupprecht
9499451b44SJordan Rupprecht        if not skip_exec:
95*619e2e09SDave Lee            self.assertNotEqual(process.GetState(), lldb.eStateExited,
9699451b44SJordan Rupprecht                                "Process should not have exited!")
97*619e2e09SDave Lee            self.assertEqual(process.GetState(), lldb.eStateStopped,
9899451b44SJordan Rupprecht                             "Process should be stopped at __dyld_start")
9999451b44SJordan Rupprecht
10099451b44SJordan Rupprecht            threads = lldbutil.get_stopped_threads(
10199451b44SJordan Rupprecht                process, lldb.eStopReasonExec)
10299451b44SJordan Rupprecht            self.assertTrue(
10399451b44SJordan Rupprecht                len(threads) == 1,
10499451b44SJordan Rupprecht                "We got a thread stopped for exec.")
10599451b44SJordan Rupprecht
10699451b44SJordan Rupprecht            # Run and we should stop at breakpoint in main after exec
10799451b44SJordan Rupprecht            process.Continue()
10899451b44SJordan Rupprecht
10999451b44SJordan Rupprecht        threads = lldbutil.get_threads_stopped_at_breakpoint(
11099451b44SJordan Rupprecht            process, breakpoint2)
11199451b44SJordan Rupprecht        if self.TraceOn():
11299451b44SJordan Rupprecht            for t in process.threads:
11399451b44SJordan Rupprecht                print(t)
11499451b44SJordan Rupprecht                if t.GetStopReason() != lldb.eStopReasonBreakpoint:
11599451b44SJordan Rupprecht                    self.runCmd("bt")
116*619e2e09SDave Lee        self.assertEqual(len(threads), 1,
11799451b44SJordan Rupprecht                        "Stopped at breakpoint in exec'ed process.")
1184bb62448SWalter Erquinigo
1194bb62448SWalter Erquinigo    @expectedFailureAll(archs=['i386'],
1204bb62448SWalter Erquinigo                        oslist=no_match(["freebsd"]),
1214bb62448SWalter Erquinigo                        bugnumber="rdar://28656532")
1224bb62448SWalter Erquinigo    @expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://problem/34559552") # this exec test has problems on ios systems
1234bb62448SWalter Erquinigo    @expectedFailureNetBSD
1244bb62448SWalter Erquinigo    @skipIfAsan # rdar://problem/43756823
1254bb62448SWalter Erquinigo    @skipIfWindows
1264bb62448SWalter Erquinigo    def test_correct_thread_plan_state_before_exec(self):
1274bb62448SWalter Erquinigo        '''
1284bb62448SWalter Erquinigo        In this test we make sure that the Thread* cache in the ThreadPlans
1294bb62448SWalter Erquinigo        is cleared correctly when performing exec
1304bb62448SWalter Erquinigo        '''
1314bb62448SWalter Erquinigo
1324bb62448SWalter Erquinigo        self.build()
1334bb62448SWalter Erquinigo        exe = self.getBuildArtifact("a.out")
1344bb62448SWalter Erquinigo        target = self.dbg.CreateTarget(exe)
1354bb62448SWalter Erquinigo
1364bb62448SWalter Erquinigo        (target, process, thread, breakpoint1) = lldbutil.run_to_source_breakpoint(
1374bb62448SWalter Erquinigo            self, 'Set breakpoint 1 here', lldb.SBFileSpec('main.cpp', False))
1384bb62448SWalter Erquinigo
1394bb62448SWalter Erquinigo        # The stop reason of the thread should be breakpoint.
140*619e2e09SDave Lee        self.assertEqual(process.GetState(), lldb.eStateStopped,
1414bb62448SWalter Erquinigo                        STOPPED_DUE_TO_BREAKPOINT)
1424bb62448SWalter Erquinigo
1434bb62448SWalter Erquinigo        threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint1)
144*619e2e09SDave Lee        self.assertEqual(len(threads), 1)
1454bb62448SWalter Erquinigo
1464bb62448SWalter Erquinigo        # We perform an instruction step, which effectively sets the cache of the base
1474bb62448SWalter Erquinigo        # thread plan, which should be cleared when a new thread list appears.
1484bb62448SWalter Erquinigo        #
1494bb62448SWalter Erquinigo        # Continuing after this instruction step will trigger a call to
1504bb62448SWalter Erquinigo        # ThreadPlan::ShouldReportRun, which sets the ThreadPlan's Thread cache to
1514bb62448SWalter Erquinigo        # the old Thread* value. In Process::UpdateThreadList we are clearing this
1524bb62448SWalter Erquinigo        # cache in preparation for the new ThreadList.
1534bb62448SWalter Erquinigo        #
1544bb62448SWalter Erquinigo        # Not doing this stepping will cause LLDB to first execute a private single step
1554bb62448SWalter Erquinigo        # past the current breakpoint, which eventually avoids the call to ShouldReportRun,
1564bb62448SWalter Erquinigo        # thus not setting the cache to its invalid value.
1574bb62448SWalter Erquinigo        thread.StepInstruction(False)
1584bb62448SWalter Erquinigo
1594bb62448SWalter Erquinigo        # Run and we should stop due to exec
1604bb62448SWalter Erquinigo        breakpoint2 = target.BreakpointCreateBySourceRegex(
1614bb62448SWalter Erquinigo            'Set breakpoint 2 here', lldb.SBFileSpec("secondprog.cpp", False))
1624bb62448SWalter Erquinigo
1634bb62448SWalter Erquinigo        process.Continue()
1644bb62448SWalter Erquinigo
165*619e2e09SDave Lee        self.assertNotEqual(process.GetState(), lldb.eStateExited,
1664bb62448SWalter Erquinigo                            "Process should not have exited!")
167*619e2e09SDave Lee        self.assertEqual(process.GetState(), lldb.eStateStopped,
1684bb62448SWalter Erquinigo                         "Process should be stopped at __dyld_start")
1694bb62448SWalter Erquinigo
1704bb62448SWalter Erquinigo        threads = lldbutil.get_stopped_threads(
1714bb62448SWalter Erquinigo            process, lldb.eStopReasonExec)
1724bb62448SWalter Erquinigo        self.assertTrue(
1734bb62448SWalter Erquinigo            len(threads) == 1,
1744bb62448SWalter Erquinigo            "We got a thread stopped for exec.")
1754bb62448SWalter Erquinigo
1764bb62448SWalter Erquinigo        # Run and we should stop at breakpoint in main after exec
1774bb62448SWalter Erquinigo        process.Continue()
1784bb62448SWalter Erquinigo
1794bb62448SWalter Erquinigo        threads = lldbutil.get_threads_stopped_at_breakpoint(
1804bb62448SWalter Erquinigo            process, breakpoint2)
181*619e2e09SDave Lee        self.assertEqual(len(threads), 1,
1824bb62448SWalter Erquinigo                        "Stopped at breakpoint in exec'ed process.")
183