Crash in Python COM Server is Python was shutdown
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
If a Python implemented COM object is referenced by a client longer than lifetime of the Python runtime the hosting process crashes if during the release of the COM object Python functions are accessed. This is fixed by a check if Python is still initialized in the process.
Patch adding python check.
Can you give some details on how Python can become uninitialized at this time? pywin32 never finalizes Python, and I expect that if it was finalized while COM objects were alive we would have far more problems than just this one (eg, if rather than the object being destructed it instead attempt to make a "normal" call things would go pear-shaped pretty quickly I'd expect)
This error happens in a mixed C++, Python and .NET application. A reference to a Python implemented COM object is held by a RCW in .NET. When the process exits Python is finalized but the COM object is held alive in the garbage collector of .NET. When a collection takes place after that the Python COM object could not access any Python function. So it is not a general problem, but a specific problem with the memory management of .NET for COM objects.
But who is finalizing Python, and why are they doing it too early?
We are finalizing the embedded Python interpreter during shutdown of the process. This is a timing behavior since the garbage collector of .NET runs in a separate thread it could happen, that the collection of the last remaining objects is after the Py_Finalize in the main thread. Since the Python COM objects share the embedded interpreter inside a process the lifetime of the interpreter engine is not controlled by the Python COM objects but by the embedded interpreter.
Is there anything preventing the GC of an object indirectly causing code to run which may invoke a method on a COM object (eg, a "Quit()" method or similar) before the final release? What I'm trying to avoid is fixing this one case when it's possible other nasty things could still happen in non-trivial cases.
Can you simply avoid finalizing Python completely? The process is going down, so it's not going to cause leaks etc.
The RCW (runtime callable wrapper) in . NET only calls release during the garbage collecting process and no other methods. Since we are using internal COM objects from the embedded Python interpreter we cannot avoid finalizing Python, These wrappers would keep the process alive due to reference counting.
fair enough - the patch is low enough risk that I'm fine with it (but probably with an updated comment that summarizes some of the discussion in this issue (eg, that we are specifically guarding against .NET's Release-only GC at program exit)