xref: /llvm-project/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py (revision c63cb0c80ec7eb2dedad6e89fb9a3042b71d3b0f)
1"""
2Test python scripted process in lldb
3"""
4
5import os
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11from lldbsuite.test import lldbtest
12
13
14class ScriptedProcesTestCase(TestBase):
15
16    mydir = TestBase.compute_mydir(__file__)
17
18    def setUp(self):
19        TestBase.setUp(self)
20        self.source = "main.c"
21
22    def tearDown(self):
23        TestBase.tearDown(self)
24
25    def test_python_plugin_package(self):
26        """Test that the lldb python module has a `plugins.scripted_process`
27        package."""
28        self.expect('script import lldb.plugins',
29                    substrs=["ModuleNotFoundError"], matching=False)
30
31        self.expect('script dir(lldb.plugins)',
32                    substrs=["scripted_process"])
33
34        self.expect('script import lldb.plugins.scripted_process',
35                    substrs=["ModuleNotFoundError"], matching=False)
36
37        self.expect('script dir(lldb.plugins.scripted_process)',
38                    substrs=["ScriptedProcess"])
39
40        self.expect('script from lldb.plugins.scripted_process import ScriptedProcess',
41                    substrs=["ImportError"], matching=False)
42
43        self.expect('script dir(ScriptedProcess)',
44                    substrs=["launch"])
45
46    @skipIf(oslist=["linux"], archs=["arm", "aarch64"])
47    def test_scripted_process_and_scripted_thread(self):
48        """Test that we can launch an lldb scripted process using the SBAPI,
49        check its process ID, read string from memory, check scripted thread
50        id, name stop reason and register context.
51        """
52        self.build()
53        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
54        self.assertTrue(target, VALID_TARGET)
55
56        scripted_process_example_relpath = 'dummy_scripted_process.py'
57        os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1'
58        self.runCmd("command script import " + os.path.join(self.getSourceDir(),
59                                                            scripted_process_example_relpath))
60
61        launch_info = lldb.SBLaunchInfo(None)
62        launch_info.SetProcessPluginName("ScriptedProcess")
63        launch_info.SetScriptedProcessClassName("dummy_scripted_process.DummyScriptedProcess")
64
65        error = lldb.SBError()
66        process = target.Launch(launch_info, error)
67        self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
68        self.assertEqual(process.GetProcessID(), 42)
69
70        self.assertEqual(process.GetNumThreads(), 1)
71
72        thread = process.GetSelectedThread()
73        self.assertTrue(thread, "Invalid thread.")
74        self.assertEqual(thread.GetThreadID(), 0x19)
75        self.assertEqual(thread.GetName(), "DummyScriptedThread.thread-1")
76        self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal)
77
78        self.assertGreater(thread.GetNumFrames(), 0)
79
80        frame = thread.GetFrameAtIndex(0)
81        register_set = frame.registers # Returns an SBValueList.
82        for regs in register_set:
83            if 'GPR' in regs.name:
84                registers  = regs
85                break
86
87        self.assertTrue(registers, "Invalid General Purpose Registers Set")
88        self.assertEqual(registers.GetNumChildren(), 21)
89        for idx, reg in enumerate(registers, start=1):
90            self.assertEqual(idx, int(reg.value, 16))
91
92    @skipIfDarwin
93    @skipUnlessDarwin
94    def test_launch_scripted_process_stack_frames(self):
95        """Test that we can launch an lldb scripted process from the command
96        line, check its process ID and read string from memory."""
97        self.build()
98        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
99        self.assertTrue(target, VALID_TARGET)
100
101        for module in target.modules:
102            if 'a.out' in module.GetFileSpec().GetFilename():
103                main_module = module
104
105        self.assertTrue(main_module, "Invalid main module.")
106        error = target.SetModuleLoadAddress(main_module, 0)
107        self.assertTrue(error.Success(), "Reloading main module at offset 0 failed.")
108
109        scripted_process_example_relpath = ['..','..','..','..','examples','python','scripted_process','my_scripted_process.py']
110        self.runCmd("command script import " + os.path.join(self.getSourceDir(),
111                                                            *scripted_process_example_relpath))
112
113        process = target.GetProcess()
114        self.assertTrue(process, PROCESS_IS_VALID)
115        self.assertEqual(process.GetProcessID(), 42)
116        self.assertEqual(process.GetNumThreads(), 1)
117
118        thread = process.GetSelectedThread()
119        self.assertTrue(thread, "Invalid thread.")
120        self.assertEqual(thread.GetThreadID(), 0x19)
121        self.assertEqual(thread.GetName(), "MyScriptedThread.thread-1")
122
123        self.assertEqual(thread.GetNumFrames(), 4)
124        frame = thread.GetSelectedFrame()
125        self.assertTrue(frame, "Invalid frame.")
126        self.assertEqual(frame.GetFunctionName(), "bar")
127        self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42)
128        self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42)
129