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