获取“ReleaseHandle失败” MDA在终结器线程中使用加密后 [英] Getting "ReleaseHandleFailed" MDA in the finalizer thread after using cryptography

查看:149
本文介绍了获取“ReleaseHandle失败” MDA在终结器线程中使用加密后的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在循环中使用第二次运行此代码(使用不同的文件参数:

I'm getting an MDA after running this code for the second time in a loop (with a different file parameter:

byte[] encryptedData = File.ReadAllBytes(file); // before this line it throws, see exception below
long dataOffset;

using (var stream = new MemoryStream(encryptedData))
using (var reader = new BinaryReader(stream))
{
    // ... read header information which is not encrypted
}


using (var stream = new MemoryStream(encryptedData))
{
    stream.Seek(dataOffset, SeekOrigin.Begin);

    using (var aesAlg = new AesCryptoServiceProvider())
    using (var decryptor = aesAlg.CreateDecryptor(key, iv))
    using (var csDecrypt = new CryptoStream(stream, decryptor, CryptoStreamMode.Read))
    using (var reader = new BinaryReader(csDecrypt))
    {
        decrypted = reader.ReadBytes((int)(encryptedData.Length - dataOffset));
    }
}

MDA如下: p>

The MDA is the following:


Microsoft.Win32.SafeHandles.SafeCapiKeyHandle类型的SafeHandle或CriticalHandle无法正确释放值为0x000000001BEA9B50的句柄。这通常表示通过其他方式(例如使用DangerousGetHandle提取句柄,并直接关闭句柄或在其周围构建另一个SafeHandle)来手柄被不正确地释放。

A SafeHandle or CriticalHandle of type 'Microsoft.Win32.SafeHandles.SafeCapiKeyHandle' failed to properly release the handle with value 0x000000001BEA9B50. This usually indicates that the handle was released incorrectly via another means (such as extracting the handle using DangerousGetHandle and closing it directly or building another SafeHandle around it.)

stacktrace不太丰富:

The stacktrace is not too informative:


mscorlib.dll!System.Runtime.InteropServices.SafeHandle.Dispose(bool disposal )+ 0x10字节
mscorlib.dll!System.Runtime.InteropServices.SafeHandle.Finalize()+ 0x1a字节

mscorlib.dll!System.Runtime.InteropServices.SafeHandle.Dispose(bool disposing) + 0x10 bytes mscorlib.dll!System.Runtime.InteropServices.SafeHandle.Finalize() + 0x1a bytes

怀疑其中一个流或CryptoServiceProvider由于某种原因未释放。除此之外,代码运行正常,并做预期。 MDA发生在控件到达方法的第一行之前。

I suspect that one of the streams or the CryptoServiceProvider is not released for some reason. Apart from this, the code runs fine and does what's expected. The MDA occurs before the control reached the first line of the method.

如何正确地做?问题的根本原因是什么?

How can I do it properly? What is the root cause of the problem?

推荐答案

很明显,终结器线程正在完成已经处理的SafeHandle。这是AesCryptoServiceProvider.Dispose(bool)方法的实现:

Clearly the finalizer thread is finalizing a SafeHandle that is already disposed. This is the implementation of the AesCryptoServiceProvider.Dispose(bool) method:

protected override void Dispose(bool disposing)
{
    try {
        if (disposing) {
            if (this.m_key != null) this.m_key.Dispose();
            if (this.m_cspHandle != null) this.m_cspHandle.Dispose();
        }
    }
    finally {
        base.Dispose(disposing);
    }
}

三个错误:


  • 处理后不会将m_key字段设置为null

  • GC.SuppressFinalize()未调用, .NET 3.5中的基类

  • SafeCapiKeyHandle类不会使其ReleaseHandle()方法中的存储句柄无效。

所有三个错误的组合足以触发此MDA。它仍然在.NET 4.0中,但至少GC.SuppressFinalize是由SymmetricAlgorithm.Dispose(bool)调用,以便终结器不会被使用。

The combination of all three bugs is enough to trigger this MDA. It is still bugged in .NET 4.0 but at least GC.SuppressFinalize is being called by SymmetricAlgorithm.Dispose(bool) so that the finalizer won't be used.

鼓励看到框架大师拧紧。您可以在connect.microsoft.com报告问题。要停止调试器,使您不能使用Debug + Exceptions,Managed Debugging Assistants,untick ReleaseHandleFailed。默认情况下,这是一个未命中的,肯定是你第一个注意到这个错误的原因。

Inspiring to see the framework masters screw up. You can report the problem at connect.microsoft.com. To stop the debugger from nagging you about this use Debug + Exceptions, Managed Debugging Assistants, untick ReleaseHandleFailed. This one is unticked by default, surely the reason you are the first to notice this bug.

我认为第三个错误使这是一个关键的问题btw,对于这个错误,导致一个回收的句柄值被关闭。很小的赔率。相当讽刺,因为这是一个安全的句柄类。

I think the third bug makes this a critical problem btw, it is technically possible for this bug to cause a recycled handle value to be closed. Very small odds though. Rather ironic, given that this is a safe handle class.

这篇关于获取“ReleaseHandle失败” MDA在终结器线程中使用加密后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆