Files
clang-p2996/lldb/test/API/commands/trace/TestTraceStartStop.py
Walter Erquinigo fb19f11ef4 [trace][intel-pt] Scaffold the 'thread trace start | stop' commands
Depends on D90490.

The stop command is simple and invokes the new method Trace::StopTracingThread(thread).

On the other hand, the start command works by delegating its implementation to a CommandObject provided by the Trace plugin. This is necessary because each trace plugin needs different options for this command. There's even the chance that a Trace plugin can't support live tracing, but instead supports offline decoding and analysis, which means that "thread trace dump instructions" works but "thread trace start" doest. Because of this and a few other reasons, it's better to have each plugin provide this implementation.

Besides, I'm using the GetSupportedTraceType method introduced in D90490 to quickly infer what's the trace plug-in that works for the current process.

As an implementation note, I moved CommandObjectIterateOverThreads to its header so that I can use it from the IntelPT plugin. Besides, the actual start and stop logic for intel-pt is not part of this diff.

Reviewed By: clayborg

Differential Revision: https://reviews.llvm.org/D90729
2020-11-18 18:24:36 -08:00

74 lines
3.0 KiB
Python

import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
class TestTraceLoad(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
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 expectGenericHelpMessageForStartCommand(self):
self.expect("help thread trace start",
substrs=["Syntax: thread trace start [<trace-options>]"])
def testStartStopSessionFileThreads(self):
# it should fail for processes from json session files
self.expect("trace load -v " + os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"))
self.expect("thread trace start", error=True,
substrs=["error: Tracing is not supported. Can't trace a non-live process"])
# the help command should be the generic one, as it's not a live process
self.expectGenericHelpMessageForStartCommand()
# this should fail because 'trace stop' is not yet implemented
self.expect("thread trace stop", error=True,
substrs=["error: Failed stopping thread 3842849"])
@skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
def testStartStopLiveThreads(self):
# The help command should be the generic one if there's no process running
self.expectGenericHelpMessageForStartCommand()
self.expect("thread trace start", error=True,
substrs=["error: Process not available"])
self.expect("file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
self.expect("b main")
self.expect("thread trace start", error=True,
substrs=["error: Process not available"])
# The help command should be the generic one if there's still no process running
self.expectGenericHelpMessageForStartCommand()
self.expect("r")
# the help command should be the intel-pt one now
self.expect("help thread trace start",
substrs=["Start tracing one or more threads with intel-pt.",
"Syntax: thread trace start [<thread-index> <thread-index> ...] [<intel-pt-options>]"])
self.expect("thread trace start",
patterns=["would trace tid .* with size_in_kb 4 and custom_config 0"])
self.expect("thread trace start --size 20 --custom-config 1",
patterns=["would trace tid .* with size_in_kb 20 and custom_config 1"])
# This fails because "trace stop" is not yet implemented.
self.expect("thread trace stop", error=True,
substrs=["error: Process is not being traced"])
self.expect("c")
# Now the process has finished, so the commands should fail
self.expect("thread trace start", error=True,
substrs=["error: Process must be launched"])
self.expect("thread trace stop", error=True,
substrs=["error: Process must be launched"])