1f3176f5fSMed Ismail Bennani""" 2f3176f5fSMed Ismail BennaniTest python scripted process in lldb 3f3176f5fSMed Ismail Bennani""" 4f3176f5fSMed Ismail Bennani 5*976867b5SMed Ismail Bennaniimport os, json, tempfile 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 15f3176f5fSMed Ismail Bennani mydir = TestBase.compute_mydir(__file__) 16f3176f5fSMed 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*976867b5SMed Ismail Bennani @skipIf(archs=no_match(['x86_64'])) 45a758c9f7SMed Ismail Bennani def test_scripted_process_and_scripted_thread(self): 46312b43daSMed Ismail Bennani """Test that we can launch an lldb scripted process using the SBAPI, 47a758c9f7SMed Ismail Bennani check its process ID, read string from memory, check scripted thread 48a758c9f7SMed Ismail Bennani id, name stop reason and register context. 49a758c9f7SMed Ismail Bennani """ 50312b43daSMed Ismail Bennani self.build() 51312b43daSMed Ismail Bennani target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 52312b43daSMed Ismail Bennani self.assertTrue(target, VALID_TARGET) 53312b43daSMed Ismail Bennani 54a758c9f7SMed Ismail Bennani scripted_process_example_relpath = 'dummy_scripted_process.py' 55312b43daSMed Ismail Bennani os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1' 56312b43daSMed Ismail Bennani self.runCmd("command script import " + os.path.join(self.getSourceDir(), 57a758c9f7SMed Ismail Bennani scripted_process_example_relpath)) 58312b43daSMed Ismail Bennani 59312b43daSMed Ismail Bennani launch_info = lldb.SBLaunchInfo(None) 60312b43daSMed Ismail Bennani launch_info.SetProcessPluginName("ScriptedProcess") 61a758c9f7SMed Ismail Bennani launch_info.SetScriptedProcessClassName("dummy_scripted_process.DummyScriptedProcess") 62312b43daSMed Ismail Bennani 63312b43daSMed Ismail Bennani error = lldb.SBError() 64312b43daSMed Ismail Bennani process = target.Launch(launch_info, error) 65312b43daSMed Ismail Bennani self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID) 66312b43daSMed Ismail Bennani self.assertEqual(process.GetProcessID(), 42) 67312b43daSMed Ismail Bennani 6859d8dd79SMed Ismail Bennani self.assertEqual(process.GetNumThreads(), 1) 6959d8dd79SMed Ismail Bennani 7059d8dd79SMed Ismail Bennani thread = process.GetSelectedThread() 7159d8dd79SMed Ismail Bennani self.assertTrue(thread, "Invalid thread.") 7259d8dd79SMed Ismail Bennani self.assertEqual(thread.GetThreadID(), 0x19) 73a758c9f7SMed Ismail Bennani self.assertEqual(thread.GetName(), "DummyScriptedThread.thread-1") 7459d8dd79SMed Ismail Bennani self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) 7559d8dd79SMed Ismail Bennani 7659d8dd79SMed Ismail Bennani self.assertGreater(thread.GetNumFrames(), 0) 7759d8dd79SMed Ismail Bennani 7859d8dd79SMed Ismail Bennani frame = thread.GetFrameAtIndex(0) 79*976867b5SMed Ismail Bennani GPRs = None 8059d8dd79SMed Ismail Bennani register_set = frame.registers # Returns an SBValueList. 8159d8dd79SMed Ismail Bennani for regs in register_set: 82*976867b5SMed Ismail Bennani if 'general purpose' in regs.name.lower(): 83*976867b5SMed Ismail Bennani GPRs = regs 8459d8dd79SMed Ismail Bennani break 8559d8dd79SMed Ismail Bennani 86*976867b5SMed Ismail Bennani self.assertTrue(GPRs, "Invalid General Purpose Registers Set") 87*976867b5SMed Ismail Bennani self.assertEqual(GPRs.GetNumChildren(), 21) 88*976867b5SMed Ismail Bennani for idx, reg in enumerate(GPRs, start=1): 8959d8dd79SMed Ismail Bennani self.assertEqual(idx, int(reg.value, 16)) 9059d8dd79SMed Ismail Bennani 91*976867b5SMed Ismail Bennani def create_stack_skinny_corefile(self, file): 92*976867b5SMed Ismail Bennani self.build() 93*976867b5SMed Ismail Bennani target, process, thread, _ = lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.c")) 94*976867b5SMed Ismail Bennani self.assertTrue(process.IsValid(), "Process is invalid.") 95*976867b5SMed Ismail Bennani # FIXME: Use SBAPI to save the process corefile. 96*976867b5SMed Ismail Bennani self.runCmd("process save-core -s stack " + file) 97*976867b5SMed Ismail Bennani self.assertTrue(os.path.exists(file), "No stack-only corefile found.") 98*976867b5SMed Ismail Bennani self.assertTrue(self.dbg.DeleteTarget(target), "Couldn't delete target") 99*976867b5SMed Ismail Bennani 100815c87fbSMed Ismail Bennani @skipUnlessDarwin 101*976867b5SMed Ismail Bennani @skipIf(archs=no_match(['x86_64'])) 102a758c9f7SMed Ismail Bennani def test_launch_scripted_process_stack_frames(self): 103312b43daSMed Ismail Bennani """Test that we can launch an lldb scripted process from the command 104312b43daSMed Ismail Bennani line, check its process ID and read string from memory.""" 105312b43daSMed Ismail Bennani self.build() 106312b43daSMed Ismail Bennani target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 107312b43daSMed Ismail Bennani self.assertTrue(target, VALID_TARGET) 108312b43daSMed Ismail Bennani 109a758c9f7SMed Ismail Bennani for module in target.modules: 110a758c9f7SMed Ismail Bennani if 'a.out' in module.GetFileSpec().GetFilename(): 111a758c9f7SMed Ismail Bennani main_module = module 112*976867b5SMed Ismail Bennani break 113a758c9f7SMed Ismail Bennani 114a758c9f7SMed Ismail Bennani self.assertTrue(main_module, "Invalid main module.") 115a758c9f7SMed Ismail Bennani error = target.SetModuleLoadAddress(main_module, 0) 116a758c9f7SMed Ismail Bennani self.assertTrue(error.Success(), "Reloading main module at offset 0 failed.") 117a758c9f7SMed Ismail Bennani 118*976867b5SMed Ismail Bennani scripted_process_example_relpath = 'stack_core_scripted_process.py' 119*976867b5SMed Ismail Bennani os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1' 120312b43daSMed Ismail Bennani self.runCmd("command script import " + os.path.join(self.getSourceDir(), 121*976867b5SMed Ismail Bennani scripted_process_example_relpath)) 122312b43daSMed Ismail Bennani 123*976867b5SMed Ismail Bennani corefile_process = None 124*976867b5SMed Ismail Bennani with tempfile.NamedTemporaryFile() as file: 125*976867b5SMed Ismail Bennani self.create_stack_skinny_corefile(file.name) 126*976867b5SMed Ismail Bennani corefile_target = self.dbg.CreateTarget(None) 127*976867b5SMed Ismail Bennani corefile_process = corefile_target.LoadCore(self.getBuildArtifact(file.name)) 128*976867b5SMed Ismail Bennani self.assertTrue(corefile_process, PROCESS_IS_VALID) 129*976867b5SMed Ismail Bennani 130*976867b5SMed Ismail Bennani structured_data = lldb.SBStructuredData() 131*976867b5SMed Ismail Bennani structured_data.SetFromJSON(json.dumps({ 132*976867b5SMed Ismail Bennani "backing_target_idx" : self.dbg.GetIndexOfTarget(corefile_process.GetTarget()) 133*976867b5SMed Ismail Bennani })) 134*976867b5SMed Ismail Bennani launch_info = lldb.SBLaunchInfo(None) 135*976867b5SMed Ismail Bennani launch_info.SetProcessPluginName("ScriptedProcess") 136*976867b5SMed Ismail Bennani launch_info.SetScriptedProcessClassName("stack_core_scripted_process.StackCoreScriptedProcess") 137*976867b5SMed Ismail Bennani launch_info.SetScriptedProcessDictionary(structured_data) 138*976867b5SMed Ismail Bennani 139*976867b5SMed Ismail Bennani error = lldb.SBError() 140*976867b5SMed Ismail Bennani process = target.Launch(launch_info, error) 141*976867b5SMed Ismail Bennani self.assertTrue(error.Success(), error.GetCString()) 142312b43daSMed Ismail Bennani self.assertTrue(process, PROCESS_IS_VALID) 143312b43daSMed Ismail Bennani self.assertEqual(process.GetProcessID(), 42) 144312b43daSMed Ismail Bennani 145*976867b5SMed Ismail Bennani self.assertEqual(process.GetNumThreads(), 1) 146a758c9f7SMed Ismail Bennani thread = process.GetSelectedThread() 147a758c9f7SMed Ismail Bennani self.assertTrue(thread, "Invalid thread.") 148*976867b5SMed Ismail Bennani self.assertEqual(thread.GetName(), "StackCoreScriptedThread.thread-1") 149312b43daSMed Ismail Bennani 150*976867b5SMed Ismail Bennani self.assertEqual(thread.GetNumFrames(), 3) 151a758c9f7SMed Ismail Bennani frame = thread.GetSelectedFrame() 152a758c9f7SMed Ismail Bennani self.assertTrue(frame, "Invalid frame.") 153a758c9f7SMed Ismail Bennani self.assertEqual(frame.GetFunctionName(), "bar") 154a758c9f7SMed Ismail Bennani self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42) 155a758c9f7SMed Ismail Bennani self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42) 156