xref: /llvm-project/lldb/test/API/functionalities/module_cache/debug_index/TestDebugIndexCache.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1a2154b19SGreg Claytonimport glob
2a2154b19SGreg Claytonimport json
3a2154b19SGreg Claytonimport lldb
4a2154b19SGreg Claytonfrom lldbsuite.test.decorators import *
5a2154b19SGreg Claytonfrom lldbsuite.test.lldbtest import *
6a2154b19SGreg Claytonfrom lldbsuite.test import lldbutil
7a2154b19SGreg Claytonimport os
8a2154b19SGreg Claytonimport time
9a2154b19SGreg Clayton
10a2154b19SGreg Clayton
11a2154b19SGreg Claytonclass DebugIndexCacheTestcase(TestBase):
12a2154b19SGreg Clayton    def setUp(self):
13a2154b19SGreg Clayton        # Call super's setUp().
14a2154b19SGreg Clayton        TestBase.setUp(self)
15a2154b19SGreg Clayton        # Set the lldb module cache directory to a directory inside the build
16a2154b19SGreg Clayton        # artifacts directory so no other tests are interfered with.
17*2238dcc3SJonas Devlieghere        self.cache_dir = os.path.join(self.getBuildDir(), "lldb-module-cache")
18a2154b19SGreg Clayton
19a2154b19SGreg Clayton    def get_module_cache_files(self, basename):
20*2238dcc3SJonas Devlieghere        module_cache_glob = os.path.join(
21*2238dcc3SJonas Devlieghere            self.cache_dir, "llvmcache-*%s*dwarf-index*" % (basename)
22*2238dcc3SJonas Devlieghere        )
23a2154b19SGreg Clayton        return glob.glob(module_cache_glob)
24a2154b19SGreg Clayton
25a2154b19SGreg Clayton    def get_stats(self, log_path=None):
26a2154b19SGreg Clayton        """
27a2154b19SGreg Clayton        Get the output of the "statistics dump" and return the JSON as a
28a2154b19SGreg Clayton        python dictionary.
29a2154b19SGreg Clayton        """
30a2154b19SGreg Clayton        # If log_path is set, open the path and emit the output of the command
31a2154b19SGreg Clayton        # for debugging purposes.
32a2154b19SGreg Clayton        if log_path is not None:
33*2238dcc3SJonas Devlieghere            f = open(log_path, "w")
34a2154b19SGreg Clayton        else:
35a2154b19SGreg Clayton            f = None
36a2154b19SGreg Clayton        return_obj = lldb.SBCommandReturnObject()
37a2154b19SGreg Clayton        command = "statistics dump "
38a2154b19SGreg Clayton        if f:
39*2238dcc3SJonas Devlieghere            f.write("(lldb) %s\n" % (command))
40a2154b19SGreg Clayton        self.ci.HandleCommand(command, return_obj, False)
41a2154b19SGreg Clayton        metrics_json = return_obj.GetOutput()
42a2154b19SGreg Clayton        if f:
43a2154b19SGreg Clayton            f.write(metrics_json)
44a2154b19SGreg Clayton        return json.loads(metrics_json)
45a2154b19SGreg Clayton
46a2154b19SGreg Clayton    def enable_lldb_index_cache(self):
47*2238dcc3SJonas Devlieghere        self.runCmd(
48*2238dcc3SJonas Devlieghere            'settings set symbols.lldb-index-cache-path "%s"' % (self.cache_dir)
49*2238dcc3SJonas Devlieghere        )
50*2238dcc3SJonas Devlieghere        self.runCmd("settings set symbols.enable-lldb-index-cache true")
51a2154b19SGreg Clayton
52a2154b19SGreg Clayton    @no_debug_info_test
53a2154b19SGreg Clayton    def test_with_caching_enabled(self):
54a2154b19SGreg Clayton        """
55a2154b19SGreg Clayton        Test module cache functionality for debug info index caching.
56a2154b19SGreg Clayton
57a2154b19SGreg Clayton        We test that a debug info index file is created for the debug
58a2154b19SGreg Clayton        information when caching is enabled with a file that contains
59a2154b19SGreg Clayton        at least one of each kind of DIE in ManualDWARFIndex::IndexSet.
60a2154b19SGreg Clayton
61a2154b19SGreg Clayton        The input file has DWARF that will fill in every member of the
62a2154b19SGreg Clayton        ManualDWARFIndex::IndexSet class to ensure we can encode all of the
63a2154b19SGreg Clayton        required information.
64a2154b19SGreg Clayton
65a2154b19SGreg Clayton        With caching enabled, we also verify that the appropriate statistics
66a2154b19SGreg Clayton        specify that the cache file was saved to the cache.
67a2154b19SGreg Clayton        """
68a2154b19SGreg Clayton        self.enable_lldb_index_cache()
69a2154b19SGreg Clayton        src_dir = self.getSourceDir()
70a2154b19SGreg Clayton        yaml_path = os.path.join(src_dir, "exe.yaml")
71a2154b19SGreg Clayton        yaml_base, ext = os.path.splitext(yaml_path)
72a2154b19SGreg Clayton        obj_path = self.getBuildArtifact("main.o")
73a2154b19SGreg Clayton        self.yaml2obj(yaml_path, obj_path)
74a2154b19SGreg Clayton
75a2154b19SGreg Clayton        # Create a target with the object file we just created from YAML
76a2154b19SGreg Clayton        target = self.dbg.CreateTarget(obj_path)
77a2154b19SGreg Clayton        self.assertTrue(target, VALID_TARGET)
78a2154b19SGreg Clayton
79*2238dcc3SJonas Devlieghere        debug_index_cache_files = self.get_module_cache_files("main.o")
80*2238dcc3SJonas Devlieghere        self.assertEqual(
81*2238dcc3SJonas Devlieghere            len(debug_index_cache_files),
82*2238dcc3SJonas Devlieghere            1,
83*2238dcc3SJonas Devlieghere            "make sure there is one file in the module cache directory (%s) for main.o that is a debug info cache"
84*2238dcc3SJonas Devlieghere            % (self.cache_dir),
85*2238dcc3SJonas Devlieghere        )
86a2154b19SGreg Clayton
87a2154b19SGreg Clayton        # Verify that the module statistics have the information that specifies
88a2154b19SGreg Clayton        # if we loaded or saved the debug index and symtab to the cache
89a2154b19SGreg Clayton        stats = self.get_stats()
90*2238dcc3SJonas Devlieghere        module_stats = stats["modules"][0]
91*2238dcc3SJonas Devlieghere        self.assertFalse(module_stats["debugInfoIndexLoadedFromCache"])
92*2238dcc3SJonas Devlieghere        self.assertTrue(module_stats["debugInfoIndexSavedToCache"])
93*2238dcc3SJonas Devlieghere        self.assertFalse(module_stats["symbolTableLoadedFromCache"])
94*2238dcc3SJonas Devlieghere        self.assertTrue(module_stats["symbolTableSavedToCache"])
95a2154b19SGreg Clayton        # Verify the top level stats track how many things were loaded or saved
96a2154b19SGreg Clayton        # to the cache.
97a2154b19SGreg Clayton        self.assertEqual(stats["totalDebugInfoIndexLoadedFromCache"], 0)
98a2154b19SGreg Clayton        self.assertEqual(stats["totalDebugInfoIndexSavedToCache"], 1)
99a2154b19SGreg Clayton        self.assertEqual(stats["totalSymbolTablesLoadedFromCache"], 0)
100a2154b19SGreg Clayton        self.assertEqual(stats["totalSymbolTablesSavedToCache"], 1)
101a2154b19SGreg Clayton
102a2154b19SGreg Clayton    @no_debug_info_test
103a2154b19SGreg Clayton    def test_with_caching_disabled(self):
104a2154b19SGreg Clayton        """
105a2154b19SGreg Clayton        Test module cache functionality for debug info index caching.
106a2154b19SGreg Clayton
107a2154b19SGreg Clayton        We test that a debug info index file is not created for the debug
108a2154b19SGreg Clayton        information when caching is disabled with a file that contains
109a2154b19SGreg Clayton        at least one of each kind of DIE in ManualDWARFIndex::IndexSet.
110a2154b19SGreg Clayton
111a2154b19SGreg Clayton        The input file has DWARF that will fill in every member of the
112a2154b19SGreg Clayton        ManualDWARFIndex::IndexSet class to ensure we can encode all of the
113a2154b19SGreg Clayton        required information.
114a2154b19SGreg Clayton
115a2154b19SGreg Clayton        With caching disabled, we also verify that the appropriate
116a2154b19SGreg Clayton        statistics specify that the cache file was not saved to the cache.
117a2154b19SGreg Clayton        """
118a2154b19SGreg Clayton        src_dir = self.getSourceDir()
119a2154b19SGreg Clayton        yaml_path = os.path.join(src_dir, "exe.yaml")
120a2154b19SGreg Clayton        yaml_base, ext = os.path.splitext(yaml_path)
121a2154b19SGreg Clayton        obj_path = self.getBuildArtifact("main.o")
122a2154b19SGreg Clayton        self.yaml2obj(yaml_path, obj_path)
123a2154b19SGreg Clayton
124a2154b19SGreg Clayton        # Create a target with the object file we just created from YAML
125a2154b19SGreg Clayton        target = self.dbg.CreateTarget(obj_path)
126a2154b19SGreg Clayton        self.assertTrue(target, VALID_TARGET)
127a2154b19SGreg Clayton
128*2238dcc3SJonas Devlieghere        debug_index_cache_files = self.get_module_cache_files("main.o")
129*2238dcc3SJonas Devlieghere        self.assertEqual(
130*2238dcc3SJonas Devlieghere            len(debug_index_cache_files),
131*2238dcc3SJonas Devlieghere            0,
132*2238dcc3SJonas Devlieghere            "make sure there is no file in the module cache directory (%s) for main.o that is a debug info cache"
133*2238dcc3SJonas Devlieghere            % (self.cache_dir),
134*2238dcc3SJonas Devlieghere        )
135a2154b19SGreg Clayton
136a2154b19SGreg Clayton        # Verify that the module statistics have the information that specifies
137a2154b19SGreg Clayton        # if we loaded or saved the debug index and symtab to the cache
138a2154b19SGreg Clayton        stats = self.get_stats()
139*2238dcc3SJonas Devlieghere        module_stats = stats["modules"][0]
140*2238dcc3SJonas Devlieghere        self.assertFalse(module_stats["debugInfoIndexLoadedFromCache"])
141*2238dcc3SJonas Devlieghere        self.assertFalse(module_stats["debugInfoIndexSavedToCache"])
142*2238dcc3SJonas Devlieghere        self.assertFalse(module_stats["symbolTableLoadedFromCache"])
143*2238dcc3SJonas Devlieghere        self.assertFalse(module_stats["symbolTableSavedToCache"])
144a2154b19SGreg Clayton        # Verify the top level stats track how many things were loaded or saved
145a2154b19SGreg Clayton        # to the cache.
146a2154b19SGreg Clayton        self.assertEqual(stats["totalDebugInfoIndexLoadedFromCache"], 0)
147a2154b19SGreg Clayton        self.assertEqual(stats["totalDebugInfoIndexSavedToCache"], 0)
148a2154b19SGreg Clayton        self.assertEqual(stats["totalSymbolTablesLoadedFromCache"], 0)
149a2154b19SGreg Clayton        self.assertEqual(stats["totalSymbolTablesSavedToCache"], 0)
150