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