diff options
author | Glen Chung <kuchung@microsoft.com> | 2023-03-16 00:50:08 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2023-05-30 13:46:12 (GMT) |
commit | a9a592f96e6498da302f8e968be1db0ad3c32123 (patch) | |
tree | 0d75f16ee2eae99b1a3f063e575b3f5f8f2ee931 /Source/cmDebuggerThread.cxx | |
parent | b0d1ddb7234950374977b83f8dbded806c15b356 (diff) | |
download | CMake-a9a592f96e6498da302f8e968be1db0ad3c32123.zip CMake-a9a592f96e6498da302f8e968be1db0ad3c32123.tar.gz CMake-a9a592f96e6498da302f8e968be1db0ad3c32123.tar.bz2 |
cmake: Add debugger
- Depends on cppdap and jsoncpp.
- Add --debugger argument to enable the Debugger.
- Add --debugger-pipe argument for DAP traffics over named pipes.
- Support breakpoints by filenames and line numbers.
- Support exception breakpoints.
- Call stack shows filenames and line numbers.
- Show Cache Variables.
- Show the state of currently defined targets,
tests and directories with their properties.
- Add cmakeVersion to DAP initialize response.
- Include unit tests.
Co-authored-by: Ben McMorran <bemcmorr@microsoft.com>
Diffstat (limited to 'Source/cmDebuggerThread.cxx')
-rw-r--r-- | Source/cmDebuggerThread.cxx | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/Source/cmDebuggerThread.cxx b/Source/cmDebuggerThread.cxx new file mode 100644 index 0000000..fd52f5a --- /dev/null +++ b/Source/cmDebuggerThread.cxx @@ -0,0 +1,150 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmDebuggerThread.h" + +#include <cstdint> +#include <utility> + +#include <cm3p/cppdap/optional.h> +#include <cm3p/cppdap/types.h> + +#include "cmDebuggerStackFrame.h" +#include "cmDebuggerVariables.h" +#include "cmDebuggerVariablesHelper.h" +#include "cmDebuggerVariablesManager.h" + +namespace cmDebugger { + +cmDebuggerThread::cmDebuggerThread(int64_t id, std::string name) + : Id(id) + , Name(std::move(name)) + , VariablesManager(std::make_shared<cmDebuggerVariablesManager>()) +{ +} + +void cmDebuggerThread::PushStackFrame(cmMakefile* mf, + std::string const& sourcePath, + cmListFileFunction const& lff) +{ + std::unique_lock<std::mutex> lock(Mutex); + Frames.emplace_back( + std::make_shared<cmDebuggerStackFrame>(mf, sourcePath, lff)); + FrameMap.insert({ Frames.back()->GetId(), Frames.back() }); +} + +void cmDebuggerThread::PopStackFrame() +{ + std::unique_lock<std::mutex> lock(Mutex); + FrameMap.erase(Frames.back()->GetId()); + FrameScopes.erase(Frames.back()->GetId()); + FrameVariables.erase(Frames.back()->GetId()); + Frames.pop_back(); +} + +std::shared_ptr<cmDebuggerStackFrame> cmDebuggerThread::GetTopStackFrame() +{ + std::unique_lock<std::mutex> lock(Mutex); + if (!Frames.empty()) { + return Frames.back(); + } + + return {}; +} + +std::shared_ptr<cmDebuggerStackFrame> cmDebuggerThread::GetStackFrame( + int64_t frameId) +{ + std::unique_lock<std::mutex> lock(Mutex); + auto it = FrameMap.find(frameId); + + if (it == FrameMap.end()) { + return {}; + } + + return it->second; +} + +dap::ScopesResponse cmDebuggerThread::GetScopesResponse( + int64_t frameId, bool supportsVariableType) +{ + std::unique_lock<std::mutex> lock(Mutex); + auto it = FrameScopes.find(frameId); + + if (it != FrameScopes.end()) { + dap::ScopesResponse response; + response.scopes = it->second; + return response; + } + + auto it2 = FrameMap.find(frameId); + if (it2 == FrameMap.end()) { + return dap::ScopesResponse(); + } + + std::shared_ptr<cmDebuggerStackFrame> frame = it2->second; + std::shared_ptr<cmDebuggerVariables> localVariables = + cmDebuggerVariablesHelper::Create(VariablesManager, "Locals", + supportsVariableType, frame); + + FrameVariables[frameId].emplace_back(localVariables); + + dap::Scope scope; + scope.name = localVariables->GetName(); + scope.presentationHint = "locals"; + scope.variablesReference = localVariables->GetId(); + + dap::Source source; + source.name = frame->GetFileName(); + source.path = source.name; + scope.source = source; + + FrameScopes[frameId].push_back(scope); + + dap::ScopesResponse response; + response.scopes.push_back(scope); + return response; +} + +dap::VariablesResponse cmDebuggerThread::GetVariablesResponse( + dap::VariablesRequest const& request) +{ + std::unique_lock<std::mutex> lock(Mutex); + dap::VariablesResponse response; + response.variables = VariablesManager->HandleVariablesRequest(request); + return response; +} + +dap::StackTraceResponse GetStackTraceResponse( + std::shared_ptr<cmDebuggerThread> const& thread) +{ + dap::StackTraceResponse response; + std::unique_lock<std::mutex> lock(thread->Mutex); + for (int i = static_cast<int>(thread->Frames.size()) - 1; i >= 0; --i) { + dap::Source source; + source.name = thread->Frames[i]->GetFileName(); + source.path = source.name; + +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Warray-bounds" +#endif + dap::StackFrame stackFrame; +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + stackFrame.line = thread->Frames[i]->GetLine(); + stackFrame.column = 1; + stackFrame.name = thread->Frames[i]->GetFileName() + " Line " + + std::to_string(stackFrame.line); + stackFrame.id = thread->Frames[i]->GetId(); + stackFrame.source = source; + + response.stackFrames.push_back(stackFrame); + } + + response.totalFrames = response.stackFrames.size(); + return response; +} + +} // namespace cmDebugger |