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