Menu

#638 Crash in Python COM Server is Python was shutdown

open
nobody
None
5
2013-04-29
2013-04-29
No

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.

Discussion

  • Stefan Schukat

    Stefan Schukat - 2013-04-29

    Patch adding python check.

     
  • Mark Hammond

    Mark Hammond - 2013-04-30

    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)

     
  • Stefan Schukat

    Stefan Schukat - 2013-04-30

    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.

     
  • Mark Hammond

    Mark Hammond - 2013-04-30

    But who is finalizing Python, and why are they doing it too early?

     
  • Stefan Schukat

    Stefan Schukat - 2013-05-02

    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.

     
  • Mark Hammond

    Mark Hammond - 2013-05-02

    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.

     
  • Stefan Schukat

    Stefan Schukat - 2013-05-02

    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.

     
  • Mark Hammond

    Mark Hammond - 2013-05-02

    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)