188 lines · python
1# Test the SBAPI for GetStatistics()2 3import json4 5import lldb6from lldbsuite.test.decorators import *7from lldbsuite.test.lldbtest import *8from lldbsuite.test import lldbutil9 10 11class TestStatsAPI(TestBase):12 NO_DEBUG_INFO_TESTCASE = True13 14 def test_stats_api(self):15 """16 Test SBTarget::GetStatistics() API.17 """18 self.build()19 exe = self.getBuildArtifact("a.out")20 # Launch a process and break21 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(22 self, "break here", lldb.SBFileSpec("main.c")23 )24 25 # Test enabling/disabling stats26 self.assertFalse(target.GetCollectingStats())27 target.SetCollectingStats(True)28 self.assertTrue(target.GetCollectingStats())29 target.SetCollectingStats(False)30 self.assertFalse(target.GetCollectingStats())31 32 # Test the function to get the statistics in JSON'ish.33 stats = target.GetStatistics()34 stream = lldb.SBStream()35 res = stats.GetAsJSON(stream)36 debug_stats = json.loads(stream.GetData())37 self.assertIn(38 "targets",39 debug_stats,40 'Make sure the "targets" key in in target.GetStatistics()',41 )42 self.assertIn(43 "modules",44 debug_stats,45 'Make sure the "modules" key in in target.GetStatistics()',46 )47 stats_json = debug_stats["targets"][0]48 self.assertIn(49 "expressionEvaluation",50 stats_json,51 'Make sure the "expressionEvaluation" key in in target.GetStatistics()["targets"][0]',52 )53 self.assertIn(54 "frameVariable",55 stats_json,56 'Make sure the "frameVariable" key in in target.GetStatistics()["targets"][0]',57 )58 self.assertNotIn(59 "loadCoreTime",60 stats_json,61 "LoadCoreTime should not be present in a live, non-coredump target",62 )63 expressionEvaluation = stats_json["expressionEvaluation"]64 self.assertIn(65 "successes",66 expressionEvaluation,67 'Make sure the "successes" key in in "expressionEvaluation" dictionary"',68 )69 self.assertIn(70 "failures",71 expressionEvaluation,72 'Make sure the "failures" key in in "expressionEvaluation" dictionary"',73 )74 frameVariable = stats_json["frameVariable"]75 self.assertIn(76 "successes",77 frameVariable,78 'Make sure the "successes" key in in "frameVariable" dictionary"',79 )80 self.assertIn(81 "failures",82 frameVariable,83 'Make sure the "failures" key in in "frameVariable" dictionary"',84 )85 86 # Test statistics summary.87 stats_options = lldb.SBStatisticsOptions()88 stats_options.SetSummaryOnly(True)89 stats_summary = target.GetStatistics(stats_options)90 stream_summary = lldb.SBStream()91 stats_summary.GetAsJSON(stream_summary)92 debug_stats_summary = json.loads(stream_summary.GetData())93 self.assertNotIn("modules", debug_stats_summary)94 self.assertNotIn("commands", debug_stats_summary)95 96 # Summary values should be the same as in full statistics.97 # The exceptions to this are:98 # - The parse time on Mac OS X is not deterministic.99 # - Memory usage may grow over time due to the use of ConstString.100 for key, value in debug_stats_summary.items():101 self.assertIn(key, debug_stats)102 if key != "memory" and key != "targets" and not key.endswith("Time"):103 self.assertEqual(debug_stats[key], value)104 105 def test_command_stats_api(self):106 """107 Test GetCommandInterpreter::GetStatistics() API.108 """109 self.build()110 exe = self.getBuildArtifact("a.out")111 lldbutil.run_to_name_breakpoint(self, "main")112 113 interp = self.dbg.GetCommandInterpreter()114 result = lldb.SBCommandReturnObject()115 interp.HandleCommand("bt", result)116 117 stream = lldb.SBStream()118 res = interp.GetStatistics().GetAsJSON(stream)119 command_stats = json.loads(stream.GetData())120 121 # Verify bt command is correctly parsed into final form.122 self.assertEqual(command_stats["thread backtrace"], 1)123 # Verify original raw command is not duplicatedly captured.124 self.assertNotIn("bt", command_stats)125 # Verify bt's regex command is not duplicatedly captured.126 self.assertNotIn("_regexp-bt", command_stats)127 128 @add_test_categories(["dwo"])129 def test_command_stats_force(self):130 """131 Test reporting all pssible debug info stats by force loading all debug132 info. For example, dwo files133 """134 src_dir = self.getSourceDir()135 dwo_yaml_path = os.path.join(src_dir, "main-main.dwo.yaml")136 exe_yaml_path = os.path.join(src_dir, "main.yaml")137 dwo_path = self.getBuildArtifact("main-main.dwo")138 exe_path = self.getBuildArtifact("main")139 self.yaml2obj(dwo_yaml_path, dwo_path)140 self.yaml2obj(exe_yaml_path, exe_path)141 142 # Turn on symbols on-demand loading143 self.runCmd("settings set symbols.load-on-demand true")144 145 # We need the current working directory to be set to the build directory146 os.chdir(self.getBuildDir())147 # Create a target with the object file we just created from YAML148 target = self.dbg.CreateTarget(exe_path)149 self.assertTrue(target, VALID_TARGET)150 151 # Get statistics152 stats_options = lldb.SBStatisticsOptions()153 stats = target.GetStatistics(stats_options)154 stream = lldb.SBStream()155 stats.GetAsJSON(stream)156 debug_stats = json.loads(stream.GetData())157 self.assertEqual(debug_stats["totalDebugInfoByteSize"], 193)158 159 # Get statistics with force loading160 stats_options.SetReportAllAvailableDebugInfo(True)161 stats_force = target.GetStatistics(stats_options)162 stream_force = lldb.SBStream()163 stats_force.GetAsJSON(stream_force)164 debug_stats_force = json.loads(stream_force.GetData())165 self.assertEqual(debug_stats_force["totalDebugInfoByteSize"], 445)166 167 def test_core_load_time(self):168 """169 Test to see if the coredump path is included in statistics dump.170 """171 yaml_file = "arm64-minidump-build-ids.yaml"172 src_dir = self.getSourceDir()173 minidump_path = self.getBuildArtifact(os.path.basename(yaml_file) + ".dmp")174 self.yaml2obj(os.path.join(src_dir, yaml_file), minidump_path)175 target = self.dbg.CreateTarget(None)176 process = target.LoadCore(minidump_path)177 self.assertTrue(process.IsValid())178 179 stats_options = lldb.SBStatisticsOptions()180 stats = target.GetStatistics(stats_options)181 stream = lldb.SBStream()182 stats.GetAsJSON(stream)183 debug_stats = json.loads(stream.GetData())184 self.assertTrue("targets" in debug_stats)185 target_info = debug_stats["targets"][0]186 self.assertTrue("loadCoreTime" in target_info)187 self.assertTrue(float(target_info["loadCoreTime"]) > 0.0)188