1import lldb 2from intelpt_testcase import * 3from lldbsuite.test.lldbtest import * 4from lldbsuite.test import lldbutil 5from lldbsuite.test.decorators import * 6 7class TestTraceTimestampCounters(TraceIntelPTTestCaseBase): 8 9 mydir = TestBase.compute_mydir(__file__) 10 11 @testSBAPIAndCommands 12 @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64'])) 13 def testTscPerThread(self): 14 self.expect("file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")) 15 self.expect("b main") 16 self.expect("r") 17 18 self.traceStartThread(enableTsc=True) 19 20 self.expect("n") 21 self.expect("thread trace dump instructions --tsc -c 1", 22 patterns=["0: \[tsc=0x[0-9a-fA-F]+\] 0x0000000000400511 movl"]) 23 24 @testSBAPIAndCommands 25 @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64'])) 26 def testMultipleTscsPerThread(self): 27 self.expect("file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")) 28 self.expect("b main") 29 self.expect("r") 30 31 self.traceStartThread(enableTsc=True) 32 33 # After each stop there'll be a new TSC 34 self.expect("n") 35 self.expect("n") 36 self.expect("n") 37 38 # We'll get the most recent instructions, with at least 3 different TSCs 39 self.runCmd("thread trace dump instructions --tsc --raw") 40 id_to_tsc = {} 41 for line in self.res.GetOutput().splitlines(): 42 m = re.search(" (.+): \[tsc=(.+)\].*", line) 43 if m: 44 id_to_tsc[int(m.group(1))] = m.group(2) 45 self.assertEqual(len(id_to_tsc), 6) 46 47 # We check that the values are right when dumping a specific id 48 for id in range(0, 6): 49 self.expect(f"thread trace dump instructions --tsc --id {id} -c 1", 50 substrs=[f"{id}: [tsc={id_to_tsc[id]}]"]) 51 52 @testSBAPIAndCommands 53 @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64'])) 54 def testTscPerProcess(self): 55 self.expect("file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")) 56 self.expect("b main") 57 self.expect("r") 58 59 self.traceStartProcess(enableTsc=True) 60 61 self.expect("n") 62 self.expect("thread trace dump instructions --tsc -c 1", 63 patterns=["0: \[tsc=0x[0-9a-fA-F]+\] 0x0000000000400511 movl"]) 64 65 @testSBAPIAndCommands 66 @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64'])) 67 def testDumpingAfterTracingWithoutTsc(self): 68 self.expect("file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")) 69 self.expect("b main") 70 self.expect("r") 71 72 self.traceStartThread(enableTsc=False) 73 74 self.expect("n") 75 self.expect("thread trace dump instructions --tsc -c 1", 76 patterns=["0: \[tsc=unavailable\] 0x0000000000400511 movl"]) 77 78 @testSBAPIAndCommands 79 @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64'])) 80 def testPSBPeriod(self): 81 def isPSBSupported(): 82 caps_file = "/sys/bus/event_source/devices/intel_pt/caps/psb_cyc" 83 if not os.path.exists(caps_file): 84 return False 85 with open(caps_file, "r") as f: 86 val = int(f.readline()) 87 if val != 1: 88 return False 89 return True 90 91 def getValidPSBValues(): 92 values_file = "/sys/bus/event_source/devices/intel_pt/caps/psb_periods" 93 values = [] 94 with open(values_file, "r") as f: 95 mask = int(f.readline(), 16) 96 for i in range(0, 32): 97 if (1 << i) & mask: 98 values.append(i) 99 return values 100 101 102 if not isPSBSupported(): 103 self.skipTest("PSB period unsupported") 104 105 valid_psb_values = getValidPSBValues() 106 # 0 should always be valid, and it's assumed by lldb-server 107 self.assertEqual(valid_psb_values[0], 0) 108 109 self.expect("file " + (os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))) 110 self.expect("b main") 111 self.expect("r") 112 113 # it's enough to test with two valid values 114 for psb_period in (valid_psb_values[0], valid_psb_values[-1]): 115 # we first test at thread level 116 self.traceStartThread(psbPeriod=psb_period) 117 self.traceStopThread() 118 119 # we now test at process level 120 self.traceStartProcess(psbPeriod=psb_period) 121 self.traceStopProcess() 122 123 # we now test invalid values 124 self.traceStartThread(psbPeriod=valid_psb_values[-1] + 1, error=True, 125 substrs=["Invalid psb_period. Valid values are: 0"]) 126 127 # TODO: dump the perf_event_attr.config as part of the upcoming "trace dump info" 128 # command and check that the psb period is included there. 129