| /* 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 |