xref: /llvm-project/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py (revision 815c87fbe20a66d28e4d09af89a39cb39270dcf0)
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    @skipUnlessDarwin
92    def test_launch_scripted_process_stack_frames(self):
93        """Test that we can launch an lldb scripted process from the command
94        line, check its process ID and read string from memory."""
95        self.build()
96        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
97        self.assertTrue(target, VALID_TARGET)
98
99        for module in target.modules:
100            if 'a.out' in module.GetFileSpec().GetFilename():
101                main_module = module
102
103        self.assertTrue(main_module, "Invalid main module.")
104        error = target.SetModuleLoadAddress(main_module, 0)
105        self.assertTrue(error.Success(), "Reloading main module at offset 0 failed.")
106
107        scripted_process_example_relpath = ['..','..','..','..','examples','python','scripted_process','my_scripted_process.py']
108        self.runCmd("command script import " + os.path.join(self.getSourceDir(),
109                                                            *scripted_process_example_relpath))
110
111        process = target.GetProcess()
112        self.assertTrue(process, PROCESS_IS_VALID)
113        self.assertEqual(process.GetProcessID(), 42)
114        self.assertEqual(process.GetNumThreads(), 1)
115
116        error = lldb.SBError()
117        hello_world = "Hello, world!"
118        memory_read = process.ReadCStringFromMemory(0x50000000000,
119                                                    len(hello_world) + 1, # NULL byte
120                                                    error)
121        thread = process.GetSelectedThread()
122        self.assertTrue(thread, "Invalid thread.")
123        self.assertEqual(thread.GetThreadID(), 0x19)
124        self.assertEqual(thread.GetName(), "MyScriptedThread.thread-1")
125
126        self.assertEqual(thread.GetNumFrames(), 4)
127        frame = thread.GetSelectedFrame()
128        self.assertTrue(frame, "Invalid frame.")
129        self.assertEqual(frame.GetFunctionName(), "bar")
130        self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42)
131        self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42)
132