summaryrefslogtreecommitdiffstats
path: root/Source/cmDebuggerThread.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmDebuggerThread.cxx')
-rw-r--r--Source/cmDebuggerThread.cxx150
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