Skip to content

Commit

Permalink
debugger fixes and improvements for macOS.
Browse files Browse the repository at this point in the history
  • Loading branch information
SpartanJ committed Jan 5, 2025
1 parent 0330f38 commit d73f1ea
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 29 deletions.
11 changes: 8 additions & 3 deletions bin/assets/plugins/debugger.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"name": "gdb",
"url": "https://www.gnu.org/software/gdb",
"run": {
"command": "gdb --interpreter=dap"
"command": "gdb",
"command_arguments": "--interpreter=dap"
},
"languages": [ "cpp", "c", "d", "go", "objectivec", "fortran", "pascal", "rust" ],
"configurations": [
Expand All @@ -23,10 +24,14 @@
]
},
{
"name": "lldb-dab",
"name": "lldb-dap",
"url": "https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md",
"run": {
"command": "lldb-dap"
"command": "lldb-dap",
"command_fallback": "lldb-vscode"
},
"find": {
"macos": "xcrun -f ${command}"
},
"languages": [ "cpp", "c", "odin", "rust", "zig" ],
"configurations": [
Expand Down
22 changes: 22 additions & 0 deletions projects/macos/ee.files
Original file line number Diff line number Diff line change
Expand Up @@ -1563,11 +1563,32 @@
../../src/tools/ecode/macos/macos.m
../../src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp
../../src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp
../../src/tools/ecode/plugins/debugger/bus.cpp
../../src/tools/ecode/plugins/debugger/bus.hpp
../../src/tools/ecode/plugins/debugger/busprocess.cpp
../../src/tools/ecode/plugins/debugger/busprocess.hpp
../../src/tools/ecode/plugins/debugger/bussocket.cpp
../../src/tools/ecode/plugins/debugger/bussocket.hpp
../../src/tools/ecode/plugins/debugger/config.cpp
../../src/tools/ecode/plugins/debugger/config.hpp
../../src/tools/ecode/plugins/debugger/dap/debuggerclientdap.hpp
../../src/tools/ecode/plugins/debugger/dap/messages.hpp
../../src/tools/ecode/plugins/debugger/dap/protocol.cpp
../../src/tools/ecode/plugins/debugger/dap/protocol.hpp
../../src/tools/ecode/plugins/debugger/debuggerclient.cpp
../../src/tools/ecode/plugins/formatter/formatterplugin.cpp
../../src/tools/ecode/plugins/formatter/formatterplugin.hpp
../../src/tools/ecode/notificationcenter.cpp
../../src/tools/ecode/notificationcenter.hpp
../../src/tools/ecode/pathhelper.hpp
../../src/tools/ecode/plugins/debugger/dap/debuggerclientdap.cpp
../../src/tools/ecode/plugins/debugger/debuggerclient.hpp
../../src/tools/ecode/plugins/debugger/debuggerclientlistener.cpp
../../src/tools/ecode/plugins/debugger/debuggerclientlistener.hpp
../../src/tools/ecode/plugins/debugger/debuggerplugin.cpp
../../src/tools/ecode/plugins/debugger/debuggerplugin.hpp
../../src/tools/ecode/plugins/debugger/statusdebuggercontroller.cpp
../../src/tools/ecode/plugins/debugger/statusdebuggercontroller.hpp
../../src/tools/ecode/plugins/git/git.cpp
../../src/tools/ecode/plugins/git/git.hpp
../../src/tools/ecode/plugins/git/gitbranchmodel.cpp
Expand All @@ -1590,6 +1611,7 @@
../../src/tools/ecode/plugins/lsp/lspprotocol.hpp
../../src/tools/ecode/plugins/plugin.cpp
../../src/tools/ecode/plugins/plugin.hpp
../../src/tools/ecode/plugins/plugincontextprovider.hpp
../../src/tools/ecode/plugins/pluginmanager.cpp
../../src/tools/ecode/plugins/pluginmanager.hpp
../../src/tools/ecode/plugins/xmltools/xmltoolsplugin.cpp
Expand Down
25 changes: 16 additions & 9 deletions src/tools/ecode/plugins/debugger/debuggerclientlistener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,12 @@ DebuggerClientListener::DebuggerClientListener( DebuggerClient* client, Debugger

DebuggerClientListener::~DebuggerClientListener() {
resetState();
if ( !mPlugin->isShuttingDown() && getStatusDebuggerController() ) {
getStatusDebuggerController()->getUIThreads()->removeEventsOfType( Event::OnModelEvent );
getStatusDebuggerController()->getUIStack()->removeEventsOfType( Event::OnModelEvent );
auto sdc = getStatusDebuggerController();
if ( !mPlugin->isShuttingDown() && sdc ) {
if ( sdc->getUIThreads() )
sdc->getUIThreads()->removeEventsOfType( Event::OnModelEvent );
if ( sdc->getUIStack() )
sdc->getUIStack()->removeEventsOfType( Event::OnModelEvent );
}
}

Expand All @@ -183,17 +186,19 @@ void DebuggerClientListener::stateChanged( DebuggerClient::State state ) {
->getStatusAppOutputController()
->initNewOutput( {}, false );

UISceneNode* sceneNode = mPlugin->getUISceneNode();

if ( !mThreadsModel ) {
mThreadsModel = std::make_shared<ThreadsModel>(
std::vector<Thread>{}, [this]( const auto& key, const auto& val ) {
return mPlugin->i18n( key, val );
std::vector<Thread>{}, [sceneNode]( const auto& key, const auto& val ) {
return sceneNode->i18n( key, val );
} );
}

if ( !mStackModel ) {
mStackModel = std::make_shared<StackModel>(
StackTraceInfo{}, [this]( const auto& key, const auto& val ) {
return mPlugin->i18n( key, val );
StackTraceInfo{}, [sceneNode]( const auto& key, const auto& val ) {
return sceneNode->i18n( key, val );
} );
}

Expand Down Expand Up @@ -243,8 +248,10 @@ void DebuggerClientListener::capabilitiesReceived( const Capabilities& /*capabil
void DebuggerClientListener::resetState() {
mStoppedData = {};
mCurrentScopePos = {};
mThreadsModel->resetThreads();
mStackModel->resetStack();
if ( mThreadsModel )
mThreadsModel->resetThreads();
if ( mStackModel )
mStackModel->resetStack();
mScope.clear();
}

Expand Down
114 changes: 98 additions & 16 deletions src/tools/ecode/plugins/debugger/debuggerplugin.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "debuggerplugin.hpp"
#include "../../notificationcenter.hpp"
#include "../../projectbuild.hpp"
#include "../../uistatusbar.hpp"
#include "busprocess.hpp"
Expand Down Expand Up @@ -177,9 +178,11 @@ void DebuggerPlugin::loadDAPConfig( const std::string& path, bool updateConfigFi
DapTool dapTool;
dapTool.name = dap.value( "name", "" );
dapTool.url = dap.value( "url", "" );

if ( dap.contains( "run" ) ) {
auto& run = dap["run"];
dapTool.run.command = run.value( "command", "" );
dapTool.fallbackCommand = run.value( "command_fallback", "" );
if ( run.contains( "command_arguments" ) && run["command_arguments"].is_array() ) {
auto& args = run["command_arguments"];
dapTool.run.args.reserve( args.size() );
Expand All @@ -189,6 +192,7 @@ void DebuggerPlugin::loadDAPConfig( const std::string& path, bool updateConfigFi
}
}
}

if ( dap.contains( "configurations" ) ) {
auto& configs = dap["configurations"];
dapTool.configurations.reserve( configs.size() );
Expand All @@ -212,6 +216,14 @@ void DebuggerPlugin::loadDAPConfig( const std::string& path, bool updateConfigFi
}
}

if ( dap.contains( "find" ) && dap["find"].is_object() ) {
auto find = dap["find"].items();
for ( const auto& [key, val] : find ) {
if ( val.is_string() )
dapTool.findBinary[key] = String::toLower( val.get<std::string>() );
}
}

mDaps.emplace_back( std::move( dapTool ) );
}
}
Expand Down Expand Up @@ -693,7 +705,33 @@ bool DebuggerPlugin::isSupportedByAnyDebugger( const std::string& language ) {
return false;
}

static std::string findCommand( const std::string& findBinary, const std::string& cmd ) {
std::string findCmd = findBinary;
String::replaceAll( findCmd, "${command}", cmd );
Process p;
p.create( findCmd );
std::string path;
p.readAllStdOut( path, Seconds( 5 ) );
int retCode = -1;
p.join( &retCode );
if ( retCode == 0 && !path.empty() ) {
String::trimInPlace( path, '\n' );
return path;
}
return "";
}

void DebuggerPlugin::runConfig( const std::string& debugger, const std::string& configuration ) {
auto runConfig = getPluginContext()->getProjectBuildManager()->getCurrentRunConfig();
if ( !runConfig ) {
auto msg =
i18n( "no_run_config",
"You must first have a \"Run Target\" configured and selected. Go to \"Build "
"Settings\" and create a new build and run setting (build step is optional)." );
mManager->getPluginContext()->getNotificationCenter()->addNotification( msg, Seconds( 5 ) );
return;
}

auto debuggerIt = std::find_if( mDaps.begin(), mDaps.end(), [&debugger]( const DapTool& dap ) {
return dap.name == debugger;
} );
Expand All @@ -720,25 +758,69 @@ void DebuggerPlugin::runConfig( const std::string& debugger, const std::string&
cmd.command = debuggerIt->run.command;
cmd.arguments = debuggerIt->run.args;

auto bus = std::make_unique<BusProcess>( cmd );
mRunButton->setEnabled( false );

mDebugger = std::make_unique<DebuggerClientDap>( protocolSettings, std::move( bus ) );
mListener = std::make_unique<DebuggerClientListener>( mDebugger.get(), this );
mDebugger->addListener( mListener.get() );
std::string findBinary;
auto findBinaryIt = debuggerIt->findBinary.find( String::toLower( Sys::getPlatform() ) );
if ( findBinaryIt != debuggerIt->findBinary.end() )
findBinary = findBinaryIt->second;

std::string fallbackCommand = debuggerIt->fallbackCommand;

mThreadPool->run(
[this, cmd = std::move( cmd ), protocolSettings = std::move( protocolSettings ),
findBinary = std::move( findBinary ),
fallbackCommand = std::move( fallbackCommand )]() mutable {
if ( !findBinary.empty() && Sys::which( cmd.command ).empty() ) {
auto foundCmd = findCommand( findBinary, cmd.command );
if ( !foundCmd.empty() ) {
cmd.command = std::move( foundCmd );
} else if ( !fallbackCommand.empty() ) {
foundCmd = findCommand( findBinary, fallbackCommand );
if ( !foundCmd.empty() )
cmd.command = std::move( foundCmd );
}
}

mRunButton->setEnabled( false );
if ( !FileSystem::fileExists( cmd.command ) && Sys::which( cmd.command ).empty() ) {
auto args = Process::parseArgs( cmd.command );
if ( args.size() <= 1 ||
( !FileSystem::fileExists( args[0] ) && Sys::which( args[0] ).empty() ) ) {
if ( fallbackCommand.empty() || ( !FileSystem::fileExists( fallbackCommand ) &&
Sys::which( fallbackCommand ).empty() ) ) {
auto msg = String::format(
i18n( "debugger_binary_not_found",
"Debugger binary not found. Binary \"%s\" must be installed." )
.toUtf8(),
cmd.command );

mManager->getPluginContext()->getNotificationCenter()->addNotification(
msg );
return;
} else {
cmd.command = std::move( fallbackCommand );
}
}
}

auto bus = std::make_unique<BusProcess>( cmd );

mThreadPool->run( [this] { mDebugger->start(); },
[this]( const Uint64& ) {
if ( !mDebugger || !mDebugger->started() ) {
exitDebugger();
} else {
mRunButton->runOnMainThread( [this] {
mRunButton->setEnabled( true );
mRunButton->setText( i18n( "cancel_run", "Cancel Run" ) );
} );
}
} );
mDebugger = std::make_unique<DebuggerClientDap>( protocolSettings, std::move( bus ) );
mListener = std::make_unique<DebuggerClientListener>( mDebugger.get(), this );
mDebugger->addListener( mListener.get() );

mDebugger->start();
},
[this]( const Uint64& ) {
if ( !mDebugger || !mDebugger->started() ) {
exitDebugger();
} else {
mRunButton->runOnMainThread( [this] {
mRunButton->setEnabled( true );
mRunButton->setText( i18n( "cancel_run", "Cancel Run" ) );
} );
}
} );
}

void DebuggerPlugin::exitDebugger() {
Expand Down
2 changes: 2 additions & 0 deletions src/tools/ecode/plugins/debugger/debuggerplugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ struct DapTool {
std::vector<std::string> languagesSupported;
DapRunConfig run;
std::vector<DapConfig> configurations;
std::unordered_map<std::string, std::string> findBinary;
std::string fallbackCommand;
};

class DebuggerPlugin : public PluginBase {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/ecode/plugins/plugincontextprovider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class StatusAppOutputController;
class ProjectBuildManager;
class NotificationCenter;
class ProjectDirectoryTree;
class TerminalConfig;
struct TerminalConfig;

class PluginContextProvider {
public:
Expand Down

0 comments on commit d73f1ea

Please sign in to comment.