1f3176f5fSMed Ismail Bennani"""
2f3176f5fSMed Ismail BennaniTest python scripted process in lldb
3f3176f5fSMed Ismail Bennani"""
4f3176f5fSMed Ismail Bennani
5f3176f5fSMed Ismail Bennaniimport os
6f3176f5fSMed Ismail Bennani
7f3176f5fSMed Ismail Bennaniimport lldb
8f3176f5fSMed Ismail Bennanifrom lldbsuite.test.decorators import *
9f3176f5fSMed Ismail Bennanifrom lldbsuite.test.lldbtest import *
10f3176f5fSMed Ismail Bennanifrom lldbsuite.test import lldbutil
11f3176f5fSMed Ismail Bennanifrom lldbsuite.test import lldbtest
12f3176f5fSMed Ismail Bennani
13f3176f5fSMed Ismail Bennani
14312b43daSMed Ismail Bennaniclass ScriptedProcesTestCase(TestBase):
15f3176f5fSMed Ismail Bennani
16f3176f5fSMed Ismail Bennani    mydir = TestBase.compute_mydir(__file__)
17f3176f5fSMed Ismail Bennani
18f3176f5fSMed Ismail Bennani    def setUp(self):
19f3176f5fSMed Ismail Bennani        TestBase.setUp(self)
20f3176f5fSMed Ismail Bennani        self.source = "main.c"
21f3176f5fSMed Ismail Bennani
22f3176f5fSMed Ismail Bennani    def tearDown(self):
23f3176f5fSMed Ismail Bennani        TestBase.tearDown(self)
24f3176f5fSMed Ismail Bennani
25f3176f5fSMed Ismail Bennani    def test_python_plugin_package(self):
26f3176f5fSMed Ismail Bennani        """Test that the lldb python module has a `plugins.scripted_process`
27f3176f5fSMed Ismail Bennani        package."""
28f3176f5fSMed Ismail Bennani        self.expect('script import lldb.plugins',
29f3176f5fSMed Ismail Bennani                    substrs=["ModuleNotFoundError"], matching=False)
30f3176f5fSMed Ismail Bennani
31f3176f5fSMed Ismail Bennani        self.expect('script dir(lldb.plugins)',
32f3176f5fSMed Ismail Bennani                    substrs=["scripted_process"])
33f3176f5fSMed Ismail Bennani
34f3176f5fSMed Ismail Bennani        self.expect('script import lldb.plugins.scripted_process',
35f3176f5fSMed Ismail Bennani                    substrs=["ModuleNotFoundError"], matching=False)
36f3176f5fSMed Ismail Bennani
37f3176f5fSMed Ismail Bennani        self.expect('script dir(lldb.plugins.scripted_process)',
38f3176f5fSMed Ismail Bennani                    substrs=["ScriptedProcess"])
39f3176f5fSMed Ismail Bennani
40f3176f5fSMed Ismail Bennani        self.expect('script from lldb.plugins.scripted_process import ScriptedProcess',
41f3176f5fSMed Ismail Bennani                    substrs=["ImportError"], matching=False)
42f3176f5fSMed Ismail Bennani
43f3176f5fSMed Ismail Bennani        self.expect('script dir(ScriptedProcess)',
44f3176f5fSMed Ismail Bennani                    substrs=["launch"])
45f3176f5fSMed Ismail Bennani
46a758c9f7SMed Ismail Bennani    def test_scripted_process_and_scripted_thread(self):
47312b43daSMed Ismail Bennani        """Test that we can launch an lldb scripted process using the SBAPI,
48a758c9f7SMed Ismail Bennani        check its process ID, read string from memory, check scripted thread
49a758c9f7SMed Ismail Bennani        id, name stop reason and register context.
50a758c9f7SMed Ismail Bennani        """
51312b43daSMed Ismail Bennani        self.build()
52312b43daSMed Ismail Bennani        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
53312b43daSMed Ismail Bennani        self.assertTrue(target, VALID_TARGET)
54312b43daSMed Ismail Bennani
55a758c9f7SMed Ismail Bennani        scripted_process_example_relpath = 'dummy_scripted_process.py'
56312b43daSMed Ismail Bennani        os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1'
57312b43daSMed Ismail Bennani        self.runCmd("command script import " + os.path.join(self.getSourceDir(),
58a758c9f7SMed Ismail Bennani                                                            scripted_process_example_relpath))
59312b43daSMed Ismail Bennani
60312b43daSMed Ismail Bennani        launch_info = lldb.SBLaunchInfo(None)
61312b43daSMed Ismail Bennani        launch_info.SetProcessPluginName("ScriptedProcess")
62a758c9f7SMed Ismail Bennani        launch_info.SetScriptedProcessClassName("dummy_scripted_process.DummyScriptedProcess")
63312b43daSMed Ismail Bennani
64312b43daSMed Ismail Bennani        error = lldb.SBError()
65312b43daSMed Ismail Bennani        process = target.Launch(launch_info, error)
66312b43daSMed Ismail Bennani        self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
67312b43daSMed Ismail Bennani        self.assertEqual(process.GetProcessID(), 42)
68312b43daSMed Ismail Bennani
6959d8dd79SMed Ismail Bennani        self.assertEqual(process.GetNumThreads(), 1)
7059d8dd79SMed Ismail Bennani
7159d8dd79SMed Ismail Bennani        thread = process.GetSelectedThread()
7259d8dd79SMed Ismail Bennani        self.assertTrue(thread, "Invalid thread.")
7359d8dd79SMed Ismail Bennani        self.assertEqual(thread.GetThreadID(), 0x19)
74a758c9f7SMed Ismail Bennani        self.assertEqual(thread.GetName(), "DummyScriptedThread.thread-1")
7559d8dd79SMed Ismail Bennani        self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal)
7659d8dd79SMed Ismail Bennani
7759d8dd79SMed Ismail Bennani        self.assertGreater(thread.GetNumFrames(), 0)
7859d8dd79SMed Ismail Bennani
7959d8dd79SMed Ismail Bennani        frame = thread.GetFrameAtIndex(0)
8059d8dd79SMed Ismail Bennani        register_set = frame.registers # Returns an SBValueList.
8159d8dd79SMed Ismail Bennani        for regs in register_set:
8259d8dd79SMed Ismail Bennani            if 'GPR' in regs.name:
8359d8dd79SMed Ismail Bennani                registers  = regs
8459d8dd79SMed Ismail Bennani                break
8559d8dd79SMed Ismail Bennani
8659d8dd79SMed Ismail Bennani        self.assertTrue(registers, "Invalid General Purpose Registers Set")
8759d8dd79SMed Ismail Bennani        self.assertEqual(registers.GetNumChildren(), 21)
8859d8dd79SMed Ismail Bennani        for idx, reg in enumerate(registers, start=1):
8959d8dd79SMed Ismail Bennani            self.assertEqual(idx, int(reg.value, 16))
9059d8dd79SMed Ismail Bennani
91*815c87fbSMed Ismail Bennani    @skipUnlessDarwin
92a758c9f7SMed Ismail Bennani    def test_launch_scripted_process_stack_frames(self):
93312b43daSMed Ismail Bennani        """Test that we can launch an lldb scripted process from the command
94312b43daSMed Ismail Bennani        line, check its process ID and read string from memory."""
95312b43daSMed Ismail Bennani        self.build()
96312b43daSMed Ismail Bennani        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
97312b43daSMed Ismail Bennani        self.assertTrue(target, VALID_TARGET)
98312b43daSMed Ismail Bennani
99a758c9f7SMed Ismail Bennani        for module in target.modules:
100a758c9f7SMed Ismail Bennani            if 'a.out' in module.GetFileSpec().GetFilename():
101a758c9f7SMed Ismail Bennani                main_module = module
102a758c9f7SMed Ismail Bennani
103a758c9f7SMed Ismail Bennani        self.assertTrue(main_module, "Invalid main module.")
104a758c9f7SMed Ismail Bennani        error = target.SetModuleLoadAddress(main_module, 0)
105a758c9f7SMed Ismail Bennani        self.assertTrue(error.Success(), "Reloading main module at offset 0 failed.")
106a758c9f7SMed Ismail Bennani
107312b43daSMed Ismail Bennani        scripted_process_example_relpath = ['..','..','..','..','examples','python','scripted_process','my_scripted_process.py']
108312b43daSMed Ismail Bennani        self.runCmd("command script import " + os.path.join(self.getSourceDir(),
109312b43daSMed Ismail Bennani                                                            *scripted_process_example_relpath))
110312b43daSMed Ismail Bennani
111312b43daSMed Ismail Bennani        process = target.GetProcess()
112312b43daSMed Ismail Bennani        self.assertTrue(process, PROCESS_IS_VALID)
113312b43daSMed Ismail Bennani        self.assertEqual(process.GetProcessID(), 42)
114a758c9f7SMed Ismail Bennani        self.assertEqual(process.GetNumThreads(), 1)
115312b43daSMed Ismail Bennani
116312b43daSMed Ismail Bennani        error = lldb.SBError()
117312b43daSMed Ismail Bennani        hello_world = "Hello, world!"
118312b43daSMed Ismail Bennani        memory_read = process.ReadCStringFromMemory(0x50000000000,
119312b43daSMed Ismail Bennani                                                    len(hello_world) + 1, # NULL byte
120312b43daSMed Ismail Bennani                                                    error)
121a758c9f7SMed Ismail Bennani        thread = process.GetSelectedThread()
122a758c9f7SMed Ismail Bennani        self.assertTrue(thread, "Invalid thread.")
123a758c9f7SMed Ismail Bennani        self.assertEqual(thread.GetThreadID(), 0x19)
124a758c9f7SMed Ismail Bennani        self.assertEqual(thread.GetName(), "MyScriptedThread.thread-1")
125312b43daSMed Ismail Bennani
126a758c9f7SMed Ismail Bennani        self.assertEqual(thread.GetNumFrames(), 4)
127a758c9f7SMed Ismail Bennani        frame = thread.GetSelectedFrame()
128a758c9f7SMed Ismail Bennani        self.assertTrue(frame, "Invalid frame.")
129a758c9f7SMed Ismail Bennani        self.assertEqual(frame.GetFunctionName(), "bar")
130a758c9f7SMed Ismail Bennani        self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42)
131a758c9f7SMed Ismail Bennani        self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42)
132