|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2020 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a function to patch multiprocessing.Process to support |
|
8 debugging of the process. |
|
9 """ |
|
10 |
|
11 import sys |
|
12 import traceback |
|
13 |
|
14 _debugClient = None |
|
15 _originalProcess = None |
|
16 _originalBootstrap = None |
|
17 |
|
18 |
|
19 def patchMultiprocessing(module, debugClient): |
|
20 """ |
|
21 Function to patch the multiprocessing module. |
|
22 |
|
23 @param module reference to the imported module to be patched |
|
24 @type module |
|
25 @param debugClient reference to the debug client object |
|
26 @type DebugClient |
|
27 """ # __IGNORE_WARNING_D234__ |
|
28 global _debugClient, _originalProcess, _originalBootstrap |
|
29 |
|
30 _debugClient = debugClient |
|
31 |
|
32 _originalProcess = module.process.BaseProcess |
|
33 _originalBootstrap = _originalProcess._bootstrap |
|
34 |
|
35 class ProcessWrapper(_originalProcess): |
|
36 """ |
|
37 Wrapper class for multiprocessing.Process. |
|
38 """ |
|
39 def _bootstrap(self, *args, **kwargs): |
|
40 """ |
|
41 Wrapper around _bootstrap to start debugger. |
|
42 |
|
43 @param args function arguments |
|
44 @type list |
|
45 @param kwargs keyword only arguments |
|
46 @type dict |
|
47 @return exit code of the process |
|
48 @rtype int |
|
49 """ |
|
50 _debugging = False |
|
51 if ( |
|
52 _debugClient.debugging and |
|
53 _debugClient.multiprocessSupport |
|
54 ): |
|
55 scriptName = sys.argv[0] |
|
56 if not _debugClient.skipMultiProcessDebugging(scriptName): |
|
57 _debugging = True |
|
58 try: |
|
59 (wd, host, port, exceptions, tracePython, redirect, |
|
60 noencoding) = _debugClient.startOptions[:7] |
|
61 _debugClient.startDebugger( |
|
62 sys.argv[0], host=host, port=port, |
|
63 exceptions=exceptions, tracePython=tracePython, |
|
64 redirect=redirect, passive=False, |
|
65 multiprocessSupport=True |
|
66 ) |
|
67 except Exception: |
|
68 print( |
|
69 # __IGNORE_WARNING_M801__ |
|
70 "Exception during multiprocessing bootstrap init:" |
|
71 ) |
|
72 traceback.print_exc(file=sys.stdout) |
|
73 sys.stdout.flush() |
|
74 raise |
|
75 |
|
76 exitcode = _originalBootstrap(self, *args, **kwargs) |
|
77 |
|
78 if _debugging: |
|
79 _debugClient.progTerminated(exitcode, "process finished") |
|
80 |
|
81 return exitcode |
|
82 |
|
83 _originalProcess._bootstrap = ProcessWrapper._bootstrap |