#638 Crash in Python COM Server is Python was shutdown

open
nobody
None
5
2013-04-29
2013-04-29
Stefan Schukat
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.

     
    Attachments
  • 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)