""" 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) def containsLibmallocError(self, output): for error in [ "pointer being freed was not allocated", "not an allocated block", ]: if error in output: return True return False @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"]) result = lldb.SBCommandReturnObject() self.dbg.GetCommandInterpreter().HandleCommand( "process status --verbose", result ) self.assertIn("Extended Crash Information", result.GetOutput()) self.assertIn("Crash-Info Annotations", result.GetOutput()) self.assertTrue(self.containsLibmallocError(result.GetOutput())) @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.assertTrue(self.containsLibmallocError(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())