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