smasherprog / screen_capture_lite

cross platform screen/window capturing library
MIT License
616 stars 156 forks source link

C#. Event handlers gets garbage collected while capturing still on, leading to crash #156

Closed wwwMADwww closed 10 months ago

wwwMADwww commented 10 months ago

Hello. I'm using library in .NET windows application through provided in src_csharp .NET wrappers.

On tag 17.1.429 everything was fine. Today i tried pre-release 17.1.1327 and started getting random unrecoverable crashes. I looked in the windows Event Logs, sometimes it says:

Application: vgarender.exe
CoreCLR Version: 7.0.523.17405
.NET Version: 7.0.5
Description: The application requested process termination through System.Environment.FailFast.
Message: A callback was made on a garbage collected delegate of type 'screen_capture_lite_csharp!SCL.ScreenCaptureCallbackWithContext::Invoke'.
Stack:
(no stack info here, empty line)

It seems that when we setting callback for events like OnNewFrame, etc., the delegate is passed to the unmanaged code but for some reason nothing is holding it in the managed code, so it's get garbage collected on next GC run and no longer can be used by unmanaged code too.

How to reproduce:

Result:

wwwMADwww commented 10 months ago

I googled and tinker around a bit. Consider this code from MonitorCaptureConfiguration.cs :

изображение

Lets see using dnSpy what it translated to after compilation:

изображение

This new ScreenCaptureCallbackWithContext(MonitorCaptureConfiguration.OnNewFrame) is successfully passed to unmanaged library but it's, as i assumed in OP, indeed used nowhere else and held by no one in managed code and thus can be GC'ed while some unmanaged code still use it. So this object needs to be placed in field or something, that's what i did in PR #157