1f3176f5fSMed Ismail Bennani""" 2f3176f5fSMed Ismail BennaniTest python scripted process in lldb 3f3176f5fSMed Ismail Bennani""" 4f3176f5fSMed Ismail Bennani 5976867b5SMed 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 44976867b5SMed 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 54312b43daSMed Ismail Bennani os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1' 55*419b4711SMed Ismail Bennani def cleanup(): 56*419b4711SMed Ismail Bennani del os.environ["SKIP_SCRIPTED_PROCESS_LAUNCH"] 57*419b4711SMed Ismail Bennani self.addTearDownHook(cleanup) 58*419b4711SMed Ismail Bennani 59*419b4711SMed Ismail Bennani scripted_process_example_relpath = 'dummy_scripted_process.py' 60312b43daSMed Ismail Bennani self.runCmd("command script import " + os.path.join(self.getSourceDir(), 61a758c9f7SMed Ismail Bennani scripted_process_example_relpath)) 62312b43daSMed Ismail Bennani 63312b43daSMed Ismail Bennani launch_info = lldb.SBLaunchInfo(None) 64312b43daSMed Ismail Bennani launch_info.SetProcessPluginName("ScriptedProcess") 65a758c9f7SMed Ismail Bennani launch_info.SetScriptedProcessClassName("dummy_scripted_process.DummyScriptedProcess") 66312b43daSMed Ismail Bennani 67312b43daSMed Ismail Bennani error = lldb.SBError() 68312b43daSMed Ismail Bennani process = target.Launch(launch_info, error) 69312b43daSMed Ismail Bennani self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID) 70312b43daSMed Ismail Bennani self.assertEqual(process.GetProcessID(), 42) 71312b43daSMed Ismail Bennani 7259d8dd79SMed Ismail Bennani self.assertEqual(process.GetNumThreads(), 1) 7359d8dd79SMed Ismail Bennani 7459d8dd79SMed Ismail Bennani thread = process.GetSelectedThread() 7559d8dd79SMed Ismail Bennani self.assertTrue(thread, "Invalid thread.") 7659d8dd79SMed Ismail Bennani self.assertEqual(thread.GetThreadID(), 0x19) 77a758c9f7SMed Ismail Bennani self.assertEqual(thread.GetName(), "DummyScriptedThread.thread-1") 7859d8dd79SMed Ismail Bennani self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) 7959d8dd79SMed Ismail Bennani 8059d8dd79SMed Ismail Bennani self.assertGreater(thread.GetNumFrames(), 0) 8159d8dd79SMed Ismail Bennani 8259d8dd79SMed Ismail Bennani frame = thread.GetFrameAtIndex(0) 83976867b5SMed Ismail Bennani GPRs = None 8459d8dd79SMed Ismail Bennani register_set = frame.registers # Returns an SBValueList. 8559d8dd79SMed Ismail Bennani for regs in register_set: 86976867b5SMed Ismail Bennani if 'general purpose' in regs.name.lower(): 87976867b5SMed Ismail Bennani GPRs = regs 8859d8dd79SMed Ismail Bennani break 8959d8dd79SMed Ismail Bennani 90976867b5SMed Ismail Bennani self.assertTrue(GPRs, "Invalid General Purpose Registers Set") 91976867b5SMed Ismail Bennani self.assertEqual(GPRs.GetNumChildren(), 21) 92976867b5SMed Ismail Bennani for idx, reg in enumerate(GPRs, start=1): 9359d8dd79SMed Ismail Bennani self.assertEqual(idx, int(reg.value, 16)) 9459d8dd79SMed Ismail Bennani 95976867b5SMed Ismail Bennani def create_stack_skinny_corefile(self, file): 96976867b5SMed Ismail Bennani self.build() 97976867b5SMed Ismail Bennani target, process, thread, _ = lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.c")) 98976867b5SMed Ismail Bennani self.assertTrue(process.IsValid(), "Process is invalid.") 99976867b5SMed Ismail Bennani # FIXME: Use SBAPI to save the process corefile. 100976867b5SMed Ismail Bennani self.runCmd("process save-core -s stack " + file) 101976867b5SMed Ismail Bennani self.assertTrue(os.path.exists(file), "No stack-only corefile found.") 102976867b5SMed Ismail Bennani self.assertTrue(self.dbg.DeleteTarget(target), "Couldn't delete target") 103976867b5SMed Ismail Bennani 104815c87fbSMed Ismail Bennani @skipUnlessDarwin 105*419b4711SMed Ismail Bennani @skipIfOutOfTreeDebugserver 106976867b5SMed Ismail Bennani @skipIf(archs=no_match(['x86_64'])) 107a758c9f7SMed Ismail Bennani def test_launch_scripted_process_stack_frames(self): 108312b43daSMed Ismail Bennani """Test that we can launch an lldb scripted process from the command 109312b43daSMed Ismail Bennani line, check its process ID and read string from memory.""" 110312b43daSMed Ismail Bennani self.build() 111312b43daSMed Ismail Bennani target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 112312b43daSMed Ismail Bennani self.assertTrue(target, VALID_TARGET) 113312b43daSMed Ismail Bennani 114a758c9f7SMed Ismail Bennani for module in target.modules: 115a758c9f7SMed Ismail Bennani if 'a.out' in module.GetFileSpec().GetFilename(): 116a758c9f7SMed Ismail Bennani main_module = module 117976867b5SMed Ismail Bennani break 118a758c9f7SMed Ismail Bennani 119a758c9f7SMed Ismail Bennani self.assertTrue(main_module, "Invalid main module.") 120a758c9f7SMed Ismail Bennani error = target.SetModuleLoadAddress(main_module, 0) 121a758c9f7SMed Ismail Bennani self.assertTrue(error.Success(), "Reloading main module at offset 0 failed.") 122a758c9f7SMed Ismail Bennani 123976867b5SMed Ismail Bennani os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1' 124*419b4711SMed Ismail Bennani def cleanup(): 125*419b4711SMed Ismail Bennani del os.environ["SKIP_SCRIPTED_PROCESS_LAUNCH"] 126*419b4711SMed Ismail Bennani self.addTearDownHook(cleanup) 127*419b4711SMed Ismail Bennani 128*419b4711SMed Ismail Bennani scripted_process_example_relpath = 'stack_core_scripted_process.py' 129312b43daSMed Ismail Bennani self.runCmd("command script import " + os.path.join(self.getSourceDir(), 130976867b5SMed Ismail Bennani scripted_process_example_relpath)) 131312b43daSMed Ismail Bennani 132976867b5SMed Ismail Bennani corefile_process = None 133976867b5SMed Ismail Bennani with tempfile.NamedTemporaryFile() as file: 134976867b5SMed Ismail Bennani self.create_stack_skinny_corefile(file.name) 135976867b5SMed Ismail Bennani corefile_target = self.dbg.CreateTarget(None) 136976867b5SMed Ismail Bennani corefile_process = corefile_target.LoadCore(self.getBuildArtifact(file.name)) 137976867b5SMed Ismail Bennani self.assertTrue(corefile_process, PROCESS_IS_VALID) 138976867b5SMed Ismail Bennani 139976867b5SMed Ismail Bennani structured_data = lldb.SBStructuredData() 140976867b5SMed Ismail Bennani structured_data.SetFromJSON(json.dumps({ 141976867b5SMed Ismail Bennani "backing_target_idx" : self.dbg.GetIndexOfTarget(corefile_process.GetTarget()) 142976867b5SMed Ismail Bennani })) 143976867b5SMed Ismail Bennani launch_info = lldb.SBLaunchInfo(None) 144976867b5SMed Ismail Bennani launch_info.SetProcessPluginName("ScriptedProcess") 145976867b5SMed Ismail Bennani launch_info.SetScriptedProcessClassName("stack_core_scripted_process.StackCoreScriptedProcess") 146976867b5SMed Ismail Bennani launch_info.SetScriptedProcessDictionary(structured_data) 147976867b5SMed Ismail Bennani 148976867b5SMed Ismail Bennani error = lldb.SBError() 149976867b5SMed Ismail Bennani process = target.Launch(launch_info, error) 150976867b5SMed Ismail Bennani self.assertTrue(error.Success(), error.GetCString()) 151312b43daSMed Ismail Bennani self.assertTrue(process, PROCESS_IS_VALID) 152312b43daSMed Ismail Bennani self.assertEqual(process.GetProcessID(), 42) 153312b43daSMed Ismail Bennani 154976867b5SMed Ismail Bennani self.assertEqual(process.GetNumThreads(), 1) 155a758c9f7SMed Ismail Bennani thread = process.GetSelectedThread() 156a758c9f7SMed Ismail Bennani self.assertTrue(thread, "Invalid thread.") 157976867b5SMed Ismail Bennani self.assertEqual(thread.GetName(), "StackCoreScriptedThread.thread-1") 158312b43daSMed Ismail Bennani 159976867b5SMed Ismail Bennani self.assertEqual(thread.GetNumFrames(), 3) 160a758c9f7SMed Ismail Bennani frame = thread.GetSelectedFrame() 161a758c9f7SMed Ismail Bennani self.assertTrue(frame, "Invalid frame.") 162a758c9f7SMed Ismail Bennani self.assertEqual(frame.GetFunctionName(), "bar") 163a758c9f7SMed Ismail Bennani self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42) 164a758c9f7SMed Ismail Bennani self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42) 165