aboutsummaryrefslogtreecommitdiff
path: root/lldb/packages/Python/lldbsuite
diff options
context:
space:
mode:
authorWalter Erquinigo <wallace@fb.com>2021-06-01 15:34:06 -0700
committerWalter Erquinigo <wallace@fb.com>2021-06-17 15:14:47 -0700
commitbf9f21a28be171dc500cc68b4cb1fcd3fc33f229 (patch)
tree15fe415b67514d3e546353eea9ed6b208bcf65ae /lldb/packages/Python/lldbsuite
parentc1360fd5fced42ea45ce1eacbf1c5e1ed54fcac5 (diff)
downloadllvm-bf9f21a28be171dc500cc68b4cb1fcd3fc33f229.zip
llvm-bf9f21a28be171dc500cc68b4cb1fcd3fc33f229.tar.gz
llvm-bf9f21a28be171dc500cc68b4cb1fcd3fc33f229.tar.bz2
[trace][intel-pt] Create basic SB API
This adds a basic SB API for creating and stopping traces. Note: This doesn't add any APIs for inspecting individual instructions. That'd be a more complicated change and it might be better to enhande the dump functionality to output the data in binary format. I'll leave that for a later diff. This also enhances the existing tests so that they test the same flow using both the command interface and the SB API. I also did some cleanup of legacy code. Differential Revision: https://reviews.llvm.org/D103500
Diffstat (limited to 'lldb/packages/Python/lldbsuite')
-rw-r--r--lldb/packages/Python/lldbsuite/test/dotest.py6
-rw-r--r--lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py99
2 files changed, 104 insertions, 1 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index dc46f21..3e832d9 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -477,6 +477,7 @@ def setupSysPath():
pluginPath = os.path.join(scriptPath, 'plugins')
toolsLLDBVSCode = os.path.join(scriptPath, 'tools', 'lldb-vscode')
toolsLLDBServerPath = os.path.join(scriptPath, 'tools', 'lldb-server')
+ intelpt = os.path.join(scriptPath, 'tools', 'intelpt')
# Insert script dir, plugin dir and lldb-server dir to the sys.path.
sys.path.insert(0, pluginPath)
@@ -484,8 +485,11 @@ def setupSysPath():
# "import lldb_vscode_testcase" from the VSCode tests
sys.path.insert(0, toolsLLDBVSCode)
# Adding test/tools/lldb-server to the path makes it easy
- sys.path.insert(0, toolsLLDBServerPath)
# to "import lldbgdbserverutils" from the lldb-server tests
+ sys.path.insert(0, toolsLLDBServerPath)
+ # Adding test/tools/intelpt to the path makes it easy
+ # to "import intelpt_testcase" from the lldb-server tests
+ sys.path.insert(0, intelpt)
# This is the root of the lldb git/svn checkout
# When this changes over to a package instead of a standalone script, this
diff --git a/lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py
new file mode 100644
index 0000000..2b7dfb1
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py
@@ -0,0 +1,99 @@
+from lldbsuite.test.lldbtest import *
+import os
+import time
+import json
+
+ADDRESS_REGEX = '0x[0-9a-fA-F]*'
+
+# Decorator that runs a test with both modes of USE_SB_API.
+# It assumes that no tests can be executed in parallel.
+def testSBAPIAndCommands(func):
+ def wrapper(*args, **kwargs):
+ TraceIntelPTTestCaseBase.USE_SB_API = True
+ func(*args, **kwargs)
+ TraceIntelPTTestCaseBase.USE_SB_API = False
+ func(*args, **kwargs)
+ return wrapper
+
+# Class that should be used by all python Intel PT tests.
+#
+# It has a handy check that skips the test if the intel-pt plugin is not enabled.
+#
+# It also contains many functions that can test both the SB API or the command line version
+# of the most important tracing actions.
+class TraceIntelPTTestCaseBase(TestBase):
+
+ NO_DEBUG_INFO_TESTCASE = True
+
+ # If True, the trace test methods will use the SB API, otherwise they'll use raw commands.
+ USE_SB_API = False
+
+ def setUp(self):
+ TestBase.setUp(self)
+ if 'intel-pt' not in configuration.enabled_plugins:
+ self.skipTest("The intel-pt test plugin is not enabled")
+
+ def getTraceOrCreate(self):
+ if not self.target().GetTrace().IsValid():
+ error = lldb.SBError()
+ self.target().CreateTrace(error)
+ return self.target().GetTrace()
+
+ def assertSBError(self, sberror, error=False):
+ if error:
+ self.assertTrue(sberror.Fail())
+ else:
+ self.assertSuccess(sberror)
+
+ def createConfiguration(self, threadBufferSize=None, processBufferSizeLimit=None):
+ obj = {}
+ if processBufferSizeLimit is not None:
+ obj["processBufferSizeLimit"] = processBufferSizeLimit
+ if threadBufferSize is not None:
+ obj["threadBufferSize"] = threadBufferSize
+
+ configuration = lldb.SBStructuredData()
+ configuration.SetFromJSON(json.dumps(obj))
+ return configuration
+
+ def traceStartThread(self, thread=None, error=False, substrs=None, threadBufferSize=None):
+ if self.USE_SB_API:
+ trace = self.getTraceOrCreate()
+ thread = thread if thread is not None else self.thread()
+ configuration = self.createConfiguration(threadBufferSize=threadBufferSize)
+ self.assertSBError(trace.Start(thread, configuration), error)
+ else:
+ command = "thread trace start"
+ if thread is not None:
+ command += " " + str(thread.GetIndexID())
+ if threadBufferSize is not None:
+ command += " -s " + str(threadBufferSize)
+ self.expect(command, error=error, substrs=substrs)
+
+ def traceStartProcess(self, processBufferSizeLimit=None, error=False, substrs=None):
+ if self.USE_SB_API:
+ trace = self.getTraceOrCreate()
+ configuration = self.createConfiguration(processBufferSizeLimit=processBufferSizeLimit)
+ self.assertSBError(trace.Start(configuration), error=error)
+ else:
+ command = "process trace start"
+ if processBufferSizeLimit != None:
+ command += " -l " + str(processBufferSizeLimit)
+ self.expect(command, error=error, substrs=substrs)
+
+ def traceStopProcess(self):
+ if self.USE_SB_API:
+ self.assertSuccess(self.target().GetTrace().Stop())
+ else:
+ self.expect("process trace stop")
+
+ def traceStopThread(self, thread=None, error=False):
+ if self.USE_SB_API:
+ thread = thread if thread is not None else self.thread()
+ self.assertSBError(self.target().GetTrace().Stop(thread), error)
+
+ else:
+ command = "thread trace stop"
+ if thread is not None:
+ command += " " + str(thread.GetIndexID())
+ self.expect(command, error=error)