From 9b6a9da552cc407c6315dd05fef17d5cae70766f Mon Sep 17 00:00:00 2001 From: Cedric Delamarre Date: Wed, 31 Mar 2021 16:12:08 +0200 Subject: [PATCH] debugger: deadlock in the java EDT due to the debug mode fixed f=figure("closerequestfcn","disp(""closing""); close(gcf()); disp(""close done !"")"); debug click on the close button of the figure the EDT is waiting for the execution of the closerequestfcn because storing a command in debug mode pause the thread. When the main thread of Scilab execute close, the close function wants to add something in the EDT which is paused. Change-Id: I0996465dd9f9965e3ef05c845260c533aded6348 --- .../action_binding/src/c/InterpreterManagement.c | 6 ++++-- scilab/modules/ast/includes/ast/debugmanager.hxx | 3 +-- .../includes/system_env/configvariable_interface.h | 2 +- scilab/modules/ast/src/cpp/ast/consoledebugger.cpp | 2 +- scilab/modules/ast/src/cpp/ast/debugmanager.cpp | 18 +++--------------- .../cpp/system_env/configvariable_interface.cpp | 4 ++-- scilab/modules/core/includes/storeCommand.h | 2 +- scilab/modules/core/src/cpp/runner.cpp | 6 ++++++ scilab/modules/core/src/cpp/storeCommand.cpp | 17 ++++++++++++----- 9 files changed, 31 insertions(+), 29 deletions(-) diff --git a/scilab/modules/action_binding/src/c/InterpreterManagement.c b/scilab/modules/action_binding/src/c/InterpreterManagement.c index 8c18f73..dfd2295 100644 --- a/scilab/modules/action_binding/src/c/InterpreterManagement.c +++ b/scilab/modules/action_binding/src/c/InterpreterManagement.c @@ -26,7 +26,8 @@ int putCommandInScilabQueue(char *command) return 1; } - return debuggerManagerExecute(command); + // 0 : don't pause the thread + return debuggerManagerExecute(command, 0); } else { @@ -49,7 +50,8 @@ int requestScilabExec(char *command) return 1; } - return debuggerManagerExecute(command); + // 0 : don't pause the thread + return debuggerManagerExecute(command, 0); } else { diff --git a/scilab/modules/ast/includes/ast/debugmanager.hxx b/scilab/modules/ast/includes/ast/debugmanager.hxx index d2b5300..c193051 100644 --- a/scilab/modules/ast/includes/ast/debugmanager.hxx +++ b/scilab/modules/ast/includes/ast/debugmanager.hxx @@ -72,7 +72,6 @@ private: DebugAction action; int level; - void internal_execution_released(); void internal_stop(); bool callstackAddFile(StackRow* _row, const std::wstring& _fileName); @@ -275,7 +274,7 @@ public: } } - char* execute(const std::string& command); //execute a command + char* execute(const std::string& command, int iWaitForIt = 1); //execute a command void print(const std::string& variable); //print a variable void show(int bp); //print the breakpoint bp or all breakpoints (bp = -1) void resume(); //resume execution diff --git a/scilab/modules/ast/includes/system_env/configvariable_interface.h b/scilab/modules/ast/includes/system_env/configvariable_interface.h index 7223126..298be6e 100644 --- a/scilab/modules/ast/includes/system_env/configvariable_interface.h +++ b/scilab/modules/ast/includes/system_env/configvariable_interface.h @@ -81,7 +81,7 @@ EXTERN_AST dynlib_ptr getEntryPointFromPosition(int position); EXTERN_AST int isEnableDebug(); EXTERN_AST int isDebugInterrupted(); -EXTERN_AST int debuggerManagerExecute(const char* command); +EXTERN_AST int debuggerManagerExecute(const char* command, int iWaitForIt); EXTERN_AST int isExecutionBreak(); EXTERN_AST void setExecutionBreak(); diff --git a/scilab/modules/ast/src/cpp/ast/consoledebugger.cpp b/scilab/modules/ast/src/cpp/ast/consoledebugger.cpp index 74f45fe..3249132 100644 --- a/scilab/modules/ast/src/cpp/ast/consoledebugger.cpp +++ b/scilab/modules/ast/src/cpp/ast/consoledebugger.cpp @@ -70,7 +70,7 @@ void ConsoleDebugger::onExecutionReleased() void ConsoleDebugger::onPrint(const std::string& variable) { // sciprint("ConsoleDebugger::onPrint.\n"); - StoreDebuggerCommand(std::string("disp("+variable+")").data()); + StoreDebuggerCommand(std::string("disp("+variable+")").data(), 1); } void ConsoleDebugger::onShow(int bp) diff --git a/scilab/modules/ast/src/cpp/ast/debugmanager.cpp b/scilab/modules/ast/src/cpp/ast/debugmanager.cpp index 767632a..ef476bf 100644 --- a/scilab/modules/ast/src/cpp/ast/debugmanager.cpp +++ b/scilab/modules/ast/src/cpp/ast/debugmanager.cpp @@ -439,7 +439,7 @@ void DebuggerManager::show(int bp) sendShow(bp); } -char* DebuggerManager::execute(const std::string& command) +char* DebuggerManager::execute(const std::string& command, int iWaitForIt) { char* error = checkCommand(command.data()); if(error) @@ -453,9 +453,7 @@ char* DebuggerManager::execute(const std::string& command) // inform debuggers sendExecution(); // execute command and wait - StoreDebuggerCommand(command.data()); - // send execution finished and update debugger informations - internal_execution_released(); + StoreDebuggerCommand(command.data(), iWaitForIt); return nullptr; } @@ -473,9 +471,6 @@ void DebuggerManager::resume() //resume execution // send "SendRunMeSignal" to unlock execution then wait ThreadManagement::WaitForDebuggerExecDoneSignal(true); - - // send execution finished and update debugger informations - internal_execution_released(); } } @@ -524,23 +519,16 @@ void DebuggerManager::abort() //abort execution clearCallStack(); ThreadManagement::WaitForDebuggerExecDoneSignal(true); - - internal_execution_released(); } } -void DebuggerManager::internal_execution_released() -{ - // send execution finished - sendExecutionReleased(); -} - void DebuggerManager::internal_stop() { interrupted = true; generateCallStack(); // release the debugger thread ThreadManagement::SendDebuggerExecDoneSignal(); + sendExecutionReleased(); // wait inside pause try { diff --git a/scilab/modules/ast/src/cpp/system_env/configvariable_interface.cpp b/scilab/modules/ast/src/cpp/system_env/configvariable_interface.cpp index be87993..b224589 100644 --- a/scilab/modules/ast/src/cpp/system_env/configvariable_interface.cpp +++ b/scilab/modules/ast/src/cpp/system_env/configvariable_interface.cpp @@ -246,9 +246,9 @@ int isDebugInterrupted() return debugger::DebuggerManager::getInstance()->isInterrupted() ? 1 : 0; } -int debuggerManagerExecute(const char* command) +int debuggerManagerExecute(const char* command, int iWaitForIt) { - return debugger::DebuggerManager::getInstance()->execute(command) ? 1 : 0; + return debugger::DebuggerManager::getInstance()->execute(command, iWaitForIt) ? 1 : 0; } int isExecutionBreak() diff --git a/scilab/modules/core/includes/storeCommand.h b/scilab/modules/core/includes/storeCommand.h index 9c849f9..8b5608d 100644 --- a/scilab/modules/core/includes/storeCommand.h +++ b/scilab/modules/core/includes/storeCommand.h @@ -59,7 +59,7 @@ int StoreConsoleCommand(const char *command, int iWaitFor); * @param command : the command * @return */ -int StoreDebuggerCommand(const char *command); +int StoreDebuggerCommand(const char *command, int iWaitFor); /** * Store a prioritary and non-interruptible command diff --git a/scilab/modules/core/src/cpp/runner.cpp b/scilab/modules/core/src/cpp/runner.cpp index d69411e..b1dfcb7 100644 --- a/scilab/modules/core/src/cpp/runner.cpp +++ b/scilab/modules/core/src/cpp/runner.cpp @@ -170,6 +170,9 @@ int StaticRunner::launch() // send the good signal about the end of execution sendExecDoneSignal(); + // send information about execution done to debuggers + manager->sendExecutionReleased(); + // set back the runner wich have been overwritten in StaticRunner::getRunner m_CurrentRunner.store(pRunSave); throw ia; @@ -201,6 +204,9 @@ int StaticRunner::launch() // send the good signal about the end of execution sendExecDoneSignal(); + // send information about execution done to debuggers + manager->sendExecutionReleased(); + //clean debugger step flag if debugger is not interrupted ( end of debug ) manager->resetStep(); diff --git a/scilab/modules/core/src/cpp/storeCommand.cpp b/scilab/modules/core/src/cpp/storeCommand.cpp index 8644208..c021823 100644 --- a/scilab/modules/core/src/cpp/storeCommand.cpp +++ b/scilab/modules/core/src/cpp/storeCommand.cpp @@ -116,7 +116,7 @@ int StoreConsoleCommand(const char *command, int iWaitFor) return 0; } -int StoreDebuggerCommand(const char *command) +int StoreDebuggerCommand(const char *command, int iWaitFor) { ThreadManagement::LockStoreCommand(); commandQueuePrioritary.emplace_back(os_strdup(command), @@ -129,10 +129,17 @@ int StoreDebuggerCommand(const char *command) // Awake Runner to execute this prioritary command ThreadManagement::SendAwakeRunnerSignal(); - // make this wait before unlock the Store Command will prevent - // dead lock in case where another thread get this command - // and execute it before this thread is waiting for. - ThreadManagement::WaitForDebuggerExecDoneSignal(false); + if (iWaitFor) + { + // make this wait before unlock the Store Command will prevent + // dead lock in case where another thread get this command + // and execute it before this thread is waiting for. + ThreadManagement::WaitForDebuggerExecDoneSignal(false); + } + else + { + ThreadManagement::UnlockStoreCommand(); + } return 0; } -- 1.7.9.5