You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
4.0 KiB
151 lines
4.0 KiB
1 year ago
|
/* 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
|