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