import lldb
import json
from intelpt_testcase import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
class TestTraceStartStopMultipleThreads(TraceIntelPTTestCaseBase):
@skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))
@testSBAPIAndCommands
def testStartMultipleLiveThreads(self):
self.build()
exe = self.getBuildArtifact("a.out")
self.dbg.CreateTarget(exe)
self.expect("b main")
self.expect("b 6")
self.expect("b 11")
self.expect("r")
self.traceStartProcess()
self.expect("continue")
self.expect("thread trace dump instructions", substrs=["main.cpp:9"])
self.expect("continue")
self.expect("thread trace dump instructions", substrs=["main.cpp:4"])
self.traceStopProcess()
@skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))
@testSBAPIAndCommands
def testStartMultipleLiveThreadsWithStops(self):
self.build()
exe = self.getBuildArtifact("a.out")
self.dbg.CreateTarget(exe)
self.expect("b main")
self.expect("b 6")
self.expect("b 11")
self.expect("r")
self.traceStartProcess()
self.expect("continue")
self.expect("thread trace dump instructions", substrs=["main.cpp:9"])
self.expect("thread trace dump instructions 2", substrs=["main.cpp:9"])
self.expect("thread trace stop all")
self.expect("thread trace dump instructions 2", substrs=["main.cpp:9"])
self.expect("continue")
self.expect("thread trace dump instructions", substrs=["main.cpp:4"])
self.expect("thread trace dump instructions 3", substrs=["main.cpp:4"])
self.expect(
"thread trace dump instructions 1", substrs=["not traced"], error=True
)
self.expect(
"thread trace dump instructions 2", substrs=["not traced"], error=True
)
self.traceStopProcess()
@skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))
def testStartMultipleLiveThreadsWithThreadStartAll(self):
self.build()
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)
self.expect("b main")
self.expect("b 6")
self.expect("b 11")
self.expect("r")
self.expect("continue")
self.expect("thread trace start all")
self.expect("n")
self.expect("thread trace dump instructions 2", substrs=["main.cpp:11"])
self.runCmd("thread trace stop all")
self.expect("thread trace dump instructions 2", substrs=["main.cpp:11"])
self.expect("continue")
self.expect(
"thread trace dump instructions 3", substrs=["not traced"], error=True
)
self.expect(
"thread trace dump instructions 1", substrs=["not traced"], error=True
)
self.expect(
"thread trace dump instructions 2", substrs=["not traced"], error=True
)
@skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))
@testSBAPIAndCommands
def testStartMultipleLiveThreadsWithSmallTotalLimit(self):
self.build()
exe = self.getBuildArtifact("a.out")
self.dbg.CreateTarget(exe)
self.expect("b main")
self.expect("r")
self.traceStartProcess(processBufferSizeLimit=5000)
self.expect("c", substrs=["Thread", "can't be traced"])
self.expect("c", substrs=["Thread", "can't be traced"])
self.traceStopProcess()
@skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))
@testSBAPIAndCommands
def testStartPerCpuSession(self):
self.skipIfPerCpuTracingIsNotSupported()
self.build()
exe = self.getBuildArtifact("a.out")
self.dbg.CreateTarget(exe)
self.expect("b main")
self.expect("r")
self.traceStartProcess(
error="True",
processBufferSizeLimit=100,
perCpuTracing=True,
substrs=[
"The process can't be traced because the process trace size "
"limit has been reached. Consider retracing with a higher limit."
],
)
self.traceStartProcess(perCpuTracing=True)
self.traceStopProcess()
self.traceStartProcess(perCpuTracing=True)
self.traceStartProcess(
error=True,
perCpuTracing=True,
substrs=["Process currently traced. Stop process tracing first"],
)
self.traceStartThread(
error="True", substrs=["Thread with tid ", "is currently traced"]
)
self.traceStopThread(
error="True",
substrs=[
"Can't stop tracing an individual thread when per-cpu process tracing is enabled"
],
)
self.expect("b 19")
self.expect("c")
self.runCmd(
"""process plugin packet send 'jLLDBTraceGetState:{"type":"intel-pt"}]'"""
)
response_header = "response: "
output = None
for line in self.res.GetOutput().splitlines():
if line.find(response_header) != -1:
response = line[
line.find(response_header) + len(response_header) :
].strip()
output = json.loads(response)
self.assertIsNotNone(output)
self.assertIn("cpus", output)
self.assertIn("tscPerfZeroConversion", output)
found_non_empty_context_switch = False
for cpu in output["cpus"]:
context_switch_size = None
ipt_trace_size = None
for binary_data in cpu["binaryData"]:
if binary_data["kind"] == "iptTrace":
ipt_trace_size = binary_data["size"]
elif binary_data["kind"] == "perfContextSwitchTrace":
context_switch_size = binary_data["size"]
self.assertIsNotNone(context_switch_size)
self.assertIsNotNone(ipt_trace_size)
if context_switch_size > 0:
found_non_empty_context_switch = True
self.assertTrue(found_non_empty_context_switch)
self.expect("thread trace dump instructions")
self.traceStopProcess()