mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-08-14 13:15:14 +03:00
debugger fixes and improvements for macOS.
This commit is contained in:
@@ -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": [
|
||||
@@ -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": [
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
} );
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "debuggerplugin.hpp"
|
||||
#include "../../notificationcenter.hpp"
|
||||
#include "../../projectbuild.hpp"
|
||||
#include "../../uistatusbar.hpp"
|
||||
#include "busprocess.hpp"
|
||||
@@ -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() );
|
||||
@@ -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() );
|
||||
@@ -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 ) );
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
} );
|
||||
@@ -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 );
|
||||
|
||||
mDebugger = std::make_unique<DebuggerClientDap>( protocolSettings, std::move( bus ) );
|
||||
mListener = std::make_unique<DebuggerClientListener>( mDebugger.get(), this );
|
||||
mDebugger->addListener( mListener.get() );
|
||||
|
||||
mRunButton->setEnabled( false );
|
||||
|
||||
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" ) );
|
||||
} );
|
||||
}
|
||||
} );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
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() {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -48,7 +48,7 @@ class StatusAppOutputController;
|
||||
class ProjectBuildManager;
|
||||
class NotificationCenter;
|
||||
class ProjectDirectoryTree;
|
||||
class TerminalConfig;
|
||||
struct TerminalConfig;
|
||||
|
||||
class PluginContextProvider {
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user