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