Skip to content

Commit

Permalink
More DAP WIP.
Browse files Browse the repository at this point in the history
  • Loading branch information
SpartanJ committed Dec 19, 2024
1 parent adcf1e2 commit 09d8067
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 70 deletions.
229 changes: 172 additions & 57 deletions src/tools/ecode/plugins/debugger/dap/debuggerclientdap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,16 @@ void DebuggerClientDap::makeRequest( const std::string_view& command,
mIdx.fetch_add( 1, std::memory_order_relaxed );
}

bool DebuggerClientDap::hasBreakpoint( const std::string& path, size_t line ) {
return false;
}

bool DebuggerClientDap::addBreakpoint( const std::string& path, size_t line ) {
return false;
}

bool DebuggerClientDap::removeBreakpoint( const std::string& path, size_t line ) {
return false;
}

bool DebuggerClientDap::isServerConnected() const {
return ( mState != State::None ) && ( mState != State::Failed ) &&
( mBus->state() == Bus::State::Running );
}

bool DebuggerClientDap::supportsTerminate() const {
return mAdapterCapabilities.supportsTerminateRequest &&
( mProtocol.launchRequest.value( DAP_COMMAND, "" ) == DAP_LAUNCH );
}

bool DebuggerClientDap::start() {
bool started = mBus->start();
if ( started )
Expand Down Expand Up @@ -111,7 +104,7 @@ void DebuggerClientDap::requestLaunchCommand() {
return;

makeRequest( mLaunchCommand, mProtocol.launchRequest,
[this]( const auto& response, const auto& body ) {
[this]( const Response& response, const auto& body ) {
if ( response.success ) {
mLaunched = true;
for ( auto client : mClients )
Expand Down Expand Up @@ -272,38 +265,45 @@ void DebuggerClientDap::processEventExited( const nlohmann::json& body ) {
}

void DebuggerClientDap::processEventOutput( const nlohmann::json& body ) {
Output output( body );
for ( auto client : mClients )
client->outputProduced( Output( body ) );
client->outputProduced( output );
}

void DebuggerClientDap::processEventProcess( const nlohmann::json& body ) {
ProcessInfo processInfo( body );
for ( auto client : mClients )
client->debuggingProcess( ProcessInfo( body ) );
client->debuggingProcess( processInfo );
}

void DebuggerClientDap::processEventThread( const nlohmann::json& body ) {
ThreadEvent threadEvent( body );
for ( auto client : mClients )
client->threadChanged( ThreadEvent( body ) );
client->threadChanged( threadEvent );
}

void DebuggerClientDap::processEventStopped( const nlohmann::json& body ) {
StoppedEvent stoppedEvent( body );
for ( auto client : mClients )
client->debuggeeStopped( StoppedEvent( body ) );
client->debuggeeStopped( stoppedEvent );
}

void DebuggerClientDap::processEventModule( const nlohmann::json& body ) {
ModuleEvent moduleEvent( body );
for ( auto client : mClients )
client->moduleChanged( ModuleEvent( body ) );
client->moduleChanged( moduleEvent );
}

void DebuggerClientDap::processEventContinued( const nlohmann::json& body ) {
ContinuedEvent continuedEvent( body );
for ( auto client : mClients )
client->debuggeeContinued( ContinuedEvent( body ) );
client->debuggeeContinued( continuedEvent );
}

void DebuggerClientDap::processEventBreakpoint( const nlohmann::json& body ) {
BreakpointEvent breakpointEvent( body );
for ( auto client : mClients )
client->breakpointChanged( BreakpointEvent( body ) );
client->breakpointChanged( breakpointEvent );
}

std::optional<DebuggerClientDap::HeaderInfo> DebuggerClientDap::readHeader() {
Expand Down Expand Up @@ -376,15 +376,16 @@ bool DebuggerClientDap::cont( int threadId, bool singleThread ) {
nlohmann::json arguments{ { DAP_THREAD_ID, threadId } };
if ( singleThread )
arguments[DAP_SINGLE_THREAD] = true;
makeRequest( "continue", arguments, [this]( const auto& response, const auto& request ) {
if ( response.success ) {
for ( auto client : mClients ) {
client->debuggeeContinued(
ContinuedEvent( request.value( DAP_THREAD_ID, 1 ),
response.body.value( DAP_ALL_THREADS_CONTINUED, true ) ) );
}
}
} );
makeRequest( "continue", arguments,
[this]( const Response& response, const nlohmann::json& request ) {
if ( response.success ) {
ContinuedEvent continuedEvent(
request.value( DAP_THREAD_ID, 1 ),
response.body.value( DAP_ALL_THREADS_CONTINUED, true ) );
for ( auto client : mClients )
client->debuggeeContinued( continuedEvent );
}
} );
return true;
}

Expand All @@ -397,10 +398,10 @@ bool DebuggerClientDap::pause( int threadId ) {
void DebuggerClientDap::processResponseNext( const Response& response,
const nlohmann::json& request ) {
if ( response.success ) {
ContinuedEvent continuedEvent( request.value( DAP_THREAD_ID, 1 ),
!response.body.value( DAP_SINGLE_THREAD, false ) );
for ( auto client : mClients )
client->debuggeeContinued(
ContinuedEvent( request.value( DAP_THREAD_ID, 1 ),
!response.body.value( DAP_SINGLE_THREAD, false ) ) );
client->debuggeeContinued( continuedEvent );
}
}

Expand Down Expand Up @@ -451,42 +452,156 @@ bool DebuggerClientDap::disconnect( bool restart ) {
if ( restart )
arguments["restart"] = true;

makeRequest( "disconnect", arguments, [this]( const auto& response, const auto& request ) {
if ( response.success ) {
for ( auto client : mClients )
client->serverDisconnected();
}
} );
makeRequest( "disconnect", arguments,
[this]( const Response& response, const nlohmann::json& request ) {
if ( response.success ) {
for ( auto client : mClients )
client->serverDisconnected();
}
} );
return true;
}

bool DebuggerClientDap::threads() {
makeRequest( DAP_THREADS, {}, [this]( const auto& response, const auto& request ) {
if ( response.success ) {
for ( auto client : mClients )
client->threads( Thread::parseList( response.body[DAP_THREADS] ) );
} else {
for ( auto client : mClients )
client->threads( {} );
}
} );
makeRequest( DAP_THREADS, {},
[this]( const Response& response, const nlohmann::json& request ) {
if ( response.success ) {
auto threads( Thread::parseList( response.body[DAP_THREADS] ) );
for ( auto client : mClients )
client->threads( threads );
} else {
for ( auto client : mClients )
client->threads( {} );
}
} );
return true;
}

bool DebuggerClientDap::stackTrace( int threadId, int startFrame, int levels ) {
const nlohmann::json arguments{
{ DAP_THREAD_ID, threadId }, { "startFrame", startFrame }, { "levels", levels } };

makeRequest( "stackTrace", arguments, [this]( const auto& response, const auto& request ) {
const int threadId = request.value( DAP_THREAD_ID, 1 );
if ( response.success ) {
for ( auto client : mClients )
client->stackTrace( threadId, StackTraceInfo( response.body ) );
} else {
for ( auto client : mClients )
client->stackTrace( threadId, StackTraceInfo() );
}
} );
makeRequest( "stackTrace", arguments,
[this]( const Response& response, const nlohmann::json& request ) {
const int threadId = request.value( DAP_THREAD_ID, 1 );
if ( response.success ) {
StackTraceInfo stackTraceInfo( response.body );
for ( auto client : mClients )
client->stackTrace( threadId, stackTraceInfo );
} else {
StackTraceInfo stackTraceInfo;
for ( auto client : mClients )
client->stackTrace( threadId, stackTraceInfo );
}
} );
return true;
}

bool DebuggerClientDap::scopes( int frameId ) {
const nlohmann::json arguments{ { DAP_FRAME_ID, frameId } };
makeRequest( DAP_SCOPES, arguments,
[this]( const Response& response, const nlohmann::json& request ) {
const int frameId = request.value( DAP_FRAME_ID, 1 );
if ( response.success ) {
auto scopes( Scope::parseList( response.body[DAP_SCOPES] ) );
for ( auto client : mClients )
client->scopes( frameId, scopes );
} else {
std::vector<Scope> scopes;
for ( auto client : mClients )
client->scopes( frameId, scopes );
}
} );
return true;
}

bool DebuggerClientDap::variables( int variablesReference, Variable::Type filter, int start,
int count ) {
nlohmann::json arguments{
{ DAP_VARIABLES_REFERENCE, variablesReference },
{ DAP_START, start },
{ DAP_COUNT, count },
};

switch ( filter ) {
case Variable::Type::Indexed:
arguments[DAP_FILTER] = "indexed";
break;
case Variable::Type::Named:
arguments[DAP_FILTER] = "named";
break;
default:
break;
}

makeRequest( DAP_VARIABLES, arguments,
[this]( const Response& response, const nlohmann::json& request ) {
const int variablesReference = request.value( DAP_VARIABLES_REFERENCE, 0 );

if ( response.success ) {
auto variableList( Variable::parseList( response.body[DAP_VARIABLES] ) );
for ( auto client : mClients )
client->variables( variablesReference, variableList );
} else {
std::vector<Variable> variableList;
for ( auto client : mClients )
client->variables( variablesReference, variableList );
}
} );

return true;
}

bool DebuggerClientDap::setBreakpoints( const std::string& path,
const std::vector<dap::SourceBreakpoint> breakpoints,
bool sourceModified ) {
return setBreakpoints( Source( path ), breakpoints, sourceModified );
}

bool DebuggerClientDap::setBreakpoints( const dap::Source& source,
const std::vector<dap::SourceBreakpoint> breakpoints,
bool sourceModified ) {
nlohmann::json bpoints = nlohmann::json::array();
for ( const auto& item : breakpoints )
bpoints.push_back( item.toJson() );

nlohmann::json arguments{ { DAP_SOURCE, source.toJson() },
{ DAP_BREAKPOINTS, bpoints },
{ "sourceModified", sourceModified } };

makeRequest( "setBreakpoints", arguments,
[this]( const Response& response, const nlohmann::json& request ) {
const auto source = Source( request[DAP_SOURCE] );
if ( response.success ) {
const auto resp = response.body;
if ( resp.contains( DAP_BREAKPOINTS ) ) {
std::vector<Breakpoint> breakpoints;
breakpoints.reserve( resp[DAP_BREAKPOINTS].size() );
for ( const auto& item : resp[DAP_BREAKPOINTS] )
breakpoints.emplace_back( item );

for ( auto client : mClients )
client->sourceBreakpoints( source.path,
source.sourceReference.value_or( 0 ),
breakpoints );
} else {
std::vector<Breakpoint> breakpoints;
breakpoints.reserve( resp[DAP_LINES].size() );
for ( const auto& item : resp[DAP_LINES] )
breakpoints.emplace_back( item.get<int>() );

for ( auto client : mClients )
client->sourceBreakpoints( source.path,
source.sourceReference.value_or( 0 ),
breakpoints );
}
} else {
for ( auto client : mClients )
client->sourceBreakpoints(
source.path, source.sourceReference.value_or( 0 ), std::nullopt );
}
} );

return true;
}

Expand Down
20 changes: 14 additions & 6 deletions src/tools/ecode/plugins/debugger/dap/debuggerclientdap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@ class DebuggerClientDap : public DebuggerClient {

DebuggerClientDap( std::unique_ptr<Bus>&& bus );

bool hasBreakpoint( const std::string& path, size_t line ) override;

bool addBreakpoint( const std::string& path, size_t line ) override;

bool removeBreakpoint( const std::string& path, size_t line ) override;

bool start() override;

bool attach() override;
Expand All @@ -48,8 +42,22 @@ class DebuggerClientDap : public DebuggerClient {

bool stackTrace( int threadId, int startFrame, int levels ) override;

bool scopes( int frameId ) override;

bool variables( int variablesReference, Variable::Type filter, int start, int count );

bool isServerConnected() const override;

bool supportsTerminate() const override;

bool setBreakpoints( const std::string& path,
const std::vector<dap::SourceBreakpoint> breakpoints,
bool sourceModified = false ) override;

bool setBreakpoints( const dap::Source& source,
const std::vector<dap::SourceBreakpoint> breakpoints,
bool sourceModified = false ) override;

protected:
std::unique_ptr<Bus> mBus;
UnorderedMap<std::string, UnorderedSet<int>> mBreakpoints;
Expand Down
19 changes: 12 additions & 7 deletions src/tools/ecode/plugins/debugger/debuggerclient.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#pragma once
#include "dap/protocol.hpp"
#include <cstddef>
#include <string>

namespace ecode {
Expand Down Expand Up @@ -50,12 +49,6 @@ class DebuggerClient {

State state() const { return mState; }

virtual bool hasBreakpoint( const std::string& path, size_t line ) = 0;

virtual bool addBreakpoint( const std::string& path, size_t line ) = 0;

virtual bool removeBreakpoint( const std::string& path, size_t line ) = 0;

virtual bool start() = 0;

virtual bool attach() = 0;
Expand All @@ -80,8 +73,20 @@ class DebuggerClient {

virtual bool stackTrace( int threadId, int startFrame, int levels ) = 0;

virtual bool scopes( int frameId ) = 0;

virtual bool isServerConnected() const = 0;

virtual bool supportsTerminate() const = 0;

virtual bool setBreakpoints( const std::string& path,
const std::vector<dap::SourceBreakpoint> breakpoints,
bool sourceModified = false ) = 0;

virtual bool setBreakpoints( const dap::Source& source,
const std::vector<dap::SourceBreakpoint> breakpoints,
bool sourceModified = false ) = 0;

protected:
void setState( const State& state );

Expand Down

0 comments on commit 09d8067

Please sign in to comment.