1bf9f21a2SWalter Erquinigofrom lldbsuite.test.lldbtest import * 2bf9f21a2SWalter Erquinigoimport os 3bf9f21a2SWalter Erquinigoimport time 4bf9f21a2SWalter Erquinigoimport json 5bf9f21a2SWalter Erquinigo 62238dcc3SJonas DevlieghereADDRESS_REGEX = "0x[0-9a-fA-F]*" 72238dcc3SJonas Devlieghere 8bf9f21a2SWalter Erquinigo 9bf9f21a2SWalter Erquinigo# Decorator that runs a test with both modes of USE_SB_API. 10bf9f21a2SWalter Erquinigo# It assumes that no tests can be executed in parallel. 11bf9f21a2SWalter Erquinigodef testSBAPIAndCommands(func): 12bf9f21a2SWalter Erquinigo def wrapper(*args, **kwargs): 13bf9f21a2SWalter Erquinigo TraceIntelPTTestCaseBase.USE_SB_API = True 14bf9f21a2SWalter Erquinigo func(*args, **kwargs) 15bf9f21a2SWalter Erquinigo TraceIntelPTTestCaseBase.USE_SB_API = False 16bf9f21a2SWalter Erquinigo func(*args, **kwargs) 172238dcc3SJonas Devlieghere 18bf9f21a2SWalter Erquinigo return wrapper 19bf9f21a2SWalter Erquinigo 202238dcc3SJonas Devlieghere 21bf9f21a2SWalter Erquinigo# Class that should be used by all python Intel PT tests. 22bf9f21a2SWalter Erquinigo# 23bf9f21a2SWalter Erquinigo# It has a handy check that skips the test if the intel-pt plugin is not enabled. 24bf9f21a2SWalter Erquinigo# 25bf9f21a2SWalter Erquinigo# It also contains many functions that can test both the SB API or the command line version 26bf9f21a2SWalter Erquinigo# of the most important tracing actions. 27bf9f21a2SWalter Erquinigoclass TraceIntelPTTestCaseBase(TestBase): 28bf9f21a2SWalter Erquinigo NO_DEBUG_INFO_TESTCASE = True 29bf9f21a2SWalter Erquinigo 30bf9f21a2SWalter Erquinigo # If True, the trace test methods will use the SB API, otherwise they'll use raw commands. 31bf9f21a2SWalter Erquinigo USE_SB_API = False 32bf9f21a2SWalter Erquinigo 33bf9f21a2SWalter Erquinigo def setUp(self): 34bf9f21a2SWalter Erquinigo TestBase.setUp(self) 352238dcc3SJonas Devlieghere if "intel-pt" not in configuration.enabled_plugins: 36bf9f21a2SWalter Erquinigo self.skipTest("The intel-pt test plugin is not enabled") 37bf9f21a2SWalter Erquinigo 386a5355e8SWalter Erquinigo def skipIfPerCpuTracingIsNotSupported(self): 391f49714dSWalter Erquinigo def is_supported(): 401f49714dSWalter Erquinigo try: 411f49714dSWalter Erquinigo with open("/proc/sys/kernel/perf_event_paranoid", "r") as permissions: 421f49714dSWalter Erquinigo value = int(permissions.readlines()[0]) 431f49714dSWalter Erquinigo if value <= 0: 441f49714dSWalter Erquinigo return True 451f49714dSWalter Erquinigo except: 461f49714dSWalter Erquinigo return False 472238dcc3SJonas Devlieghere 481f49714dSWalter Erquinigo if not is_supported(): 492238dcc3SJonas Devlieghere self.skipTest( 502238dcc3SJonas Devlieghere "Per cpu tracing is not supported. You need " 5137161079SWalter Erquinigo "/proc/sys/kernel/perf_event_paranoid to be 0 or -1. " 522238dcc3SJonas Devlieghere "You can use `sudo sysctl -w kernel.perf_event_paranoid=-1` for that." 532238dcc3SJonas Devlieghere ) 541f49714dSWalter Erquinigo 55bf9f21a2SWalter Erquinigo def getTraceOrCreate(self): 56bf9f21a2SWalter Erquinigo if not self.target().GetTrace().IsValid(): 57bf9f21a2SWalter Erquinigo error = lldb.SBError() 58bf9f21a2SWalter Erquinigo self.target().CreateTrace(error) 59bf9f21a2SWalter Erquinigo return self.target().GetTrace() 60bf9f21a2SWalter Erquinigo 61bf9f21a2SWalter Erquinigo def assertSBError(self, sberror, error=False): 62bf9f21a2SWalter Erquinigo if error: 63bf9f21a2SWalter Erquinigo self.assertTrue(sberror.Fail()) 64bf9f21a2SWalter Erquinigo else: 65bf9f21a2SWalter Erquinigo self.assertSuccess(sberror) 66bf9f21a2SWalter Erquinigo 672238dcc3SJonas Devlieghere def createConfiguration( 682238dcc3SJonas Devlieghere self, 692238dcc3SJonas Devlieghere iptTraceSize=None, 702238dcc3SJonas Devlieghere processBufferSizeLimit=None, 712238dcc3SJonas Devlieghere enableTsc=False, 722238dcc3SJonas Devlieghere psbPeriod=None, 732238dcc3SJonas Devlieghere perCpuTracing=False, 742238dcc3SJonas Devlieghere ): 75bf9f21a2SWalter Erquinigo obj = {} 76bf9f21a2SWalter Erquinigo if processBufferSizeLimit is not None: 77bf9f21a2SWalter Erquinigo obj["processBufferSizeLimit"] = processBufferSizeLimit 786a5355e8SWalter Erquinigo if iptTraceSize is not None: 796a5355e8SWalter Erquinigo obj["iptTraceSize"] = iptTraceSize 8004195843SWalter Erquinigo if psbPeriod is not None: 8104195843SWalter Erquinigo obj["psbPeriod"] = psbPeriod 8204195843SWalter Erquinigo obj["enableTsc"] = enableTsc 836a5355e8SWalter Erquinigo obj["perCpuTracing"] = perCpuTracing 84bf9f21a2SWalter Erquinigo 85bf9f21a2SWalter Erquinigo configuration = lldb.SBStructuredData() 86bf9f21a2SWalter Erquinigo configuration.SetFromJSON(json.dumps(obj)) 87bf9f21a2SWalter Erquinigo return configuration 88bf9f21a2SWalter Erquinigo 892238dcc3SJonas Devlieghere def traceStartThread( 902238dcc3SJonas Devlieghere self, 912238dcc3SJonas Devlieghere thread=None, 922238dcc3SJonas Devlieghere error=False, 932238dcc3SJonas Devlieghere substrs=None, 942238dcc3SJonas Devlieghere iptTraceSize=None, 952238dcc3SJonas Devlieghere enableTsc=False, 962238dcc3SJonas Devlieghere psbPeriod=None, 972238dcc3SJonas Devlieghere ): 98bf9f21a2SWalter Erquinigo if self.USE_SB_API: 99bf9f21a2SWalter Erquinigo trace = self.getTraceOrCreate() 100bf9f21a2SWalter Erquinigo thread = thread if thread is not None else self.thread() 10104195843SWalter Erquinigo configuration = self.createConfiguration( 1022238dcc3SJonas Devlieghere iptTraceSize=iptTraceSize, enableTsc=enableTsc, psbPeriod=psbPeriod 1032238dcc3SJonas Devlieghere ) 104bf9f21a2SWalter Erquinigo self.assertSBError(trace.Start(thread, configuration), error) 105bf9f21a2SWalter Erquinigo else: 106bf9f21a2SWalter Erquinigo command = "thread trace start" 107bf9f21a2SWalter Erquinigo if thread is not None: 108bf9f21a2SWalter Erquinigo command += " " + str(thread.GetIndexID()) 1096a5355e8SWalter Erquinigo if iptTraceSize is not None: 1106a5355e8SWalter Erquinigo command += " -s " + str(iptTraceSize) 11104195843SWalter Erquinigo if enableTsc: 11204195843SWalter Erquinigo command += " --tsc" 11304195843SWalter Erquinigo if psbPeriod is not None: 11404195843SWalter Erquinigo command += " --psb-period " + str(psbPeriod) 115bf9f21a2SWalter Erquinigo self.expect(command, error=error, substrs=substrs) 116bf9f21a2SWalter Erquinigo 1172238dcc3SJonas Devlieghere def traceStartProcess( 1182238dcc3SJonas Devlieghere self, 1192238dcc3SJonas Devlieghere processBufferSizeLimit=None, 1202238dcc3SJonas Devlieghere error=False, 1212238dcc3SJonas Devlieghere substrs=None, 1222238dcc3SJonas Devlieghere enableTsc=False, 1232238dcc3SJonas Devlieghere psbPeriod=None, 1242238dcc3SJonas Devlieghere perCpuTracing=False, 1252238dcc3SJonas Devlieghere ): 126bf9f21a2SWalter Erquinigo if self.USE_SB_API: 127bf9f21a2SWalter Erquinigo trace = self.getTraceOrCreate() 12804195843SWalter Erquinigo configuration = self.createConfiguration( 1292238dcc3SJonas Devlieghere processBufferSizeLimit=processBufferSizeLimit, 1302238dcc3SJonas Devlieghere enableTsc=enableTsc, 1312238dcc3SJonas Devlieghere psbPeriod=psbPeriod, 1322238dcc3SJonas Devlieghere perCpuTracing=perCpuTracing, 1332238dcc3SJonas Devlieghere ) 134bf9f21a2SWalter Erquinigo self.assertSBError(trace.Start(configuration), error=error) 135bf9f21a2SWalter Erquinigo else: 136bf9f21a2SWalter Erquinigo command = "process trace start" 137*58611451SEisuke Kawashima if processBufferSizeLimit is not None: 138bf9f21a2SWalter Erquinigo command += " -l " + str(processBufferSizeLimit) 13904195843SWalter Erquinigo if enableTsc: 14004195843SWalter Erquinigo command += " --tsc" 14104195843SWalter Erquinigo if psbPeriod is not None: 14204195843SWalter Erquinigo command += " --psb-period " + str(psbPeriod) 1436a5355e8SWalter Erquinigo if perCpuTracing: 1446a5355e8SWalter Erquinigo command += " --per-cpu-tracing" 145bf9f21a2SWalter Erquinigo self.expect(command, error=error, substrs=substrs) 146bf9f21a2SWalter Erquinigo 147bf9f21a2SWalter Erquinigo def traceStopProcess(self): 148bf9f21a2SWalter Erquinigo if self.USE_SB_API: 149bf9f21a2SWalter Erquinigo self.assertSuccess(self.target().GetTrace().Stop()) 150bf9f21a2SWalter Erquinigo else: 151bf9f21a2SWalter Erquinigo self.expect("process trace stop") 152bf9f21a2SWalter Erquinigo 1531f49714dSWalter Erquinigo def traceStopThread(self, thread=None, error=False, substrs=None): 154bf9f21a2SWalter Erquinigo if self.USE_SB_API: 155bf9f21a2SWalter Erquinigo thread = thread if thread is not None else self.thread() 156bf9f21a2SWalter Erquinigo self.assertSBError(self.target().GetTrace().Stop(thread), error) 157bf9f21a2SWalter Erquinigo 158bf9f21a2SWalter Erquinigo else: 159bf9f21a2SWalter Erquinigo command = "thread trace stop" 160bf9f21a2SWalter Erquinigo if thread is not None: 161bf9f21a2SWalter Erquinigo command += " " + str(thread.GetIndexID()) 1621f49714dSWalter Erquinigo self.expect(command, error=error, substrs=substrs) 16350f93679SJakob Johnson 164b532dd54SWalter Erquinigo def traceLoad(self, traceDescriptionFilePath, error=False, substrs=None): 16550f93679SJakob Johnson if self.USE_SB_API: 16650f93679SJakob Johnson traceDescriptionFile = lldb.SBFileSpec(traceDescriptionFilePath, True) 16750f93679SJakob Johnson loadTraceError = lldb.SBError() 168b532dd54SWalter Erquinigo self.dbg.LoadTraceFromFile(loadTraceError, traceDescriptionFile) 16950f93679SJakob Johnson self.assertSBError(loadTraceError, error) 17050f93679SJakob Johnson else: 17150f93679SJakob Johnson command = f"trace load -v {traceDescriptionFilePath}" 17250f93679SJakob Johnson self.expect(command, error=error, substrs=substrs) 173b532dd54SWalter Erquinigo 174b532dd54SWalter Erquinigo def traceSave(self, traceBundleDir, compact=False, error=False, substrs=None): 175b532dd54SWalter Erquinigo if self.USE_SB_API: 176b532dd54SWalter Erquinigo save_error = lldb.SBError() 177b532dd54SWalter Erquinigo self.target().GetTrace().SaveToDisk( 1782238dcc3SJonas Devlieghere save_error, lldb.SBFileSpec(traceBundleDir), compact 1792238dcc3SJonas Devlieghere ) 180b532dd54SWalter Erquinigo self.assertSBError(save_error, error) 181b532dd54SWalter Erquinigo else: 182b532dd54SWalter Erquinigo command = f"trace save {traceBundleDir}" 183b532dd54SWalter Erquinigo if compact: 184b532dd54SWalter Erquinigo command += " -c" 185b532dd54SWalter Erquinigo self.expect(command, error=error, substrs=substrs) 186