xref: /llvm-project/lldb/test/API/commands/target/debuginfo/TestDebugInfoSize.py (revision dd7386d85f11cf6ad911b9827c7018fb08c6c205)
1"""
2Test SBTarget.GetStatistics() reporting for dwo files.
3"""
4
5import json
6import os
7
8from lldbsuite.test import lldbtest, lldbutil
9from lldbsuite.test.decorators import *
10from lldbsuite.test_event.build_exception import BuildError
11
12
13SKELETON_DEBUGINFO_SIZE = 602
14MAIN_DWO_DEBUGINFO_SIZE = 385
15FOO_DWO_DEBUGINFO_SIZE = 380
16
17
18class TestDebugInfoSize(lldbtest.TestBase):
19    # Concurrency is the primary test factor here, not debug info variants.
20    NO_DEBUG_INFO_TESTCASE = True
21
22    def get_output_from_yaml(self):
23        exe = self.getBuildArtifact("a.out")
24        main_dwo = self.getBuildArtifact("a.out-main.dwo")
25        foo_dwo = self.getBuildArtifact("a.out-foo.dwo")
26
27        src_dir = self.getSourceDir()
28        exe_yaml_path = os.path.join(src_dir, "a.out.yaml")
29        self.yaml2obj(exe_yaml_path, exe)
30
31        main_dwo_yaml_path = os.path.join(src_dir, "a.out-main.dwo.yaml")
32        self.yaml2obj(main_dwo_yaml_path, main_dwo)
33
34        foo_dwo_yaml_path = os.path.join(src_dir, "a.out-foo.dwo.yaml")
35        self.yaml2obj(foo_dwo_yaml_path, foo_dwo)
36        return (exe, main_dwo, foo_dwo)
37
38    @add_test_categories(["dwo"])
39    def test_dwo(self):
40        (exe, main_dwo, foo_dwo) = self.get_output_from_yaml()
41
42        # Make sure dwo files exist
43        self.assertTrue(os.path.exists(main_dwo), f'Make sure "{main_dwo}" file exists')
44        self.assertTrue(os.path.exists(foo_dwo), f'Make sure "{foo_dwo}" file exists')
45
46        target = self.dbg.CreateTarget(exe)
47        self.assertTrue(target, lldbtest.VALID_TARGET)
48
49        stats = target.GetStatistics()
50        stream = lldb.SBStream()
51        res = stats.GetAsJSON(stream)
52        debug_stats = json.loads(stream.GetData())
53        self.assertIn(
54            "totalDebugInfoByteSize",
55            debug_stats,
56            'Make sure the "totalDebugInfoByteSize" key is in target.GetStatistics()',
57        )
58        self.assertEqual(
59            debug_stats["totalDebugInfoByteSize"],
60            SKELETON_DEBUGINFO_SIZE + MAIN_DWO_DEBUGINFO_SIZE + FOO_DWO_DEBUGINFO_SIZE,
61        )
62
63    @add_test_categories(["dwo"])
64    def test_only_load_skeleton_debuginfo(self):
65        (exe, main_dwo, foo_dwo) = self.get_output_from_yaml()
66
67        # REMOVE one of the dwo files
68        os.unlink(main_dwo)
69        os.unlink(foo_dwo)
70
71        target = self.dbg.CreateTarget(exe)
72        self.assertTrue(target, lldbtest.VALID_TARGET)
73
74        stats = target.GetStatistics()
75        stream = lldb.SBStream()
76        res = stats.GetAsJSON(stream)
77        debug_stats = json.loads(stream.GetData())
78        self.assertIn(
79            "totalDebugInfoByteSize",
80            debug_stats,
81            'Make sure the "totalDebugInfoByteSize" key is in target.GetStatistics()',
82        )
83        self.assertEqual(debug_stats["totalDebugInfoByteSize"], SKELETON_DEBUGINFO_SIZE)
84
85    @add_test_categories(["dwo"])
86    def test_load_partial_dwos(self):
87        (exe, main_dwo, foo_dwo) = self.get_output_from_yaml()
88
89        # REMOVE one of the dwo files
90        os.unlink(main_dwo)
91
92        target = self.dbg.CreateTarget(exe)
93        self.assertTrue(target, lldbtest.VALID_TARGET)
94
95        stats = target.GetStatistics()
96        stream = lldb.SBStream()
97        res = stats.GetAsJSON(stream)
98        debug_stats = json.loads(stream.GetData())
99        self.assertIn(
100            "totalDebugInfoByteSize",
101            debug_stats,
102            'Make sure the "totalDebugInfoByteSize" key is in target.GetStatistics()',
103        )
104        self.assertEqual(
105            debug_stats["totalDebugInfoByteSize"],
106            SKELETON_DEBUGINFO_SIZE + FOO_DWO_DEBUGINFO_SIZE,
107        )
108
109    @add_test_categories(["dwo"])
110    def test_dwos_loaded_symbols_on_demand(self):
111        (exe, main_dwo, foo_dwo) = self.get_output_from_yaml()
112
113        # Make sure dwo files exist
114        self.assertTrue(os.path.exists(main_dwo), f'Make sure "{main_dwo}" file exists')
115        self.assertTrue(os.path.exists(foo_dwo), f'Make sure "{foo_dwo}" file exists')
116
117        # Load symbols on-demand
118        self.runCmd("settings set symbols.load-on-demand true")
119
120        target = self.dbg.CreateTarget(exe)
121        self.assertTrue(target, lldbtest.VALID_TARGET)
122
123        # By default dwo files will not be loaded
124        stats = target.GetStatistics()
125        stream = lldb.SBStream()
126        res = stats.GetAsJSON(stream)
127        debug_stats = json.loads(stream.GetData())
128        self.assertIn(
129            "totalDebugInfoByteSize",
130            debug_stats,
131            'Make sure the "totalDebugInfoByteSize" key is in target.GetStatistics()',
132        )
133        self.assertEqual(debug_stats["totalDebugInfoByteSize"], SKELETON_DEBUGINFO_SIZE)
134
135        # Force loading all the dwo files
136        stats_options = lldb.SBStatisticsOptions()
137        stats_options.SetReportAllAvailableDebugInfo(True)
138        stats = target.GetStatistics(stats_options)
139        stream = lldb.SBStream()
140        stats.GetAsJSON(stream)
141        debug_stats = json.loads(stream.GetData())
142        self.assertEqual(
143            debug_stats["totalDebugInfoByteSize"],
144            SKELETON_DEBUGINFO_SIZE + MAIN_DWO_DEBUGINFO_SIZE + FOO_DWO_DEBUGINFO_SIZE,
145        )
146