diff options
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 |