xref: /llvm-project/lldb/test/API/python_api/run_locker/TestRunLocker.py (revision eb21ee49cff081911d99d29ba887c1715fc2b8fc)
1"""
2Test that the run locker really does work to keep
3us from running SB API that should only be run
4while stopped.  This test is mostly concerned with
5what happens between launch and first stop.
6"""
7
8import lldb
9import lldbsuite.test.lldbutil as lldbutil
10from lldbsuite.test.decorators import *
11from lldbsuite.test.lldbtest import *
12
13
14class TestRunLocker(TestBase):
15    NO_DEBUG_INFO_TESTCASE = True
16
17    @expectedFailureAll(oslist=["windows"])
18    # Is flaky on Linux AArch64 buildbot.
19    @skipIf(oslist=["linux"], archs=["aarch64"])
20    def test_run_locker(self):
21        """Test that the run locker is set correctly when we launch"""
22        self.build()
23        self.runlocker_test(False)
24
25    @expectedFailureAll(oslist=["windows"])
26    # Is flaky on Linux AArch64 buildbot.
27    @skipIf(oslist=["linux"], archs=["aarch64"])
28    def test_run_locker_stop_at_entry(self):
29        """Test that the run locker is set correctly when we launch"""
30        self.build()
31        self.runlocker_test(False)
32
33    def setUp(self):
34        # Call super's setUp().
35        TestBase.setUp(self)
36        self.main_source_file = lldb.SBFileSpec("main.c")
37
38    def runlocker_test(self, stop_at_entry):
39        """The code to stop at entry handles events slightly differently, so
40        we test both versions of process launch."""
41
42        target = lldbutil.run_to_breakpoint_make_target(self)
43
44        launch_info = target.GetLaunchInfo()
45        if stop_at_entry:
46            flags = launch_info.GetFlags()
47            launch_info.SetFlags(flags | lldb.eLaunchFlagStopAtEntry)
48
49        error = lldb.SBError()
50        # We are trying to do things when the process is running, so
51        # we have to run the debugger asynchronously.
52        self.dbg.SetAsync(True)
53
54        listener = lldb.SBListener("test-run-lock-listener")
55        launch_info.SetListener(listener)
56        process = target.Launch(launch_info, error)
57        self.assertSuccess(error, "Launched the process")
58
59        event = lldb.SBEvent()
60
61        event_result = listener.WaitForEvent(10, event)
62        self.assertTrue(event_result, "timed out waiting for launch")
63        state_type = lldb.SBProcess.GetStateFromEvent(event)
64        # We don't always see a launching...
65        if state_type == lldb.eStateLaunching:
66            event_result = listener.WaitForEvent(10, event)
67            self.assertTrue(
68                event_result, "Timed out waiting for running after launching"
69            )
70            state_type = lldb.SBProcess.GetStateFromEvent(event)
71
72        self.assertState(state_type, lldb.eStateRunning, "Didn't get a running event")
73
74        # We aren't checking the entry state, but just making sure
75        # the running state is set properly if we continue in this state.
76
77        if stop_at_entry:
78            event_result = listener.WaitForEvent(10, event)
79            self.assertTrue(event_result, "Timed out waiting for stop at entry stop")
80            state_type = lldb.SBProcess.GetStateFromEvent(event)
81            self.assertState(state_type, eStateStopped, "Stop at entry stopped")
82            process.Continue()
83
84        # Okay, now the process is running, make sure we can't do things
85        # you aren't supposed to do while running, and that we get some
86        # actual error:
87        val = target.EvaluateExpression("SomethingToCall()")
88        error = val.GetError()
89        self.assertTrue(error.Fail(), "Failed to run expression")
90        self.assertIn(
91            "can't evaluate expressions when the process is running",
92            error.GetCString(),
93            "Stopped by stop locker",
94        )
95
96        # This should also fail if we try to use the script interpreter directly:
97        interp = self.dbg.GetCommandInterpreter()
98        result = lldb.SBCommandReturnObject()
99        ret = interp.HandleCommand(
100            "script var = lldb.frame.EvaluateExpression('SomethingToCall()'); var.GetError().GetCString()",
101            result,
102        )
103        self.assertIn(
104            "can't evaluate expressions when the process is running", result.GetOutput()
105        )
106