- Notifications
You must be signed in to change notification settings - Fork750
Description
Environment
- Pythonnet version: 3.0.0-rc4
- Python version: 3.7.7
- Operating System: Windows 10 21H2
- .NET Runtime: 5.0.17
Details
- I think there might be a race condition in
Python.Runtime.Platform.WindowsLoader.GetAllModules
. I am hitting this very sporadically when I initialize Python.NET from Python. The outer and inner exceptions are:
System.TypeInitializationException: The type initializer for 'Delegates' threw an exception. ---> System.ComponentModel.Win32Exception (6): The handle is invalid. at Python.Runtime.Platform.WindowsLoader.GetAllModules() in /tmp/build-via-sdist-sstjjspf/pythonnet-3.0.0rc4/src/runtime/Native/LibraryLoader.cs:line 153 at Python.Runtime.Platform.WindowsLoader.GetFunction(IntPtr hModule, String procedureName) in /tmp/build-via-sdist-sstjjspf/pythonnet-3.0.0rc4/src/runtime/Native/LibraryLoader.cs:line 133 at Python.Runtime.Runtime.Delegates.GetFunctionByName(String functionName, IntPtr libraryHandle) in /tmp/build-via-sdist-sstjjspf/pythonnet-3.0.0rc4/src/runtime/Runtime.Delegates.cs:line 296 at Python.Runtime.Runtime.Delegates..cctor() in /tmp/build-via-sdist-sstjjspf/pythonnet-3.0.0rc4/src/runtime/Runtime.Delegates.cs:line 110 --- End of inner exception stack trace --- at Python.Runtime.Runtime.Delegates.get_PyGILState_Ensure() in /tmp/build-via-sdist-sstjjspf/pythonnet-3.0.0rc4/src/runtime/Runtime.Delegates.cs:line 319 at Python.Runtime.Runtime.PyGILState_Ensure() in /tmp/build-via-sdist-sstjjspf/pythonnet-3.0.0rc4/src/runtime/Runtime.cs:line 747 at Python.Runtime.PythonEngine.AcquireLock() in /tmp/build-via-sdist-sstjjspf/pythonnet-3.0.0rc4/src/runtime/PythonEngine.cs:line 472 at Python.Runtime.Py.GILState..ctor() in /tmp/build-via-sdist-sstjjspf/pythonnet-3.0.0rc4/src/runtime/Py.cs:line 27 at Python.Runtime.Py.GIL() in /tmp/build-via-sdist-sstjjspf/pythonnet-3.0.0rc4/src/runtime/Py.cs:line 13 at Python.Runtime.Loader.Initialize(IntPtr data, Int32 size) in /tmp/build-via-sdist-sstjjspf/pythonnet-3.0.0rc4/src/runtime/Loader.cs:line 26
Line numbers don't seem to line up exactly for me, but when I'm able to catch it in the debugger, it's thethrow new Win32Exception()
lines that trigger it.
I think what might be happening in my case is that the handleself
here:https://github.com/pythonnet/pythonnet/blob/v3.0.0-rc4/src/runtime/Native/LibraryLoader.cs#L140
is being closed before one of the calls toEnumProcessModules
.
The docs forProcess.GetCurrentProcess()
say that each invocation returns a newProcess
component; each instance opens its own handle to the current process, and that handle gets closed whenProcess.Close
orProcess.Dispose
is called. Since a reference isn't being retained to the object returned byProcess.GetCurrentProcess()
, the garbage collector is able to collect it and its handle would be closed, which means thatself
is no longer valid.
I think one solution would be something like...
using (Process p = Process.GetCurrentProcess()){ EnumProcessModules(p.Handle, ...}
in order to keep the process alive while its handle is still being accessed. Thanks!