158 lines · python
1import lldb2from intelpt_testcase import *3from lldbsuite.test.lldbtest import *4from lldbsuite.test import lldbutil5from lldbsuite.test.decorators import *6 7 8@skipIfNoIntelPT9class TestTraceTimestampCounters(TraceIntelPTTestCaseBase):10 @testSBAPIAndCommands11 @skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))12 def testTscPerThread(self):13 self.expect(14 "file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")15 )16 self.expect("b main")17 self.expect("r")18 19 self.traceStartThread(enableTsc=True)20 21 self.expect("n")22 self.expect(23 "thread trace dump instructions -t -c 1",24 patterns=[r": \[\d+.\d+ ns\] 0x0000000000400511 movl"],25 )26 27 @testSBAPIAndCommands28 @skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))29 def testMultipleTscsPerThread(self):30 self.expect(31 "file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")32 )33 self.expect("b main")34 self.expect("r")35 36 self.traceStartThread(enableTsc=True)37 38 # After each stop there'll be a new TSC39 self.expect("si")40 self.expect("si")41 self.expect("si")42 43 # We'll get the most recent instructions, with at least 3 different TSCs44 self.runCmd("thread trace dump instructions -t --raw --forward")45 id_to_timestamp = {}46 for line in self.res.GetOutput().splitlines():47 m = re.search(r" (.+): \[(.+)\ ns].*", line)48 if m:49 id_to_timestamp[int(m.group(1))] = m.group(2)50 self.assertEqual(len(id_to_timestamp), 3)51 52 # We check that the values are right when dumping a specific id53 for id, timestamp in id_to_timestamp.items():54 self.expect(55 f"thread trace dump instructions -t --id {id} -c 1",56 substrs=[f"{id}: [{timestamp} ns]"],57 )58 59 @testSBAPIAndCommands60 @skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))61 def testTscPerProcess(self):62 self.expect(63 "file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")64 )65 self.expect("b main")66 self.expect("r")67 68 self.traceStartProcess(enableTsc=True)69 70 self.expect("n")71 self.expect(72 "thread trace dump instructions -t -c 1",73 patterns=[r": \[\d+.\d+ ns\] 0x0000000000400511 movl"],74 )75 76 self.expect(77 "thread trace dump instructions -t -c 1 --pretty-json",78 patterns=[r'''"timestamp_ns": "\d+.\d+"'''],79 )80 81 @testSBAPIAndCommands82 @skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))83 def testDumpingAfterTracingWithoutTsc(self):84 self.expect(85 "file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")86 )87 self.expect("b main")88 self.expect("r")89 90 self.traceStartThread(enableTsc=False)91 92 self.expect("n")93 self.expect(94 "thread trace dump instructions -t -c 1",95 patterns=[r": \[unavailable\] 0x0000000000400511 movl"],96 )97 98 self.expect(99 "thread trace dump instructions -t -c 1 --json",100 substrs=[""""timestamp_ns":null"""],101 )102 103 @testSBAPIAndCommands104 @skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))105 def testPSBPeriod(self):106 def isPSBSupported():107 caps_file = "/sys/bus/event_source/devices/intel_pt/caps/psb_cyc"108 if not os.path.exists(caps_file):109 return False110 with open(caps_file, "r") as f:111 val = int(f.readline())112 if val != 1:113 return False114 return True115 116 def getValidPSBValues():117 values_file = "/sys/bus/event_source/devices/intel_pt/caps/psb_periods"118 values = []119 with open(values_file, "r") as f:120 mask = int(f.readline(), 16)121 for i in range(0, 32):122 if (1 << i) & mask:123 values.append(i)124 return values125 126 if not isPSBSupported():127 self.skipTest("PSB period unsupported")128 129 valid_psb_values = getValidPSBValues()130 # 0 should always be valid, and it's assumed by lldb-server131 self.assertEqual(valid_psb_values[0], 0)132 133 self.expect(134 "file " + (os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))135 )136 self.expect("b main")137 self.expect("r")138 139 # it's enough to test with two valid values140 for psb_period in (valid_psb_values[0], valid_psb_values[-1]):141 # we first test at thread level142 self.traceStartThread(psbPeriod=psb_period)143 self.traceStopThread()144 145 # we now test at process level146 self.traceStartProcess(psbPeriod=psb_period)147 self.traceStopProcess()148 149 # we now test invalid values150 self.traceStartThread(151 psbPeriod=valid_psb_values[-1] + 1,152 error=True,153 substrs=["Invalid psb_period. Valid values are: 0"],154 )155 156 # TODO: dump the perf_event_attr.config as part of the upcoming "trace dump info"157 # command and check that the psb period is included there.158