-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[System.Drawing.Common] In test, dispose of Metafile after Graphics #42985
Conversation
Tagging subscribers to this area: @safern, @tannergooding, @jeffhandley |
The changes to |
Fixes dotnet#37838 Verified using libgdiplus built with mono/libgdiplus#671
18f4078
to
40044fc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @lambdageek
I'm a little confused here. It sounds like the test is doing the wrong thing, but even if the test is buggy, it shouldn't be able to crash the runtime like this. Doesn't this suggest there's also a bug in either System.Drawing.Common, libgdiplus, or mono? |
Oh, I see, the fix for the issue is this for the test + mono/libgdiplus#671 for the actual bug? |
Now I'm back to being confused ;-) |
Is it a bug in libgdiplus if it's being used incorrectly? I'm not sure. The change in libgdiplus is effectively an assertion so that you definitely crash if you use the API incorrectly. The current behavior is that you overwrite some freed memory - so you get a crash if you get unlucky. |
it's P/Invoking a native library that is writing over freed memory. why would we expect something other than a crash in that situation? |
The test is P/Invoking? Where? |
Now I'm confused. Are there two problems here?
If there's a bug to be fixed in libgdiplus, I think that's a separate issue, no? |
Not sure. There are plenty of situations where one disposable type wrapping another disposable type doesn't do anything in its Dispose except call Dispose on the wrapped instance, and Dispose is idempotent, so it's acceptable use. There are also cases where objects are ref counted, e.g. with SafeHandle, and the wrapper would have taken a ref on the wrapped thing such that disposing the wrapped thing wouldn't have actually closed the wrapped thing until after everything was disposed and released ref counts. I don't know what category these fall into nor what guarantees we've made in docs... but it seems like this works on Windows?
My confusion is that the APIs being used here are managed. Misuse of a managed API shouldn't cause a seg fault / crash. If it's actually misuse, worst case it should throw an exception. e.g. if I misuse FileStream, it shouldn't crash the process (even though FileStream P/Invokes as an implementation detail), worst case a use-after-dispose would produce an ObjectDisposedException. So I'm trying to understand what makes this special; it's possible there some aspect of this I'm just missing that makes it different :) |
Thanks @stephentoub. Going to look for another approach (leaning toward refcounting) |
Thanks, @lambdageek. Just to be clear, I wasn't trying to demand a different direction, simply trying to understand and highlight differences I see in other APIs, ask questions to better understand, etc. |
(Also, if this is causing problems in CI or for devs running tests locally, we can of course disable the test until it's resolved. We can also change the test as you suggested if we believe that's more represented of typical usage; I just want to make sure we don't then lose sight of the underlying issue being worked around.) |
Fixes #37838
Verified using libgdiplus built with
mono/libgdiplus#671