diff -r d23e9854aea4 -r 18a7312cfdb3 src/eric7/DebugClients/Python/MultiprocessingExtension.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/eric7/DebugClients/Python/MultiprocessingExtension.py Sun Jul 24 11:29:56 2022 +0200 @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2020 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a function to patch multiprocessing.Process to support +debugging of the process. +""" + +import sys +import traceback + +_debugClient = None +_originalProcess = None +_originalBootstrap = None + + +def patchMultiprocessing(module, debugClient): + """ + Function to patch the multiprocessing module. + + @param module reference to the imported module to be patched + @type module + @param debugClient reference to the debug client object + @type DebugClient + """ # __IGNORE_WARNING_D234__ + global _debugClient, _originalProcess, _originalBootstrap + + _debugClient = debugClient + + _originalProcess = module.process.BaseProcess + _originalBootstrap = _originalProcess._bootstrap + + class ProcessWrapper(_originalProcess): + """ + Wrapper class for multiprocessing.Process. + """ + + def _bootstrap(self, *args, **kwargs): + """ + Wrapper around _bootstrap to start debugger. + + @param args function arguments + @type list + @param kwargs keyword only arguments + @type dict + @return exit code of the process + @rtype int + """ + _debugging = False + if _debugClient.debugging and _debugClient.multiprocessSupport: + scriptName = sys.argv[0] + if not _debugClient.skipMultiProcessDebugging(scriptName): + _debugging = True + try: + ( + wd, + host, + port, + exceptions, + tracePython, + redirect, + noencoding, + ) = _debugClient.startOptions[:7] + _debugClient.startDebugger( + sys.argv[0], + host=host, + port=port, + exceptions=exceptions, + tracePython=tracePython, + redirect=redirect, + passive=False, + multiprocessSupport=True, + ) + except Exception: + print( + # __IGNORE_WARNING_M801__ + "Exception during multiprocessing bootstrap init:" + ) + traceback.print_exc(file=sys.stdout) + sys.stdout.flush() + raise + + exitcode = _originalBootstrap(self, *args, **kwargs) + + if _debugging: + _debugClient.progTerminated(exitcode, "process finished") + + return exitcode + + _originalProcess._bootstrap = ProcessWrapper._bootstrap