diff options
author | Walter Erquinigo <a20012251@gmail.com> | 2020-11-09 13:36:26 -0800 |
---|---|---|
committer | Walter Erquinigo <a20012251@gmail.com> | 2021-03-30 17:31:37 -0700 |
commit | 0b69756110db444282c40ea16929186b2910c3b1 (patch) | |
tree | 328177fba14ef2d43aa597e6274f536d4c44caed /lldb/source/Commands/CommandObjectThread.cpp | |
parent | c23ee7718ea4f9292622af3d80efe2491eb2a506 (diff) | |
download | llvm-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.cpp | 94 |
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(); } }; |