mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fix debugger output transmission after program termination for remote debug and save_signatures mode (PY-13861).
This commit is contained in:
@@ -245,14 +245,22 @@ def killAllPydevThreads():
|
||||
|
||||
|
||||
#=======================================================================================================================
|
||||
# PyDBCheckAliveThread
|
||||
# CheckOutputThread
|
||||
# Non-daemonic thread guaranties that all data is written even if program is finished
|
||||
#=======================================================================================================================
|
||||
class PyDBCheckAliveThread(PyDBDaemonThread):
|
||||
class CheckOutputThread(PyDBDaemonThread):
|
||||
|
||||
def __init__(self, pyDb):
|
||||
PyDBDaemonThread.__init__(self)
|
||||
self.pyDb = pyDb
|
||||
self.setName('pydevd.CheckAliveThread')
|
||||
pyDb.output_checker = self
|
||||
|
||||
def start(self):
|
||||
# it should be non daemon
|
||||
thread = threading.Thread(target=self.run)
|
||||
thread.daemon = False
|
||||
thread.start()
|
||||
|
||||
def OnRun(self):
|
||||
if self.dontTraceMe:
|
||||
@@ -270,7 +278,8 @@ class PyDBCheckAliveThread(PyDBDaemonThread):
|
||||
pydevd_tracing.SetTrace(None) # no debugging on this thread
|
||||
|
||||
while not self.killReceived:
|
||||
if not self.pyDb.haveAliveThreads():
|
||||
if not self.pyDb.haveAliveThreads() and self.pyDb.writer.empty() \
|
||||
and not has_data_to_redirect():
|
||||
try:
|
||||
pydev_log.debug("No alive threads, finishing debug session")
|
||||
self.pyDb.FinishDebuggingSession()
|
||||
@@ -279,10 +288,14 @@ class PyDBCheckAliveThread(PyDBDaemonThread):
|
||||
traceback.print_exc()
|
||||
|
||||
self.killReceived = True
|
||||
return
|
||||
|
||||
self.pyDb.checkOutputRedirect()
|
||||
|
||||
time.sleep(0.3)
|
||||
|
||||
|
||||
|
||||
|
||||
def doKillPydevThread(self):
|
||||
pass
|
||||
|
||||
@@ -311,6 +324,7 @@ class PyDB:
|
||||
pydevd_tracing.ReplaceSysSetTraceFunc()
|
||||
self.reader = None
|
||||
self.writer = None
|
||||
self.output_checker = None
|
||||
self.quitting = None
|
||||
self.cmdFactory = NetCommandFactory()
|
||||
self._cmd_queue = {} # the hash of Queues. Key is thread id, value is thread
|
||||
@@ -1453,10 +1467,8 @@ class PyDB:
|
||||
if self._finishDebuggingSession and not self._terminationEventSent:
|
||||
#that was not working very well because jython gave some socket errors
|
||||
try:
|
||||
threads = DictKeys(PyDBDaemonThread.created_pydb_daemon_threads)
|
||||
for t in threads:
|
||||
if hasattr(t, 'doKillPydevThread'):
|
||||
t.doKillPydevThread()
|
||||
if self.output_checker is None:
|
||||
killAllPydevThreads()
|
||||
except:
|
||||
traceback.print_exc()
|
||||
self._terminationEventSent = True
|
||||
@@ -1577,7 +1589,9 @@ class PyDB:
|
||||
|
||||
|
||||
PyDBCommandThread(self).start()
|
||||
PyDBCheckAliveThread(self).start()
|
||||
if self.signature_factory is not None:
|
||||
# we need all data to be sent to IDE even after program finishes
|
||||
CheckOutputThread(self).start()
|
||||
|
||||
|
||||
def patch_threads(self):
|
||||
@@ -1736,13 +1750,26 @@ def usage(doExit=0):
|
||||
def initStdoutRedirect():
|
||||
if not getattr(sys, 'stdoutBuf', None):
|
||||
sys.stdoutBuf = pydevd_io.IOBuf()
|
||||
sys.stdout_original = sys.stdout
|
||||
sys.stdout = pydevd_io.IORedirector(sys.stdout, sys.stdoutBuf) #@UndefinedVariable
|
||||
|
||||
def initStderrRedirect():
|
||||
if not getattr(sys, 'stderrBuf', None):
|
||||
sys.stderrBuf = pydevd_io.IOBuf()
|
||||
sys.stderr_original = sys.stderr
|
||||
sys.stderr = pydevd_io.IORedirector(sys.stderr, sys.stderrBuf) #@UndefinedVariable
|
||||
|
||||
|
||||
def has_data_to_redirect():
|
||||
if getattr(sys, 'stdoutBuf', None):
|
||||
if not sys.stdoutBuf.empty():
|
||||
return True
|
||||
if getattr(sys, 'stderrBuf', None):
|
||||
if not sys.stderrBuf.empty():
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
#=======================================================================================================================
|
||||
# settrace
|
||||
#=======================================================================================================================
|
||||
@@ -1881,7 +1908,7 @@ def _locked_settrace(
|
||||
debugger.setSuspend(t, CMD_THREAD_SUSPEND)
|
||||
|
||||
PyDBCommandThread(debugger).start()
|
||||
PyDBCheckAliveThread(debugger).start()
|
||||
CheckOutputThread(debugger).start()
|
||||
|
||||
else:
|
||||
# ok, we're already in debug mode, with all set, so, let's just set the break
|
||||
|
||||
@@ -454,6 +454,8 @@ class WriterThread(PyDBDaemonThread):
|
||||
if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 0:
|
||||
traceback.print_exc()
|
||||
|
||||
def empty(self):
|
||||
return self.cmdQueue.empty()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ class IOBuf:
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def empty(self):
|
||||
return len(self.buflist) == 0
|
||||
|
||||
class _RedirectionsHolder:
|
||||
_stack_stdout = []
|
||||
|
||||
Reference in New Issue
Block a user