mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-28 17:16:29 +03:00
More debugger fixes.
This commit is contained in:
@@ -205,39 +205,39 @@
|
||||
"run": [
|
||||
{
|
||||
"args": "-v",
|
||||
"command": "ecode-debug",
|
||||
"command": "${project_root}/bin/ecode-debug",
|
||||
"name": "ecode-debug",
|
||||
"working_dir": "${project_root}/bin"
|
||||
},
|
||||
{
|
||||
"args": "-x",
|
||||
"command": "ecode",
|
||||
"command": "${project_root}/bin/ecode",
|
||||
"name": "ecode-release",
|
||||
"working_dir": "${project_root}/bin"
|
||||
},
|
||||
{
|
||||
"args": "",
|
||||
"command": "eepp-unit_tests-debug",
|
||||
"command": "${project_root}/bin/eepp-unit-tests-debug",
|
||||
"name": "eepp-unit_tests-debug",
|
||||
"run_in_terminal": true,
|
||||
"working_dir": "${project_root}/bin/unit_tests"
|
||||
"working_dir": "${project_root}/bin/unit_tests/"
|
||||
},
|
||||
{
|
||||
"args": "",
|
||||
"command": "eepp-unit_tests",
|
||||
"command": "${project_root}/bin/eepp-unit_tests",
|
||||
"name": "eepp-unit_tests",
|
||||
"run_in_terminal": true,
|
||||
"working_dir": "${project_root}/bin/unit_tests"
|
||||
},
|
||||
{
|
||||
"args": "",
|
||||
"command": "eepp-empty-window-debug",
|
||||
"command": "${project_root}/bin/eepp-empty-window-debug",
|
||||
"name": "eepp-empty_window-debug",
|
||||
"working_dir": "${project_root}/bin"
|
||||
},
|
||||
{
|
||||
"args": "",
|
||||
"command": "eepp-empty-window",
|
||||
"command": "${project_root}/bin/eepp-empty-window",
|
||||
"name": "eepp-empty_window",
|
||||
"working_dir": "${project_root}/bin"
|
||||
}
|
||||
|
||||
@@ -1814,7 +1814,7 @@ std::map<KeyBindings::Shortcut, std::string> App::getLocalKeybindings() {
|
||||
{ { KEY_5, KEYMOD_LALT }, "toggle-status-app-output" },
|
||||
{ { KEY_B, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "project-build-start" },
|
||||
{ { KEY_C, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "project-build-cancel" },
|
||||
{ { KEY_F5, KEYMOD_NONE }, "project-build-and-run" },
|
||||
{ { KEY_R, KeyMod::getDefaultModifier() }, "project-build-and-run" },
|
||||
{ { KEY_O, KEYMOD_LALT | KEYMOD_SHIFT }, "show-open-documents" },
|
||||
{ { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-workspace-symbol-search" },
|
||||
{ { KEY_P, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-document-symbol-search" },
|
||||
@@ -1822,7 +1822,7 @@ std::map<KeyBindings::Shortcut, std::string> App::getLocalKeybindings() {
|
||||
};
|
||||
}
|
||||
|
||||
// Old keybindings will be rebinded to the new keybindings of they are still set to the old
|
||||
// Old keybindings will be rebinded to the new keybindings when they are still set to the old
|
||||
// keybindind
|
||||
std::map<std::string, std::string> App::getMigrateKeybindings() {
|
||||
return { { "fullscreen-toggle", "alt+return" }, { "switch-to-tab-1", "alt+1" },
|
||||
@@ -1834,7 +1834,8 @@ std::map<std::string, std::string> App::getMigrateKeybindings() {
|
||||
#if EE_PLATFORM == EE_PLATFORM_MACOS
|
||||
{ "menu-toggle", "mod+shift+m" },
|
||||
#endif
|
||||
{ "lock-toggle", "mod+shift+l" }, { "debug-widget-tree-view", "f11" } };
|
||||
{ "lock-toggle", "mod+shift+l" }, { "debug-widget-tree-view", "f11" },
|
||||
{ "project-build-and-run", "f5" } };
|
||||
}
|
||||
|
||||
std::vector<std::string> App::getUnlockedCommands() {
|
||||
@@ -1908,7 +1909,8 @@ void App::saveProject( bool onlyIfNeeded, bool sessionSnapshotEnabled ) {
|
||||
mConfig.saveProject(
|
||||
mCurrentProject, mSplitter, mConfigPath, mProjectDocConfig,
|
||||
mProjectBuildManager ? mProjectBuildManager->getConfig() : ProjectBuildConfiguration(),
|
||||
onlyIfNeeded, sessionSnapshotEnabled && mConfig.workspace.sessionSnapshot, mPluginManager.get() );
|
||||
onlyIfNeeded, sessionSnapshotEnabled && mConfig.workspace.sessionSnapshot,
|
||||
mPluginManager.get() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -109,12 +109,13 @@ std::vector<FeaturesHealth::LangHealth> FeaturesHealth::getHealth( PluginManager
|
||||
if ( debugger ) {
|
||||
std::vector<DapTool> found = debugger->getDebuggersForLang( def.getLSPName() );
|
||||
for ( const auto& dbg : found ) {
|
||||
FeatureStatus debugger;
|
||||
debugger.name = dbg.name;
|
||||
debugger.url = dbg.url;
|
||||
debugger.path = Sys::which( dbg.run.command );
|
||||
debugger.found = !debugger.path.empty();
|
||||
lang.debugger.emplace_back( std::move( debugger ) );
|
||||
FeatureStatus fdbg;
|
||||
fdbg.name = dbg.name;
|
||||
fdbg.url = dbg.url;
|
||||
auto debuggerBin = debugger->debuggerBinaryExists( dbg.name );
|
||||
fdbg.path = debuggerBin ? debuggerBin->command : "";
|
||||
fdbg.found = !fdbg.path.empty();
|
||||
lang.debugger.emplace_back( std::move( fdbg ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ ThreadEvent::ThreadEvent( const json& body ) :
|
||||
StoppedEvent::StoppedEvent( const json& body ) :
|
||||
reason( body[DAP_REASON].get<std::string>() ),
|
||||
description( parseOptionalString( body, "description" ) ),
|
||||
threadId( body[DAP_THREAD_ID].get<int>() ),
|
||||
threadId( body.value( DAP_THREAD_ID, 1 ) ),
|
||||
preserveFocusHint( parseOptionalBool( body, "preserveFocusHint" ) ),
|
||||
text( parseOptionalString( body, "text" ) ),
|
||||
allThreadsStopped( parseOptionalBool( body, "allThreadsStopped" ) ),
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "models/stackmodel.hpp"
|
||||
#include "models/threadsmodel.hpp"
|
||||
#include "models/variablesmodel.hpp"
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/ui/uipopupmenu.hpp>
|
||||
#include <eepp/window/input.hpp>
|
||||
|
||||
@@ -101,17 +102,30 @@ void DebuggerClientListener::stateChanged( DebuggerClient::State state ) {
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerClientListener::initialized() {
|
||||
void DebuggerClientListener::sendBreakpoints() {
|
||||
Lock l( mPlugin->mBreakpointsMutex );
|
||||
for ( const auto& fileBps : mPlugin->mBreakpoints )
|
||||
mClient->setBreakpoints( fileBps.first, fromSet( fileBps.second ) );
|
||||
for ( const auto& fileBps : mPlugin->mBreakpoints ) {
|
||||
std::string path( fileBps.first );
|
||||
if ( isRemote() ) {
|
||||
FileSystem::filePathRemoveBasePath( mPlugin->mProjectPath, path );
|
||||
path = "/" + path;
|
||||
}
|
||||
mClient->setBreakpoints( path, fromSet( fileBps.second ) );
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerClientListener::initialized() {
|
||||
sendBreakpoints();
|
||||
}
|
||||
|
||||
void DebuggerClientListener::launched() {}
|
||||
|
||||
void DebuggerClientListener::configured() {}
|
||||
|
||||
void DebuggerClientListener::failed() {}
|
||||
void DebuggerClientListener::failed() {
|
||||
mPlugin->exitDebugger();
|
||||
resetState();
|
||||
}
|
||||
|
||||
void DebuggerClientListener::debuggeeRunning() {}
|
||||
|
||||
@@ -184,6 +198,10 @@ void DebuggerClientListener::debuggingProcess( const ProcessInfo& ) {}
|
||||
void DebuggerClientListener::errorResponse( const std::string& command, const std::string& summary,
|
||||
const std::optional<Message>& /*message*/ ) {
|
||||
if ( command != "evaluate" ) {
|
||||
if ( command == "launch" ) {
|
||||
failed();
|
||||
}
|
||||
|
||||
mPlugin->getPluginContext()->getNotificationCenter()->addNotification( summary,
|
||||
Seconds( 5 ) );
|
||||
}
|
||||
@@ -328,6 +346,10 @@ void DebuggerClientListener::expressionEvaluated( const std::string& /*expressio
|
||||
void DebuggerClientListener::gotoTargets( const Source& /*source*/, const int /*line*/,
|
||||
const std::vector<GotoTarget>& /*targets*/ ) {}
|
||||
|
||||
bool DebuggerClientListener::isRemote() const {
|
||||
return mIsRemote;
|
||||
}
|
||||
|
||||
bool DebuggerClientListener::isStopped() const {
|
||||
return mStoppedData ? true : false;
|
||||
}
|
||||
@@ -352,6 +374,10 @@ std::optional<std::pair<std::string, int>> DebuggerClientListener::getCurrentSco
|
||||
return mCurrentScopePos;
|
||||
}
|
||||
|
||||
void DebuggerClientListener::setIsRemote( bool isRemote ) {
|
||||
mIsRemote = isRemote;
|
||||
}
|
||||
|
||||
StatusDebuggerController* DebuggerClientListener::getStatusDebuggerController() const {
|
||||
return mPlugin->getStatusDebuggerController();
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ class DebuggerClientListener : public DebuggerClient::Listener {
|
||||
void gotoTargets( const Source& source, const int line,
|
||||
const std::vector<GotoTarget>& targets );
|
||||
|
||||
bool isRemote() const;
|
||||
|
||||
bool isStopped() const;
|
||||
|
||||
std::optional<StoppedEvent> getStoppedData() const;
|
||||
@@ -65,12 +67,17 @@ class DebuggerClientListener : public DebuggerClient::Listener {
|
||||
|
||||
std::optional<std::pair<std::string, int>> getCurrentScopePos() const;
|
||||
|
||||
void setIsRemote( bool isRemote );
|
||||
|
||||
void sendBreakpoints();
|
||||
|
||||
protected:
|
||||
DebuggerClient* mClient{ nullptr };
|
||||
DebuggerPlugin* mPlugin{ nullptr };
|
||||
std::optional<StoppedEvent> mStoppedData;
|
||||
std::optional<std::pair<std::string, int>> mCurrentScopePos;
|
||||
bool mPausedToRefreshBreakpoints{ false };
|
||||
bool mIsRemote{ false };
|
||||
int mCurrentThreadId{ 1 };
|
||||
int mCurrentFrameId{ 0 };
|
||||
std::shared_ptr<ThreadsModel> mThreadsModel;
|
||||
|
||||
@@ -625,8 +625,11 @@ void DebuggerPlugin::buildSidePanelTab() {
|
||||
mTabContents->bind( "debugger_conf_list", mUIDebuggerConfList );
|
||||
|
||||
mUIDebuggerList->on( Event::OnValueChange, [this]( const Event* event ) {
|
||||
mCurDebugger = event->getNode()->asType<UIDropDownList>()->getText().toUtf8();
|
||||
mCurConfiguration = "";
|
||||
auto cur = event->getNode()->asType<UIDropDownList>()->getText().toUtf8();
|
||||
if ( cur != mCurDebugger ) {
|
||||
mCurDebugger = std::move( cur );
|
||||
mCurConfiguration = "";
|
||||
}
|
||||
} );
|
||||
|
||||
mUIDebuggerConfList->on( Event::OnValueChange, [this]( const Event* event ) {
|
||||
@@ -886,14 +889,13 @@ void DebuggerPlugin::sendFileBreakpoints( const std::string& filePath ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Lock l( mBreakpointsMutex );
|
||||
auto fileBps = mBreakpoints.find( filePath );
|
||||
if ( fileBps == mBreakpoints.end() )
|
||||
return;
|
||||
for ( const auto& fileBps : mBreakpoints ) {
|
||||
mDebugger->setBreakpoints( fileBps.first,
|
||||
DebuggerClientListener::fromSet( fileBps.second ) );
|
||||
{
|
||||
Lock l( mBreakpointsMutex );
|
||||
auto fileBps = mBreakpoints.find( filePath );
|
||||
if ( fileBps == mBreakpoints.end() )
|
||||
return;
|
||||
}
|
||||
mListener->sendBreakpoints();
|
||||
}
|
||||
|
||||
void DebuggerPlugin::updateDebuggerConfigurationList() {
|
||||
@@ -1360,19 +1362,10 @@ void DebuggerPlugin::runConfig( const std::string& debugger, const std::string&
|
||||
for ( const std::string& cmdArg : configIt->cmdArgs )
|
||||
runConfig.args.emplace_back( cmdArg );
|
||||
|
||||
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, protocolSettings = std::move( protocolSettings ),
|
||||
runSettings = std::move( runConfig ), findBinary = std::move( findBinary ),
|
||||
fallbackCommand = std::move( fallbackCommand ), randomPort]() mutable {
|
||||
run( std::move( protocolSettings ), std::move( runSettings ), std::move( findBinary ),
|
||||
std::move( fallbackCommand ), randomPort );
|
||||
runSettings = std::move( runConfig ), randomPort, debugger]() mutable {
|
||||
run( debugger, std::move( protocolSettings ), std::move( runSettings ), randomPort );
|
||||
},
|
||||
[this]( const Uint64& ) {
|
||||
if ( !mDebugger || !mDebugger->started() ) {
|
||||
@@ -1384,13 +1377,28 @@ void DebuggerPlugin::runConfig( const std::string& debugger, const std::string&
|
||||
} );
|
||||
}
|
||||
|
||||
void DebuggerPlugin::run( ProtocolSettings&& protocolSettings, DapRunConfig&& runConfig,
|
||||
std::string&& findBinary, std::string&& fallbackCommand,
|
||||
int /*randPort*/ ) {
|
||||
std::optional<Command>
|
||||
DebuggerPlugin::debuggerBinaryExists( const std::string& debugger,
|
||||
std::optional<DapRunConfig> optRunConfig ) {
|
||||
auto debuggerIt = std::find_if( mDaps.begin(), mDaps.end(), [&debugger]( const DapTool& dap ) {
|
||||
return dap.name == debugger;
|
||||
} );
|
||||
|
||||
if ( debuggerIt == mDaps.end() )
|
||||
return {};
|
||||
|
||||
DapRunConfig runConfig = optRunConfig ? *optRunConfig : debuggerIt->run;
|
||||
Command cmd;
|
||||
cmd.command = std::move( runConfig.command );
|
||||
cmd.arguments = std::move( runConfig.args );
|
||||
|
||||
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;
|
||||
|
||||
if ( !findBinary.empty() && Sys::which( cmd.command ).empty() ) {
|
||||
auto foundCmd = findCommand( findBinary, cmd.command );
|
||||
if ( !foundCmd.empty() ) {
|
||||
@@ -1402,27 +1410,43 @@ void DebuggerPlugin::run( ProtocolSettings&& protocolSettings, DapRunConfig&& ru
|
||||
}
|
||||
}
|
||||
|
||||
if ( protocolSettings.launchCommand == REQUEST_TYPE_LAUNCH && !cmd.command.empty() &&
|
||||
!FileSystem::fileExists( cmd.command ) && Sys::which( cmd.command ).empty() ) {
|
||||
if ( !cmd.command.empty() && !FileSystem::fileExists( cmd.command ) &&
|
||||
Sys::which( cmd.command ).empty() ) {
|
||||
auto args = Process::parseArgs( cmd.command );
|
||||
if ( args.size() <= 1 ||
|
||||
if ( args.empty() ||
|
||||
( !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;
|
||||
return {};
|
||||
} else {
|
||||
cmd.command = std::move( fallbackCommand );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void DebuggerPlugin::run( const std::string& debugger, ProtocolSettings&& protocolSettings,
|
||||
DapRunConfig&& runConfig, int /*randPort*/ ) {
|
||||
std::optional<Command> cmdOpt = debuggerBinaryExists( debugger, runConfig );
|
||||
|
||||
if ( !cmdOpt && ( protocolSettings.launchCommand == REQUEST_TYPE_LAUNCH ||
|
||||
( protocolSettings.launchCommand == REQUEST_TYPE_ATTACH &&
|
||||
protocolSettings.launchRequest.value( "mode", "" ) == "local" ) ) ) {
|
||||
auto msg =
|
||||
String::format( i18n( "debugger_binary_not_found",
|
||||
"Debugger binary not found. Binary \"%s\" must be installed." )
|
||||
.toUtf8(),
|
||||
runConfig.command );
|
||||
|
||||
mManager->getPluginContext()->getNotificationCenter()->addNotification( msg );
|
||||
return;
|
||||
}
|
||||
|
||||
Command cmd = std::move( *cmdOpt );
|
||||
bool isRemote = false;
|
||||
|
||||
if ( protocolSettings.launchCommand == REQUEST_TYPE_LAUNCH ) {
|
||||
auto bus = std::make_unique<BusProcess>( cmd );
|
||||
mDebugger = std::make_unique<DebuggerClientDap>( protocolSettings, std::move( bus ) );
|
||||
@@ -1452,6 +1476,7 @@ void DebuggerPlugin::run( ProtocolSettings&& protocolSettings, DapRunConfig&& ru
|
||||
} else if ( mode == "remote" ) {
|
||||
auto bus = std::make_unique<BusSocket>( con );
|
||||
mDebugger = std::make_unique<DebuggerClientDap>( protocolSettings, std::move( bus ) );
|
||||
isRemote = true;
|
||||
}
|
||||
} else {
|
||||
getManager()->getPluginContext()->getNotificationCenter()->addNotification( String::format(
|
||||
@@ -1461,12 +1486,14 @@ void DebuggerPlugin::run( ProtocolSettings&& protocolSettings, DapRunConfig&& ru
|
||||
}
|
||||
|
||||
if ( !mDebugger ) {
|
||||
getManager()->getPluginContext()->getNotificationCenter()->addNotification( i18n(
|
||||
"debugger_configuration_not_supported", "Debugger configuration not supported." ) );
|
||||
getManager()->getPluginContext()->getNotificationCenter()->addNotification(
|
||||
i18n( "debugger_configuration_not_supported",
|
||||
"Debugger configuration currently not supported." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
mListener = std::make_unique<DebuggerClientListener>( mDebugger.get(), this );
|
||||
mListener->setIsRemote( isRemote );
|
||||
mDebugger->addListener( mListener.get() );
|
||||
|
||||
DebuggerClientDap* dap = static_cast<DebuggerClientDap*>( mDebugger.get() );
|
||||
|
||||
@@ -64,6 +64,9 @@ class DebuggerPlugin : public PluginBase {
|
||||
|
||||
std::vector<DapTool> getDebuggersForLang( const std::string& lang );
|
||||
|
||||
std::optional<Command> debuggerBinaryExists( const std::string& debugger,
|
||||
std::optional<DapRunConfig> runConfig = {} );
|
||||
|
||||
protected:
|
||||
friend class DebuggerClientListener;
|
||||
|
||||
@@ -142,8 +145,8 @@ class DebuggerPlugin : public PluginBase {
|
||||
|
||||
void runConfig( const std::string& debugger, const std::string& configuration );
|
||||
|
||||
void run( ProtocolSettings&& protocolSettings, DapRunConfig&& runConfig,
|
||||
std::string&& findBinary, std::string&& fallbackCommand, int randPort );
|
||||
void run( const std::string& debugger, ProtocolSettings&& protocolSettings,
|
||||
DapRunConfig&& runConfig, int randPort );
|
||||
|
||||
void exitDebugger();
|
||||
|
||||
|
||||
@@ -572,7 +572,7 @@ void TerminalManager::setKeybindings( UITerminal* term ) {
|
||||
"debug-draw-boxes-toggle", "debug-draw-debug-data", "debug-widget-tree-view",
|
||||
"open-locatebar", "open-command-palette", "open-global-search", "menu-toggle",
|
||||
"console-toggle", "go-to-line", "editor-go-back", "editor-go-forward",
|
||||
"project-run-executable", "project-build-and-run" } );
|
||||
"project-run-executable" } );
|
||||
}
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
Reference in New Issue
Block a user