aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Commands/CommandObjectThread.cpp
diff options
context:
space:
mode:
authorWalter Erquinigo <a20012251@gmail.com>2020-11-09 13:36:26 -0800
committerWalter Erquinigo <a20012251@gmail.com>2021-03-30 17:31:37 -0700
commit0b69756110db444282c40ea16929186b2910c3b1 (patch)
tree328177fba14ef2d43aa597e6274f536d4c44caed /lldb/source/Commands/CommandObjectThread.cpp
parentc23ee7718ea4f9292622af3d80efe2491eb2a506 (diff)
downloadllvm-0b69756110db444282c40ea16929186b2910c3b1.zip
llvm-0b69756110db444282c40ea16929186b2910c3b1.tar.gz
llvm-0b69756110db444282c40ea16929186b2910c3b1.tar.bz2
[trace][intel-pt] Implement trace start and trace stop
This implements the interactive trace start and stop methods. This diff ended up being much larger than I anticipated because, by doing it, I found that I had implemented in the beginning many things in a non optimal way. In any case, the code is much better now. There's a lot of boilerplate code due to the gdb-remote protocol, but the main changes are: - New tracing packets: jLLDBTraceStop, jLLDBTraceStart, jLLDBTraceGetBinaryData. The gdb-remote packet definitions are quite comprehensive. - Implementation of the "process trace start|stop" and "thread trace start|stop" commands. - Implementaiton of an API in Trace.h to interact with live traces. - Created an IntelPTDecoder for live threads, that use the debugger's stop id as checkpoint for its internal cache. - Added a functionality to stop the process in case "process tracing" is enabled and a new thread can't traced. - Added tests I have some ideas to unify the code paths for post mortem and live threads, but I'll do that in another diff. Differential Revision: https://reviews.llvm.org/D91679
Diffstat (limited to 'lldb/source/Commands/CommandObjectThread.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectThread.cpp94
1 files changed, 26 insertions, 68 deletions
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index f4ce5cc..a88fda9 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -11,6 +11,7 @@
#include <sstream>
#include "CommandObjectThreadUtil.h"
+#include "CommandObjectTrace.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Host/OptionParser.h"
@@ -1978,75 +1979,34 @@ public:
// CommandObjectTraceStart
-/// This class works by delegating the logic to the actual trace plug-in that
-/// can support the current process.
-class CommandObjectTraceStart : public CommandObjectProxy {
+class CommandObjectTraceStart : public CommandObjectTraceProxy {
public:
CommandObjectTraceStart(CommandInterpreter &interpreter)
- : CommandObjectProxy(interpreter, "thread trace start",
- "Start tracing threads with the corresponding trace "
- "plug-in for the current process.",
- "thread trace start [<trace-options>]") {}
+ : CommandObjectTraceProxy(
+ /*live_debug_session_only*/ true, interpreter, "thread trace start",
+ "Start tracing threads with the corresponding trace "
+ "plug-in for the current process.",
+ "thread trace start [<trace-options>]") {}
protected:
- llvm::Expected<CommandObjectSP> DoGetProxyCommandObject() {
- ProcessSP process_sp = m_interpreter.GetExecutionContext().GetProcessSP();
-
- if (!process_sp)
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "Process not available.");
- if (!process_sp->IsAlive())
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "Process must be launched.");
-
- llvm::Expected<TraceTypeInfo> trace_type =
- process_sp->GetSupportedTraceType();
-
- if (!trace_type)
- return llvm::createStringError(
- llvm::inconvertibleErrorCode(), "Tracing is not supported. %s",
- llvm::toString(trace_type.takeError()).c_str());
-
- CommandObjectSP delegate_sp =
- PluginManager::GetTraceStartCommand(trace_type->name, m_interpreter);
- if (!delegate_sp)
- return llvm::createStringError(
- llvm::inconvertibleErrorCode(),
- "No trace plug-in matches the specified type: \"%s\"",
- trace_type->name.c_str());
- return delegate_sp;
+ lldb::CommandObjectSP GetDelegateCommand(Trace &trace) override {
+ return trace.GetThreadTraceStartCommand(m_interpreter);
}
-
- CommandObject *GetProxyCommandObject() override {
- if (llvm::Expected<CommandObjectSP> delegate = DoGetProxyCommandObject()) {
- m_delegate_sp = *delegate;
- m_delegate_error.clear();
- return m_delegate_sp.get();
- } else {
- m_delegate_sp.reset();
- m_delegate_error = llvm::toString(delegate.takeError());
- return nullptr;
- }
- }
-
-private:
- llvm::StringRef GetUnsupportedError() override { return m_delegate_error; }
-
- CommandObjectSP m_delegate_sp;
- std::string m_delegate_error;
};
// CommandObjectTraceStop
-class CommandObjectTraceStop : public CommandObjectIterateOverThreads {
+class CommandObjectTraceStop : public CommandObjectMultipleThreads {
public:
CommandObjectTraceStop(CommandInterpreter &interpreter)
- : CommandObjectIterateOverThreads(
+ : CommandObjectMultipleThreads(
interpreter, "thread trace stop",
- "Stop tracing threads. "
+ "Stop tracing threads, including the ones traced with the "
+ "\"process trace start\" command."
"Defaults to the current thread. Thread indices can be "
- "specified as arguments.\n Use the thread-index \"all\" to trace "
- "all threads.",
+ "specified as arguments.\n Use the thread-index \"all\" to stop "
+ "tracing "
+ "for all existing threads.",
"thread trace stop [<thread-index> <thread-index> ...]",
eCommandRequiresProcess | eCommandTryTargetAPILock |
eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
@@ -2054,20 +2014,18 @@ public:
~CommandObjectTraceStop() override = default;
- bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
- const Thread &thread =
- *m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
- Trace &trace = *m_exe_ctx.GetTargetSP()->GetTrace();
+ bool DoExecuteOnThreads(Args &command, CommandReturnObject &result,
+ const std::vector<lldb::tid_t> &tids) override {
+ ProcessSP process_sp = m_exe_ctx.GetProcessSP();
- if (llvm::Error err = trace.StopTracingThread(thread)) {
- result.AppendErrorWithFormat("Failed stopping thread %" PRIu64 ": %s\n",
- tid, toString(std::move(err)).c_str());
- result.SetStatus(eReturnStatusFailed);
- }
+ TraceSP trace_sp = process_sp->GetTarget().GetTrace();
- // We don't return false on errors to try to stop as many threads as
- // possible.
- return true;
+ if (llvm::Error err = trace_sp->StopThreads(tids))
+ result.SetError(toString(std::move(err)));
+ else
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
+ return result.Succeeded();
}
};