| """ |
| Test saving a mini dump. |
| """ |
| |
| |
| import os |
| import lldb |
| from lldbsuite.test.decorators import * |
| from lldbsuite.test.lldbtest import * |
| from lldbsuite.test import lldbutil |
| |
| |
| class ProcessSaveCoreMinidumpTestCase(TestBase): |
| @skipUnlessArch("x86_64") |
| @skipUnlessPlatform(["linux"]) |
| def test_save_linux_mini_dump(self): |
| """Test that we can save a Linux mini dump.""" |
| self.build() |
| exe = self.getBuildArtifact("a.out") |
| core = self.getBuildArtifact("core.dmp") |
| core_sb = self.getBuildArtifact("core_sb.dmp") |
| try: |
| target = self.dbg.CreateTarget(exe) |
| process = target.LaunchSimple( |
| None, None, self.get_process_working_directory() |
| ) |
| self.assertState(process.GetState(), lldb.eStateStopped) |
| |
| # get neccessary data for the verification phase |
| process_info = process.GetProcessInfo() |
| expected_pid = process_info.GetProcessID() if process_info.IsValid() else -1 |
| expected_number_of_modules = target.GetNumModules() |
| expected_modules = target.modules |
| expected_number_of_threads = process.GetNumThreads() |
| expected_threads = [] |
| |
| for thread_idx in range(process.GetNumThreads()): |
| thread = process.GetThreadAtIndex(thread_idx) |
| thread_id = thread.GetThreadID() |
| expected_threads.append(thread_id) |
| |
| # save core and, kill process and verify corefile existence |
| self.runCmd( |
| "process save-core --plugin-name=minidump --style=stack " + core |
| ) |
| self.assertTrue(os.path.isfile(core)) |
| |
| # validate savinig via SBProcess |
| error = process.SaveCore(core_sb, "minidump", lldb.eSaveCoreStackOnly) |
| self.assertTrue(error.Success()) |
| self.assertTrue(os.path.isfile(core_sb)) |
| |
| error = process.SaveCore(core_sb, "minidump", lldb.eSaveCoreFull) |
| self.assertTrue(error.Fail()) |
| error = process.SaveCore(core_sb, "minidump", lldb.eSaveCoreDirtyOnly) |
| self.assertTrue(error.Fail()) |
| |
| self.assertSuccess(process.Kill()) |
| |
| # To verify, we'll launch with the mini dump |
| target = self.dbg.CreateTarget(None) |
| process = target.LoadCore(core) |
| |
| # check if the core is in desired state |
| self.assertTrue(process, PROCESS_IS_VALID) |
| self.assertTrue(process.GetProcessInfo().IsValid()) |
| self.assertEqual(process.GetProcessInfo().GetProcessID(), expected_pid) |
| self.assertTrue(target.GetTriple().find("linux") != -1) |
| self.assertTrue(target.GetNumModules(), expected_number_of_modules) |
| self.assertEqual(process.GetNumThreads(), expected_number_of_threads) |
| |
| for module, expected in zip(target.modules, expected_modules): |
| self.assertTrue(module.IsValid()) |
| module_file_name = module.GetFileSpec().GetFilename() |
| expected_file_name = expected.GetFileSpec().GetFilename() |
| # skip kernel virtual dynamic shared objects |
| if "vdso" in expected_file_name: |
| continue |
| self.assertEqual(module_file_name, expected_file_name) |
| self.assertEqual(module.GetUUIDString(), expected.GetUUIDString()) |
| |
| for thread_idx in range(process.GetNumThreads()): |
| thread = process.GetThreadAtIndex(thread_idx) |
| self.assertTrue(thread.IsValid()) |
| thread_id = thread.GetThreadID() |
| self.assertTrue(thread_id in expected_threads) |
| finally: |
| # Clean up the mini dump file. |
| self.assertTrue(self.dbg.DeleteTarget(target)) |
| if os.path.isfile(core): |
| os.unlink(core) |
| if os.path.isfile(core_sb): |
| os.unlink(core_sb) |