xref: /llvm-project/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py (revision c26e53e129085b64f66f0b4cbc5fd4bfdf6575e6)
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    def test_scripted_process_and_scripted_thread(self):
47        """Test that we can launch an lldb scripted process using the SBAPI,
48        check its process ID, read string from memory, check scripted thread
49        id, name stop reason and register context.
50        """
51        self.build()
52        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
53        self.assertTrue(target, VALID_TARGET)
54
55        scripted_process_example_relpath = 'dummy_scripted_process.py'
56        os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1'
57        self.runCmd("command script import " + os.path.join(self.getSourceDir(),
58                                                            scripted_process_example_relpath))
59
60        launch_info = lldb.SBLaunchInfo(None)
61        launch_info.SetProcessPluginName("ScriptedProcess")
62        launch_info.SetScriptedProcessClassName("dummy_scripted_process.DummyScriptedProcess")
63
64        error = lldb.SBError()
65        process = target.Launch(launch_info, error)
66        self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
67        self.assertEqual(process.GetProcessID(), 42)
68
69        self.assertEqual(process.GetNumThreads(), 1)
70
71        thread = process.GetSelectedThread()
72        self.assertTrue(thread, "Invalid thread.")
73        self.assertEqual(thread.GetThreadID(), 0x19)
74        self.assertEqual(thread.GetName(), "DummyScriptedThread.thread-1")
75        self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal)
76
77        self.assertGreater(thread.GetNumFrames(), 0)
78
79        frame = thread.GetFrameAtIndex(0)
80        register_set = frame.registers # Returns an SBValueList.
81        for regs in register_set:
82            if 'GPR' in regs.name:
83                registers  = regs
84                break
85
86        self.assertTrue(registers, "Invalid General Purpose Registers Set")
87        self.assertEqual(registers.GetNumChildren(), 21)
88        for idx, reg in enumerate(registers, start=1):
89            self.assertEqual(idx, int(reg.value, 16))
90
91    @skipIfDarwin
92    @skipUnlessDarwin
93    def test_launch_scripted_process_stack_frames(self):
94        """Test that we can launch an lldb scripted process from the command
95        line, check its process ID and read string from memory."""
96        self.build()
97        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
98        self.assertTrue(target, VALID_TARGET)
99
100        for module in target.modules:
101            if 'a.out' in module.GetFileSpec().GetFilename():
102                main_module = module
103
104        self.assertTrue(main_module, "Invalid main module.")
105        error = target.SetModuleLoadAddress(main_module, 0)
106        self.assertTrue(error.Success(), "Reloading main module at offset 0 failed.")
107
108        scripted_process_example_relpath = ['..','..','..','..','examples','python','scripted_process','my_scripted_process.py']
109        self.runCmd("command script import " + os.path.join(self.getSourceDir(),
110                                                            *scripted_process_example_relpath))
111
112        process = target.GetProcess()
113        self.assertTrue(process, PROCESS_IS_VALID)
114        self.assertEqual(process.GetProcessID(), 42)
115        self.assertEqual(process.GetNumThreads(), 1)
116
117        thread = process.GetSelectedThread()
118        self.assertTrue(thread, "Invalid thread.")
119        self.assertEqual(thread.GetThreadID(), 0x19)
120        self.assertEqual(thread.GetName(), "MyScriptedThread.thread-1")
121
122        self.assertEqual(thread.GetNumFrames(), 4)
123        frame = thread.GetSelectedFrame()
124        self.assertTrue(frame, "Invalid frame.")
125        self.assertEqual(frame.GetFunctionName(), "bar")
126        self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42)
127        self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42)
128