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 def setUp(self): 18f3176f5fSMed Ismail Bennani TestBase.setUp(self) 19f3176f5fSMed Ismail Bennani 20f3176f5fSMed Ismail Bennani def tearDown(self): 21f3176f5fSMed Ismail Bennani TestBase.tearDown(self) 22f3176f5fSMed Ismail Bennani 23f3176f5fSMed Ismail Bennani def test_python_plugin_package(self): 24f3176f5fSMed Ismail Bennani """Test that the lldb python module has a `plugins.scripted_process` 25f3176f5fSMed Ismail Bennani package.""" 26f3176f5fSMed Ismail Bennani self.expect('script import lldb.plugins', 27f3176f5fSMed Ismail Bennani substrs=["ModuleNotFoundError"], matching=False) 28f3176f5fSMed Ismail Bennani 29f3176f5fSMed Ismail Bennani self.expect('script dir(lldb.plugins)', 30f3176f5fSMed Ismail Bennani substrs=["scripted_process"]) 31f3176f5fSMed Ismail Bennani 32f3176f5fSMed Ismail Bennani self.expect('script import lldb.plugins.scripted_process', 33f3176f5fSMed Ismail Bennani substrs=["ModuleNotFoundError"], matching=False) 34f3176f5fSMed Ismail Bennani 35f3176f5fSMed Ismail Bennani self.expect('script dir(lldb.plugins.scripted_process)', 36f3176f5fSMed Ismail Bennani substrs=["ScriptedProcess"]) 37f3176f5fSMed Ismail Bennani 38f3176f5fSMed Ismail Bennani self.expect('script from lldb.plugins.scripted_process import ScriptedProcess', 39f3176f5fSMed Ismail Bennani substrs=["ImportError"], matching=False) 40f3176f5fSMed Ismail Bennani 41f3176f5fSMed Ismail Bennani self.expect('script dir(ScriptedProcess)', 42f3176f5fSMed Ismail Bennani substrs=["launch"]) 43f3176f5fSMed Ismail Bennani 44*6aa48034SMed Ismail Bennani def move_blueprint_to_dsym(self, blueprint_name): 45*6aa48034SMed Ismail Bennani blueprint_origin_path = os.path.join(self.getSourceDir(), blueprint_name) 46*6aa48034SMed Ismail Bennani dsym_bundle = self.getBuildArtifact("a.out.dSYM") 47*6aa48034SMed Ismail Bennani blueprint_destination_path = os.path.join(dsym_bundle, "Contents", 48*6aa48034SMed Ismail Bennani "Resources", "Python") 49*6aa48034SMed Ismail Bennani if not os.path.exists(blueprint_destination_path): 50*6aa48034SMed Ismail Bennani os.mkdir(blueprint_destination_path) 51*6aa48034SMed Ismail Bennani 52*6aa48034SMed Ismail Bennani blueprint_destination_path = os.path.join(blueprint_destination_path, "a_out.py") 53*6aa48034SMed Ismail Bennani shutil.copy(blueprint_origin_path, blueprint_destination_path) 54*6aa48034SMed Ismail Bennani 55c3ca2c6bSMed Ismail Bennani @skipUnlessDarwin 56caea440aSMed Ismail Bennani def test_invalid_scripted_register_context(self): 57caea440aSMed Ismail Bennani """Test that we can launch an lldb scripted process with an invalid 58caea440aSMed Ismail Bennani Scripted Thread, with invalid register context.""" 59caea440aSMed Ismail Bennani self.build() 60caea440aSMed Ismail Bennani 61caea440aSMed Ismail Bennani os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1' 62a6b56243SMed Ismail Bennani def cleanup(): 63a6b56243SMed Ismail Bennani del os.environ["SKIP_SCRIPTED_PROCESS_LAUNCH"] 64a6b56243SMed Ismail Bennani self.addTearDownHook(cleanup) 65a6b56243SMed Ismail Bennani 66*6aa48034SMed Ismail Bennani self.runCmd("settings set target.load-script-from-symbol-file true") 67*6aa48034SMed Ismail Bennani self.move_blueprint_to_dsym('invalid_scripted_process.py') 68*6aa48034SMed Ismail Bennani target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 69*6aa48034SMed Ismail Bennani self.assertTrue(target, VALID_TARGET) 70*6aa48034SMed Ismail Bennani log_file = self.getBuildArtifact('thread.log') 71*6aa48034SMed Ismail Bennani self.runCmd("log enable lldb thread -f " + log_file) 72*6aa48034SMed Ismail Bennani self.assertTrue(os.path.isfile(log_file)) 73caea440aSMed Ismail Bennani 74caea440aSMed Ismail Bennani launch_info = lldb.SBLaunchInfo(None) 75caea440aSMed Ismail Bennani launch_info.SetProcessPluginName("ScriptedProcess") 76*6aa48034SMed Ismail Bennani launch_info.SetScriptedProcessClassName("a_out.InvalidScriptedProcess") 77caea440aSMed Ismail Bennani error = lldb.SBError() 789c144b3bSMed Ismail Bennani 79caea440aSMed Ismail Bennani process = target.Launch(launch_info, error) 80caea440aSMed Ismail Bennani 81779bbbf2SDave Lee self.assertSuccess(error) 82caea440aSMed Ismail Bennani self.assertTrue(process, PROCESS_IS_VALID) 83caea440aSMed Ismail Bennani self.assertEqual(process.GetProcessID(), 666) 84caea440aSMed Ismail Bennani self.assertEqual(process.GetNumThreads(), 0) 85caea440aSMed Ismail Bennani 869c144b3bSMed Ismail Bennani with open(log_file, 'r') as f: 879c144b3bSMed Ismail Bennani log = f.read() 889c144b3bSMed Ismail Bennani 899c144b3bSMed Ismail Bennani self.assertIn("Failed to get scripted thread registers data.", log) 90caea440aSMed Ismail Bennani 9186e6030eSMed Ismail Bennani @skipUnlessDarwin 92a758c9f7SMed Ismail Bennani def test_scripted_process_and_scripted_thread(self): 93312b43daSMed Ismail Bennani """Test that we can launch an lldb scripted process using the SBAPI, 94a758c9f7SMed Ismail Bennani check its process ID, read string from memory, check scripted thread 95a758c9f7SMed Ismail Bennani id, name stop reason and register context. 96a758c9f7SMed Ismail Bennani """ 97312b43daSMed Ismail Bennani self.build() 98312b43daSMed Ismail Bennani target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 99312b43daSMed Ismail Bennani self.assertTrue(target, VALID_TARGET) 100312b43daSMed Ismail Bennani 101312b43daSMed Ismail Bennani os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1' 102a6b56243SMed Ismail Bennani def cleanup(): 103a6b56243SMed Ismail Bennani del os.environ["SKIP_SCRIPTED_PROCESS_LAUNCH"] 104a6b56243SMed Ismail Bennani self.addTearDownHook(cleanup) 105a6b56243SMed Ismail Bennani 106419b4711SMed Ismail Bennani scripted_process_example_relpath = 'dummy_scripted_process.py' 107312b43daSMed Ismail Bennani self.runCmd("command script import " + os.path.join(self.getSourceDir(), 108a758c9f7SMed Ismail Bennani scripted_process_example_relpath)) 109312b43daSMed Ismail Bennani 110312b43daSMed Ismail Bennani launch_info = lldb.SBLaunchInfo(None) 111312b43daSMed Ismail Bennani launch_info.SetProcessPluginName("ScriptedProcess") 112a758c9f7SMed Ismail Bennani launch_info.SetScriptedProcessClassName("dummy_scripted_process.DummyScriptedProcess") 113312b43daSMed Ismail Bennani 114312b43daSMed Ismail Bennani error = lldb.SBError() 115312b43daSMed Ismail Bennani process = target.Launch(launch_info, error) 116312b43daSMed Ismail Bennani self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID) 117312b43daSMed Ismail Bennani self.assertEqual(process.GetProcessID(), 42) 118312b43daSMed Ismail Bennani 11959d8dd79SMed Ismail Bennani self.assertEqual(process.GetNumThreads(), 1) 12059d8dd79SMed Ismail Bennani 12159d8dd79SMed Ismail Bennani thread = process.GetSelectedThread() 12259d8dd79SMed Ismail Bennani self.assertTrue(thread, "Invalid thread.") 12359d8dd79SMed Ismail Bennani self.assertEqual(thread.GetThreadID(), 0x19) 124a758c9f7SMed Ismail Bennani self.assertEqual(thread.GetName(), "DummyScriptedThread.thread-1") 12559d8dd79SMed Ismail Bennani self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) 12659d8dd79SMed Ismail Bennani 12759d8dd79SMed Ismail Bennani self.assertGreater(thread.GetNumFrames(), 0) 12859d8dd79SMed Ismail Bennani 12959d8dd79SMed Ismail Bennani frame = thread.GetFrameAtIndex(0) 130976867b5SMed Ismail Bennani GPRs = None 13159d8dd79SMed Ismail Bennani register_set = frame.registers # Returns an SBValueList. 13259d8dd79SMed Ismail Bennani for regs in register_set: 133976867b5SMed Ismail Bennani if 'general purpose' in regs.name.lower(): 134976867b5SMed Ismail Bennani GPRs = regs 13559d8dd79SMed Ismail Bennani break 13659d8dd79SMed Ismail Bennani 137976867b5SMed Ismail Bennani self.assertTrue(GPRs, "Invalid General Purpose Registers Set") 138c3ca2c6bSMed Ismail Bennani self.assertGreater(GPRs.GetNumChildren(), 0) 139976867b5SMed Ismail Bennani for idx, reg in enumerate(GPRs, start=1): 140c3ca2c6bSMed Ismail Bennani if idx > 21: 141c3ca2c6bSMed Ismail Bennani break 14259d8dd79SMed Ismail Bennani self.assertEqual(idx, int(reg.value, 16)) 14359d8dd79SMed Ismail Bennani 14470665844SMed Ismail Bennani self.assertTrue(frame.IsArtificial(), "Frame is not artificial") 14570665844SMed Ismail Bennani pc = frame.GetPCAddress().GetLoadAddress(target) 14670665844SMed Ismail Bennani self.assertEqual(pc, 0x0100001b00) 147