1"""
2Test lldb process crash info.
3"""
4
5import os
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12class PlatformProcessCrashInfoTestCase(TestBase):
13
14    mydir = TestBase.compute_mydir(__file__)
15
16    def setUp(self):
17        TestBase.setUp(self)
18        self.runCmd("settings set auto-confirm true")
19        self.source = "main.c"
20        self.line = 3
21
22    def tearDown(self):
23        self.runCmd("settings clear auto-confirm")
24        TestBase.tearDown(self)
25
26    @skipUnlessDarwin
27    def test_cli(self):
28        """Test that `process status --verbose` fetches the extended crash
29        information dictionnary from the command-line properly."""
30        self.build()
31        exe = self.getBuildArtifact("a.out")
32        self.expect("file " + exe,
33                    patterns=["Current executable set to .*a.out"])
34
35        self.expect('process launch',
36                    patterns=["Process .* launched: .*a.out"])
37
38        self.expect('process status --verbose',
39                    patterns=["\"message\".*pointer being freed was not allocated"])
40
41
42    @skipUnlessDarwin
43    def test_api(self):
44        """Test that lldb can fetch a crashed process' extended crash information
45        dictionnary from the api properly."""
46        self.build()
47        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
48        self.assertTrue(target, VALID_TARGET)
49
50        target.LaunchSimple(None, None, os.getcwd())
51
52        stream = lldb.SBStream()
53        self.assertTrue(stream)
54
55        crash_info = target.GetExtendedCrashInformation()
56
57        error = crash_info.GetAsJSON(stream)
58
59        self.assertTrue(error.Success())
60
61        self.assertTrue(crash_info.IsValid())
62
63        self.assertIn("pointer being freed was not allocated", stream.GetData())
64
65    @skipUnlessDarwin
66    def test_before_launch(self):
67        """Test that lldb doesn't fetch the extended crash information
68        dictionnary from if the process wasn't launched yet."""
69        self.build()
70        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
71        self.assertTrue(target, VALID_TARGET)
72
73        stream = lldb.SBStream()
74        self.assertTrue(stream)
75
76        crash_info = target.GetExtendedCrashInformation()
77
78        error = crash_info.GetAsJSON(stream)
79        self.assertFalse(error.Success())
80        self.assertIn("No structured data.", error.GetCString())
81
82    @skipUnlessDarwin
83    def test_on_sane_process(self):
84        """Test that lldb doesn't fetch the extended crash information
85        dictionnary from a 'sane' stopped process."""
86        self.build()
87        target, _, _, _ = lldbutil.run_to_line_breakpoint(self, lldb.SBFileSpec(self.source),
88                                        self.line)
89
90        stream = lldb.SBStream()
91        self.assertTrue(stream)
92
93        crash_info = target.GetExtendedCrashInformation()
94
95        error = crash_info.GetAsJSON(stream)
96        self.assertFalse(error.Success())
97        self.assertIn("No structured data.", error.GetCString())
98