| """ |
| Test lldb process crash info. |
| """ |
| |
| import os |
| |
| import lldb |
| from lldbsuite.test.decorators import * |
| from lldbsuite.test.lldbtest import * |
| from lldbsuite.test import lldbutil |
| from lldbsuite.test import lldbtest |
| |
| |
| class PlatformProcessCrashInfoTestCase(TestBase): |
| def setUp(self): |
| TestBase.setUp(self) |
| self.runCmd("settings set auto-confirm true") |
| self.source = "main.c" |
| self.line = line_number(self.source, "// break here") |
| |
| def tearDown(self): |
| self.runCmd("settings clear auto-confirm") |
| TestBase.tearDown(self) |
| |
| @skipIfAsan # The test process intentionally double-frees. |
| @skipUnlessDarwin |
| def test_cli(self): |
| """Test that `process status --verbose` fetches the extended crash |
| information dictionary from the command-line properly.""" |
| self.build() |
| exe = self.getBuildArtifact("a.out") |
| self.expect("file " + exe, patterns=["Current executable set to .*a.out"]) |
| |
| self.expect("process launch", patterns=["Process .* launched: .*a.out"]) |
| |
| self.expect( |
| "process status --verbose", |
| patterns=[ |
| "Extended Crash Information", |
| "Crash-Info Annotations", |
| "pointer being freed was not allocated", |
| ], |
| ) |
| |
| @skipIfAsan # The test process intentionally hits a memory bug. |
| @skipUnlessDarwin |
| def test_api(self): |
| """Test that lldb can fetch a crashed process' extended crash information |
| dictionary from the api properly.""" |
| self.build() |
| target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) |
| self.assertTrue(target, VALID_TARGET) |
| |
| target.LaunchSimple(None, None, os.getcwd()) |
| |
| stream = lldb.SBStream() |
| self.assertTrue(stream) |
| |
| process = target.GetProcess() |
| self.assertTrue(process) |
| |
| crash_info = process.GetExtendedCrashInformation() |
| |
| error = crash_info.GetAsJSON(stream) |
| |
| self.assertSuccess(error) |
| |
| self.assertTrue(crash_info.IsValid()) |
| |
| self.assertIn("pointer being freed was not allocated", stream.GetData()) |
| |
| # dyld leaves permanent crash_info records when testing on device. |
| @skipIfDarwinEmbedded |
| def test_on_sane_process(self): |
| """Test that lldb doesn't fetch the extended crash information |
| dictionary from a 'sane' stopped process.""" |
| self.build() |
| target, _, _, _ = lldbutil.run_to_line_breakpoint( |
| self, lldb.SBFileSpec(self.source), self.line |
| ) |
| |
| stream = lldb.SBStream() |
| self.assertTrue(stream) |
| |
| process = target.GetProcess() |
| self.assertTrue(process) |
| |
| crash_info = process.GetExtendedCrashInformation() |
| |
| error = crash_info.GetAsJSON(stream) |
| self.assertFalse(error.Success()) |
| self.assertIn("No structured data.", error.GetCString()) |