Closed uholzer closed 2 years ago
I am sorry but I do not think your analyze of what is causing this problem could be correct. Objects involved in p/invoke calls and objects they are referring to should stay alive during the p/invoke call and that includes the original managed object that the temporary unmanaged structure was created from. Also, I would have seen this problem a lot in my tests if a problem like this was showing up here. I assume that there might be something else going on that is worth investigating though. Could you share more code where this happens?
On the current master branch it happens to me as follows:
This is with Visual Studio 2019 and .NET Framework 4.8 installed if I am not mistaken.
On the current master branch it happens to me as follows:
- I run the RegistryFS (net46) sample with the Release configuration in the debugger. It starts up properly but after browsing for a short amount of time in the file system, listing a few folders at most, I get the "CallbackOnCollectedDelegate".
Okay thanks. I'll take a look and see what I can find there!
Ah, yes I see now. There is some strange optimization in release build that causes this. It is possible to avoid with GC.KeepAlive
but not in the way you have done it in the pull request. A GC.KeepAlive
call needs to be after the last unmanaged call where the object needs to stay alive. (You were calling it immediately after object creation which has no effect.) I made a new pull request with just two calls to GC.KeepAlive
after the DokanMain
call.
I do believe that my version is correct because the call to GC.KeepAlive
comes after DokanMain. However, your pull request works for me too.
I do believe that my version is correct because the call to
GC.KeepAlive
comes after DokanMain. However, your pull request works for me too.
Yes you are right, sorry about that. I misread the diff in some strange way. My bad!
...and for the record, this is not at all expected behaviour or a documented requirement. This is most likely a bug either in the optimizing parts of the compiler or, more likely in this case, a bug in .NET Framework. I cannot seem to reproduce it in .NET Core for example and with small seemingly unrelated changes somewhere it no longer happens in .NET Framework either. So in my opinion we should really consider this a workaround for a framework (compiler, runtime etc) bug, not a bugfix for DokanNet itself.
Thanks to both of you to look into this issue! I would say if LTRData small PR do the job, we should use it. Uholzer, in your PR you have introduced the Configuration instance function which is a good idea, could you make a new pull request or reused the existing one just for that change ?
@LTRData your PR has a bunch of previous changes. Could you clean the history so I can merge a single commit ?
@LTRData your PR has a bunch of previous changes. Could you clean the history so I can merge a single commit ?
Yes you are right, it has become a bit messy since last things I did here. I'll back up a couple of steps and make a clean simple commit instead.
I made a new release with you guys fix https://github.com/dokan-dev/dokan-dotnet/releases/tag/v2.0.1.1
Thanks again! 😎 🏆
This is a weird one: When calling Dokan.Mount, my application reproducibly behaves as follows:
DokanNet!DokanNet.DokanOperationProxy+GetFileInformationDelegate::Invoke
was called from unmanaged code even though it had already been garbage collected. This happens while the call to Dokan.Mount is still running.My take on this is as follows:
This pull request is my attempt at fixing it. It has solved the problem for me. However, I am not quite sure if this works out in all cases. The garbage collector can basically do two things: