-
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
X509Store.Certificates.Find() results in surprisingly large finalized object counts #44382
Comments
Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @jeffhandley |
Disposing of the X509Store doesn't dispose of all of the certificate objects returned in the Certificates collection, as they can be used after the store is disposed. Try adding: foreach (var cert in certs) cert.Dispose(); to your test. That should reduce the amount of finalization you see. However, there does appear to be a bug beyond that. @bartonjs, the StorePal.CopyTo's method use of SafeHandles is really strange: it's bending over backwards to try to keep pointers in safe handles only to then extract the underlying handle from each in a "dangerous" way. As a result, it's paying additional cost but isn't actually being any safer, and it's not disposing of a bunch of SafeHandles it seems it should, incurring even more cost. Even adding the aforementioned Dispose to get rid of a bunch of finalization, you can still see lots of finalization with this stack creating the handles:
and all for handles that have IsInvalid==true. The handles are all transferred to something that will be disposed of, so it's doesn't appear to actually be a leak, but lots of invalid SafeHandle objects are getting left for finalization unnecessarily. It seems like this line: Line 157 in 628c14b
should actually be: CERT_CONTEXT* pPrevCertContext = null;
if (pCertContext != null)
{
pPrevCertContext = pCertContext.Disconnect();
pCertContext.Dispose();
} and then also here: Line 45 in 628c14b
there should be an additional call like: pCertContext.Dispose(); after the loop to dispose of the final SafeHandle. But, again, I question how SafeHandles are being used here at all: it seems like this would all be much simpler if |
@stephentoub Enumerating the returned certificates collection and disposing of the certificates individually does reduce, but doesn't eliminate, the spike in finalized objects. |
Right, see the remainder of my comment (which I added subsequent to initially posting). |
Description
While debugging a memory allocation issue, I noted a large number of finalized objects were being reported in my perfview trace, specifically over 100,000 instances of finalization for Internal.Cryptography.Pal.Native.SafeCertContextHandle.
After some experimentation, I've found that the following program reproduces this behavior:
Configuration
I've reproduced this behavior on both .NET 5.0 RC2 and .NET Core 3.1. Windows 10 20H2, x86 and x64.
Regression?
The behavior seem to be present in .NET Core 3.1, so if this is a regression it doesn't appear to be a particularly new one.
Other information
I'm happy to learn that I'm doing something terribly stupid with the above API. :)
The text was updated successfully, but these errors were encountered: