debugger: deadlock in the java EDT due to the debug mode fixed 18/21718/2
Cedric Delamarre [Wed, 31 Mar 2021 14:12:08 +0000 (16:12 +0200)]
  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

scilab/modules/action_binding/src/c/InterpreterManagement.c
scilab/modules/ast/includes/ast/debugmanager.hxx
scilab/modules/ast/includes/system_env/configvariable_interface.h
scilab/modules/ast/src/cpp/ast/consoledebugger.cpp
scilab/modules/ast/src/cpp/ast/debugmanager.cpp
scilab/modules/ast/src/cpp/system_env/configvariable_interface.cpp
scilab/modules/core/includes/storeCommand.h
scilab/modules/core/src/cpp/runner.cpp
scilab/modules/core/src/cpp/storeCommand.cpp

index 8c18f73..dfd2295 100644 (file)
@@ -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
     {
index d2b5300..c193051 100644 (file)
@@ -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
index 7223126..298be6e 100644 (file)
@@ -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();
index 74f45fe..3249132 100644 (file)
@@ -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)
index 767632a..ef476bf 100644 (file)
@@ -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
     {
index be87993..b224589 100644 (file)
@@ -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()
index 9c849f9..8b5608d 100644 (file)
@@ -59,7 +59,7 @@ int StoreConsoleCommand(const char *command, int iWaitFor);
  * @param command : the command
   * @return <ReturnValue>
  */
-int StoreDebuggerCommand(const char *command);
+int StoreDebuggerCommand(const char *command, int iWaitFor);
 
 /**
  * Store a prioritary and non-interruptible command
index d69411e..b1dfcb7 100644 (file)
@@ -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();
 
index 8644208..c021823 100644 (file)
@@ -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;
 }