xref: /llvm-project/lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py (revision b8d1776fc58d56af30d446386788e377d25dd512)
1from lldbsuite.test.lldbtest import *
2import os
3import time
4import json
5
6ADDRESS_REGEX = '0x[0-9a-fA-F]*'
7
8# Decorator that runs a test with both modes of USE_SB_API.
9# It assumes that no tests can be executed in parallel.
10def testSBAPIAndCommands(func):
11    def wrapper(*args, **kwargs):
12        TraceIntelPTTestCaseBase.USE_SB_API = True
13        func(*args, **kwargs)
14        TraceIntelPTTestCaseBase.USE_SB_API = False
15        func(*args, **kwargs)
16    return wrapper
17
18# Class that should be used by all python Intel PT tests.
19#
20# It has a handy check that skips the test if the intel-pt plugin is not enabled.
21#
22# It also contains many functions that can test both the SB API or the command line version
23# of the most important tracing actions.
24class TraceIntelPTTestCaseBase(TestBase):
25
26    NO_DEBUG_INFO_TESTCASE = True
27
28    # If True, the trace test methods will use the SB API, otherwise they'll use raw commands.
29    USE_SB_API = False
30
31    def setUp(self):
32        TestBase.setUp(self)
33        if 'intel-pt' not in configuration.enabled_plugins:
34            self.skipTest("The intel-pt test plugin is not enabled")
35
36    def getTraceOrCreate(self):
37        if not self.target().GetTrace().IsValid():
38            error = lldb.SBError()
39            self.target().CreateTrace(error)
40        return self.target().GetTrace()
41
42    def assertSBError(self, sberror, error=False):
43        if error:
44            self.assertTrue(sberror.Fail())
45        else:
46            self.assertSuccess(sberror)
47
48    def createConfiguration(self, traceBufferSize=None,
49                            processBufferSizeLimit=None, enableTsc=False,
50                            psbPeriod=None, perCoreTracing=False):
51        obj = {}
52        if processBufferSizeLimit is not None:
53            obj["processBufferSizeLimit"] = processBufferSizeLimit
54        if traceBufferSize is not None:
55            obj["traceBufferSize"] = traceBufferSize
56        if psbPeriod is not None:
57            obj["psbPeriod"] = psbPeriod
58        obj["enableTsc"] = enableTsc
59        obj["perCoreTracing"] = perCoreTracing
60
61        configuration = lldb.SBStructuredData()
62        configuration.SetFromJSON(json.dumps(obj))
63        return configuration
64
65    def traceStartThread(self, thread=None, error=False, substrs=None,
66                         traceBufferSize=None, enableTsc=False, psbPeriod=None):
67        if self.USE_SB_API:
68            trace = self.getTraceOrCreate()
69            thread = thread if thread is not None else self.thread()
70            configuration = self.createConfiguration(
71                traceBufferSize=traceBufferSize, enableTsc=enableTsc,
72                psbPeriod=psbPeriod)
73            self.assertSBError(trace.Start(thread, configuration), error)
74        else:
75            command = "thread trace start"
76            if thread is not None:
77                command += " " + str(thread.GetIndexID())
78            if traceBufferSize is not None:
79                command += " -s " + str(traceBufferSize)
80            if enableTsc:
81                command += " --tsc"
82            if psbPeriod is not None:
83                command += " --psb-period " + str(psbPeriod)
84            self.expect(command, error=error, substrs=substrs)
85
86    def traceStartProcess(self, processBufferSizeLimit=None, error=False,
87                          substrs=None, enableTsc=False, psbPeriod=None,
88                          perCoreTracing=False):
89        if self.USE_SB_API:
90            trace = self.getTraceOrCreate()
91            configuration = self.createConfiguration(
92                processBufferSizeLimit=processBufferSizeLimit, enableTsc=enableTsc,
93                psbPeriod=psbPeriod, perCoreTracing=perCoreTracing)
94            self.assertSBError(trace.Start(configuration), error=error)
95        else:
96            command = "process trace start"
97            if processBufferSizeLimit != None:
98                command += " -l " + str(processBufferSizeLimit)
99            if enableTsc:
100                command += " --tsc"
101            if psbPeriod is not None:
102                command += " --psb-period " + str(psbPeriod)
103            if perCoreTracing:
104                command += " --per-core-tracing"
105            self.expect(command, error=error, substrs=substrs)
106
107    def traceStopProcess(self):
108        if self.USE_SB_API:
109            self.assertSuccess(self.target().GetTrace().Stop())
110        else:
111            self.expect("process trace stop")
112
113    def traceStopThread(self, thread=None, error=False):
114        if self.USE_SB_API:
115            thread = thread if thread is not None else self.thread()
116            self.assertSBError(self.target().GetTrace().Stop(thread), error)
117
118        else:
119            command = "thread trace stop"
120            if thread is not None:
121                command += " " + str(thread.GetIndexID())
122            self.expect(command, error=error)
123