1f3176f5fSMed Ismail Bennani""" 2f3176f5fSMed Ismail BennaniTest python scripted process in lldb 3f3176f5fSMed Ismail Bennani""" 4f3176f5fSMed Ismail Bennani 5*6aa48034SMed Ismail Bennaniimport os, shutil 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 13312b43daSMed Ismail Bennaniclass ScriptedProcesTestCase(TestBase): 14f3176f5fSMed Ismail Bennani 15d327108dSMed Ismail Bennani NO_DEBUG_INFO_TESTCASE = True 16d327108dSMed Ismail Bennani 17f3176f5fSMed Ismail Bennani mydir = TestBase.compute_mydir(__file__) 18f3176f5fSMed Ismail Bennani 19f3176f5fSMed Ismail Bennani def setUp(self): 20f3176f5fSMed Ismail Bennani TestBase.setUp(self) 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 46*6aa48034SMed Ismail Bennani def move_blueprint_to_dsym(self, blueprint_name): 47*6aa48034SMed Ismail Bennani blueprint_origin_path = os.path.join(self.getSourceDir(), blueprint_name) 48*6aa48034SMed Ismail Bennani dsym_bundle = self.getBuildArtifact("a.out.dSYM") 49*6aa48034SMed Ismail Bennani blueprint_destination_path = os.path.join(dsym_bundle, "Contents", 50*6aa48034SMed Ismail Bennani "Resources", "Python") 51*6aa48034SMed Ismail Bennani if not os.path.exists(blueprint_destination_path): 52*6aa48034SMed Ismail Bennani os.mkdir(blueprint_destination_path) 53*6aa48034SMed Ismail Bennani 54*6aa48034SMed Ismail Bennani blueprint_destination_path = os.path.join(blueprint_destination_path, "a_out.py") 55*6aa48034SMed Ismail Bennani shutil.copy(blueprint_origin_path, blueprint_destination_path) 56*6aa48034SMed Ismail Bennani 57c3ca2c6bSMed Ismail Bennani @skipUnlessDarwin 58caea440aSMed Ismail Bennani def test_invalid_scripted_register_context(self): 59caea440aSMed Ismail Bennani """Test that we can launch an lldb scripted process with an invalid 60caea440aSMed Ismail Bennani Scripted Thread, with invalid register context.""" 61caea440aSMed Ismail Bennani self.build() 62caea440aSMed Ismail Bennani 63caea440aSMed Ismail Bennani os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1' 64a6b56243SMed Ismail Bennani def cleanup(): 65a6b56243SMed Ismail Bennani del os.environ["SKIP_SCRIPTED_PROCESS_LAUNCH"] 66a6b56243SMed Ismail Bennani self.addTearDownHook(cleanup) 67a6b56243SMed Ismail Bennani 68*6aa48034SMed Ismail Bennani self.runCmd("settings set target.load-script-from-symbol-file true") 69*6aa48034SMed Ismail Bennani self.move_blueprint_to_dsym('invalid_scripted_process.py') 70*6aa48034SMed Ismail Bennani target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 71*6aa48034SMed Ismail Bennani self.assertTrue(target, VALID_TARGET) 72*6aa48034SMed Ismail Bennani log_file = self.getBuildArtifact('thread.log') 73*6aa48034SMed Ismail Bennani self.runCmd("log enable lldb thread -f " + log_file) 74*6aa48034SMed Ismail Bennani self.assertTrue(os.path.isfile(log_file)) 75caea440aSMed Ismail Bennani 76caea440aSMed Ismail Bennani launch_info = lldb.SBLaunchInfo(None) 77caea440aSMed Ismail Bennani launch_info.SetProcessPluginName("ScriptedProcess") 78*6aa48034SMed Ismail Bennani launch_info.SetScriptedProcessClassName("a_out.InvalidScriptedProcess") 79caea440aSMed Ismail Bennani error = lldb.SBError() 809c144b3bSMed Ismail Bennani 81caea440aSMed Ismail Bennani process = target.Launch(launch_info, error) 82caea440aSMed Ismail Bennani 83779bbbf2SDave Lee self.assertSuccess(error) 84caea440aSMed Ismail Bennani self.assertTrue(process, PROCESS_IS_VALID) 85caea440aSMed Ismail Bennani self.assertEqual(process.GetProcessID(), 666) 86caea440aSMed Ismail Bennani self.assertEqual(process.GetNumThreads(), 0) 87caea440aSMed Ismail Bennani 889c144b3bSMed Ismail Bennani with open(log_file, 'r') as f: 899c144b3bSMed Ismail Bennani log = f.read() 909c144b3bSMed Ismail Bennani 919c144b3bSMed Ismail Bennani self.assertIn("Failed to get scripted thread registers data.", log) 92caea440aSMed Ismail Bennani 9386e6030eSMed Ismail Bennani @skipUnlessDarwin 94a758c9f7SMed Ismail Bennani def test_scripted_process_and_scripted_thread(self): 95312b43daSMed Ismail Bennani """Test that we can launch an lldb scripted process using the SBAPI, 96a758c9f7SMed Ismail Bennani check its process ID, read string from memory, check scripted thread 97a758c9f7SMed Ismail Bennani id, name stop reason and register context. 98a758c9f7SMed Ismail Bennani """ 99312b43daSMed Ismail Bennani self.build() 100312b43daSMed Ismail Bennani target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 101312b43daSMed Ismail Bennani self.assertTrue(target, VALID_TARGET) 102312b43daSMed Ismail Bennani 103312b43daSMed Ismail Bennani os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1' 104a6b56243SMed Ismail Bennani def cleanup(): 105a6b56243SMed Ismail Bennani del os.environ["SKIP_SCRIPTED_PROCESS_LAUNCH"] 106a6b56243SMed Ismail Bennani self.addTearDownHook(cleanup) 107a6b56243SMed Ismail Bennani 108419b4711SMed Ismail Bennani scripted_process_example_relpath = 'dummy_scripted_process.py' 109312b43daSMed Ismail Bennani self.runCmd("command script import " + os.path.join(self.getSourceDir(), 110a758c9f7SMed Ismail Bennani scripted_process_example_relpath)) 111312b43daSMed Ismail Bennani 112312b43daSMed Ismail Bennani launch_info = lldb.SBLaunchInfo(None) 113312b43daSMed Ismail Bennani launch_info.SetProcessPluginName("ScriptedProcess") 114a758c9f7SMed Ismail Bennani launch_info.SetScriptedProcessClassName("dummy_scripted_process.DummyScriptedProcess") 115312b43daSMed Ismail Bennani 116312b43daSMed Ismail Bennani error = lldb.SBError() 117312b43daSMed Ismail Bennani process = target.Launch(launch_info, error) 118312b43daSMed Ismail Bennani self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID) 119312b43daSMed Ismail Bennani self.assertEqual(process.GetProcessID(), 42) 120312b43daSMed Ismail Bennani 12159d8dd79SMed Ismail Bennani self.assertEqual(process.GetNumThreads(), 1) 12259d8dd79SMed Ismail Bennani 12359d8dd79SMed Ismail Bennani thread = process.GetSelectedThread() 12459d8dd79SMed Ismail Bennani self.assertTrue(thread, "Invalid thread.") 12559d8dd79SMed Ismail Bennani self.assertEqual(thread.GetThreadID(), 0x19) 126a758c9f7SMed Ismail Bennani self.assertEqual(thread.GetName(), "DummyScriptedThread.thread-1") 12759d8dd79SMed Ismail Bennani self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) 12859d8dd79SMed Ismail Bennani 12959d8dd79SMed Ismail Bennani self.assertGreater(thread.GetNumFrames(), 0) 13059d8dd79SMed Ismail Bennani 13159d8dd79SMed Ismail Bennani frame = thread.GetFrameAtIndex(0) 132976867b5SMed Ismail Bennani GPRs = None 13359d8dd79SMed Ismail Bennani register_set = frame.registers # Returns an SBValueList. 13459d8dd79SMed Ismail Bennani for regs in register_set: 135976867b5SMed Ismail Bennani if 'general purpose' in regs.name.lower(): 136976867b5SMed Ismail Bennani GPRs = regs 13759d8dd79SMed Ismail Bennani break 13859d8dd79SMed Ismail Bennani 139976867b5SMed Ismail Bennani self.assertTrue(GPRs, "Invalid General Purpose Registers Set") 140c3ca2c6bSMed Ismail Bennani self.assertGreater(GPRs.GetNumChildren(), 0) 141976867b5SMed Ismail Bennani for idx, reg in enumerate(GPRs, start=1): 142c3ca2c6bSMed Ismail Bennani if idx > 21: 143c3ca2c6bSMed Ismail Bennani break 14459d8dd79SMed Ismail Bennani self.assertEqual(idx, int(reg.value, 16)) 14559d8dd79SMed Ismail Bennani 14670665844SMed Ismail Bennani self.assertTrue(frame.IsArtificial(), "Frame is not artificial") 14770665844SMed Ismail Bennani pc = frame.GetPCAddress().GetLoadAddress(target) 14870665844SMed Ismail Bennani self.assertEqual(pc, 0x0100001b00) 149