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