Skip to content

Commit ff179dd

Browse files
committed
Pulsar-Debugger: Accept source.path in SetBreakpointsRequest and SourceRequest.
Also breakpoints are now correctly unverified for files not used by the running module, and VSCode shows breakpoints set outside of the debugging session.
1 parent b15a02d commit ff179dd

File tree

3 files changed

+83
-22
lines changed

3 files changed

+83
-22
lines changed

include/pulsar-debugger/types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ namespace PulsarDebugger
7474
std::optional<Pulsar::String> GetSourcePath(SourceReference sourceReference) const;
7575
std::optional<Pulsar::String> GetSourceContent(SourceReference sourceReference) const;
7676

77+
SourceReference FindSourceReferenceForPath(const char* path) const;
78+
7779
// TODO: This may be optimized by batching
7880
// void FilterReachableLines(SourceReference sourceReference, Pulsar::List<size_t>& lines) const;
7981

src/pulsar-debugger/dapserver.cpp

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -166,28 +166,54 @@ DAPServer::DAPServer(Session& session, LogFile logFile)
166166

167167
m_Session->registerHandler([this](const dap::SetBreakpointsRequest& req) -> dap::ResponseOrError<dap::SetBreakpointsResponse>
168168
{
169-
if (!req.source.sourceReference) {
170-
return dap::Error("Only source.sourceReference is supported for SetBreakpointsRequest.");
169+
auto debuggableModule = this->m_Debugger.GetModule();
170+
SourceReference sourceReference = req.source.sourceReference.value(NULL_REFERENCE);
171+
if (!req.source.sourceReference && req.source.path) {
172+
if (debuggableModule) {
173+
sourceReference = debuggableModule->FindSourceReferenceForPath(req.source.path->c_str());
174+
}
171175
}
172176

173177
dap::SetBreakpointsResponse res;
174-
this->m_Debugger.ClearBreakpoints(*req.source.sourceReference);
175-
176-
if (req.breakpoints) {
177-
res.breakpoints.resize(req.breakpoints->size());
178-
179-
for (size_t i = 0; i < req.breakpoints->size(); ++i) {
180-
const auto& reqBreakpoint = (*req.breakpoints)[i];
181-
auto& resBreakpoint = res.breakpoints[i];
182-
183-
auto breakpointError = this->m_Debugger.SetBreakpoint(
184-
*req.source.sourceReference,
185-
this->m_LinesStartAt1
186-
? static_cast<size_t>(reqBreakpoint.line-1)
187-
: static_cast<size_t>(reqBreakpoint.line));
188-
resBreakpoint.verified = !breakpointError;
189-
if (!resBreakpoint.verified)
190-
resBreakpoint.message = breakpointError->CString();
178+
if (sourceReference == NULL_REFERENCE) {
179+
if (req.breakpoints) {
180+
res.breakpoints.resize(req.breakpoints->size());
181+
182+
for (size_t i = 0; i < req.breakpoints->size(); ++i) {
183+
auto& resBreakpoint = res.breakpoints[i];
184+
resBreakpoint.verified = false;
185+
resBreakpoint.message = "Source not loaded.";
186+
}
187+
}
188+
} else {
189+
this->m_Debugger.ClearBreakpoints(sourceReference);
190+
191+
if (req.breakpoints) {
192+
res.breakpoints.resize(req.breakpoints->size());
193+
194+
for (size_t i = 0; i < req.breakpoints->size(); ++i) {
195+
const auto& reqBreakpoint = (*req.breakpoints)[i];
196+
auto& resBreakpoint = res.breakpoints[i];
197+
198+
if (debuggableModule) {
199+
dap::Source breakpointSource;
200+
breakpointSource.path = debuggableModule->GetSourcePath(sourceReference)->CString();
201+
breakpointSource.sourceReference = sourceReference;
202+
resBreakpoint.source = std::move(breakpointSource);
203+
}
204+
205+
auto breakpointError = this->m_Debugger.SetBreakpoint(
206+
sourceReference,
207+
this->m_LinesStartAt1
208+
? static_cast<size_t>(reqBreakpoint.line-1)
209+
: static_cast<size_t>(reqBreakpoint.line));
210+
211+
resBreakpoint.verified = !breakpointError;
212+
if (!resBreakpoint.verified) {
213+
resBreakpoint.reason = "failed";
214+
resBreakpoint.message = breakpointError->CString();
215+
}
216+
}
191217
}
192218
}
193219

@@ -231,13 +257,31 @@ DAPServer::DAPServer(Session& session, LogFile logFile)
231257

232258
m_Session->registerHandler([this](const dap::SourceRequest& req) -> dap::ResponseOrError<dap::SourceResponse>
233259
{
234-
auto source = this->GetSourceContent(req.sourceReference);
260+
auto debuggableModule = this->m_Debugger.GetModule();
261+
if (!debuggableModule) {
262+
return dap::Error("No module is being debugged.");
263+
}
264+
265+
SourceReference sourceReference = req.sourceReference;
266+
if (req.source) {
267+
if (req.source->sourceReference) {
268+
sourceReference = *req.source->sourceReference;
269+
} else if (req.source->path) {
270+
sourceReference = debuggableModule->FindSourceReferenceForPath(req.source->path->c_str());
271+
}
272+
}
273+
274+
if (sourceReference == NULL_REFERENCE) {
275+
return dap::Error("Could not find source.");
276+
}
277+
278+
auto source = debuggableModule->GetSourceContent(sourceReference);
235279
if (!source) {
236-
return dap::Error("Unknown source reference '%d'.", int(req.sourceReference));
280+
return dap::Error("Unknown source reference '%d'.", int(sourceReference));
237281
}
238282

239283
dap::SourceResponse res;
240-
res.content = std::move(*source);
284+
res.content = source->CString();
241285
return res;
242286
});
243287

src/pulsar-debugger/types.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "pulsar-debugger/types.h"
22

3+
#include <filesystem>
4+
35
namespace PulsarDebugger
46
{
57

@@ -143,4 +145,17 @@ std::optional<Pulsar::String> DebuggableModule::GetSourceContent(SourceReference
143145
return m_Module.SourceDebugSymbols[sourceReference].Source;
144146
}
145147

148+
SourceReference DebuggableModule::FindSourceReferenceForPath(const char* path) const
149+
{
150+
std::filesystem::path pathToSearch(path);
151+
for (size_t uSourceReference = 0; uSourceReference < m_Module.SourceDebugSymbols.Size(); ++uSourceReference) {
152+
std::filesystem::path candidatePath(m_Module.SourceDebugSymbols[uSourceReference].Path.CString());
153+
154+
std::error_code ec;
155+
if (std::filesystem::equivalent(pathToSearch, candidatePath, ec) && !ec)
156+
return static_cast<SourceReference>(uSourceReference);
157+
}
158+
return NULL_REFERENCE;
159+
}
160+
146161
}

0 commit comments

Comments
 (0)