在的SqlCeConnection处置访问冲突异常 [英] Access Violation Exception in SqlCeConnection dispose

查看:345
本文介绍了在的SqlCeConnection处置访问冲突异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

应用程序/ code说明:

我的应用程序是基于C#和使用SQL Server CE,同时code位置iv'e得到这个例外只有两次。与此异常崩溃未导入到这个版本。在这个版本中唯一的变化是改变了.NET框架4.5.2。

我对处置的的SqlCeConnection ,出现以下错误获得访问冲突异常

  

试图读取或写入受保护的内存。这通常是   指示其他内存已损坏。

此异常不是由的try catch子句截获.NET - 这会导致系统崩溃

在我的code我用以下命令来运行

 尝试
{
    VAR的connectionString =的String.Format({0} {1} {2},数据源=,_localDB,文件模式=读写;最大数据库大小= 4000;坚持安全信息= FALSE;);
    使用(VAR的SqlCeConnection =新的SqlCeConnection(的connectionString))
    {
        使用(VAR sqlCeCommand =新SqlCeCommand())
        {
            sqlCeCommand.Connection =的SqlCeConnection;
            sqlCeCommand.CommandText =SELECT * FROM应用;
            sqlCeConnection.Open();
            VAR的结果=(字符串)sqlCeCommand.ExecuteScalar();
            的isValid =的IsValid(结果)!;
        }
    }
}
赶上(例外前)
{
    _log.Error(异常,前);
}
 

在第一次崩溃调用堆栈:

  NTDLL!ZwWaitForMultipleObjects +一
KERNELBASE!WaitForMultipleObjectsEx + E8
KERNEL32!WaitForMultipleObjectsExImplementation + B3
KERNEL32!疫情周报preportFaultInternal + 215
KERNEL32!疫情周报preportFault + 77
KERNEL32!基地preportFault + 1F
KERNEL32!UnhandledExceptionFilter的+ 1FC
NTDLL! ? :: FNODOBFM ::'串'+ 2365
NTDLL!_C_specific_handler + 8C
NTDLL!RtlpExecuteHandlerForException + D
NTDLL!RtlDispatchException + 45A
NTDLL!KiUserExceptionDispatcher + 2E
sqlcese35!__ SafeRelease + C
sqlcese35!柱::`矢量删除析构函数'+ 5℃
sqlcese35!对象:: DeleteObjects + 39
sqlcese35!表::`矢量删除析构函数'+ 45
sqlcese35!表::发布+ 27
sqlcese35!哈希表::〜哈希表+ 2A
sqlcese35!商店::〜店+ 12B
sqlcese35!商店::发布+ 2A
sqlceme35 ME_SafeRelease + 17!
DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr的为ByRef)+78
[InlinedCallFrame](System.Data.SqlServerCe.NativeMethods.SafeRelease)System.Data.SqlServerCe.NativeMethods.SafeRelease(IntPtrByRef)
System.Data.SqlServerCe.SqlCeConnection.ReleaseNativeInterfaces()+ 147
System.Data.SqlServerCe.SqlCeConnection.Dispose(布尔)+ F1
System_ni!System.ComponentModel.Component.Dispose()+ 18
 

第二次碰撞调用堆栈:

  NTDLL!NtWaitForMultipleObjects +一
KERNELBASE!WaitForMultipleObjectsEx + E8
KERNEL32!WaitForMultipleObjectsExImplementation + B3
KERNEL32!疫情周报preportFaultInternal + 215
KERNEL32!疫情周报preportFault + 77
KERNEL32!基地preportFault + 1F
KERNEL32!UnhandledExceptionFilter的+ 1FC
NTDLL! ? :: FNODOBFM ::'串'+ 2335
NTDLL!_C_specific_handler + 8C
NTDLL!RtlpExecuteHandlerForException + D
NTDLL!RtlDispatchException + 45A
NTDLL!KiUserExceptionDispatcher + 2E
< Unloaded_sqlcese35.dll> + 7c88c
< Unloaded_sqlceqp35.dll> 102790
0x06ccc898
0x06f9efc8
0x1eca8018
0x1f207400
< Unloaded_sqlcese35.dll> + 228dc
0x00000004
0x2edff008
0x00000002
0x00000003
0x00000004
< Unloaded_sqlcese35.dll> + 3fbd9
0x06ccc898
DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr的为ByRef)+78
[InlinedCallFrame](System.Data.SqlServerCe.NativeMethods.SafeRelease)System.Data.SqlServerCe.NativeMethods.SafeRelease(IntPtrByRef)
System.Data.SqlServerCe.SqlCeConnection.ReleaseNativeInterfaces()+ 147
System.Data.SqlServerCe.SqlCeConnection.Dispose(布尔)+ F1
System_ni!System.ComponentModel.Component.Dispose()+ 1b的
 

我发现,提出了一些解决方案,在互联网上的一些参考:

  1. 可能的解决方案:检查在同一个连接多线程的问题(<一href="http://stackoverflow.com/questions/18547759/attempted-to-read-write-protected-memory-this-is-often-an-indication-that-other">attempted读取写入受保护的内存。这通常指示其他内存已损坏)

    拒绝
    一个。该连接在使用括号创建并没有得到重用。
    湾调用方法是通过转储文件,它不是同时被称为每隔5分钟和验证。

  2. 可能的解决方案: SQL CE版本不匹配(<一href="http://blogs.msdn.com/b/sqlservercompact/archive/2009/05/06/troubleshooting-access-violation-exception-while-using-sql-server-compact-database-with-ado-net-provider.aspx" rel="nofollow">http://blogs.msdn.com/b/sqlservercompact/archive/2009/05/06/troubleshooting-access-violation-exception-while-using-sql-server-compact-database-with-ado-net-provider.aspx)

    可能抑制:我可以在安装的版本看到的是3.5 SP2(3.5.8080.0),并从位于垃圾堆里的模块,我可以看到 sqlceme35.dll System.Data.SqlServerCe.dll DLL的是版本3.05.8080.0

  3. 可能的解决方案这是问题如下: <一href="http://stackoverflow.com/a/20492181/1447518">http://stackoverflow.com/a/20492181/1447518

    可能抑制:这听起来是不是从统计权perspective-的code在同一个地方坠毁过两次,虽然没有在应用code另一个地方,这将写入和读取到不同的数据库和应用程序没有崩溃那里。

  4. 过去的事情,我在想,可能建议dll的卸载问题(看看第二个调用堆栈)。我的猜测是,该dll的是从应用程序,而应用程序需要他们为了做一个dispose卸载,但接缝有点模糊和长镜头

我的问题是:这可能会使这个问题,什么是可能的解决办法

解决方案

虽然这种解决方案尚未得到确认,该解决方案如下:

这是第二次调用堆栈,我可以看到有卸载的本机DLL的,我的猜测是,SQL连接的Dispose方法,其中利用它目前处理的方法之一。 我彻底的验证过程转储所有的SqlCeConnection类型为在处置的过程。

眼看ErikEj评论使我意识到它会更好,如果我将在SQL-CE之间取得了3.5至4.0(System.Data.SqlServerCe.dll)的code差异一看。

查看code后,我可以看到发布的方法被移到了Dispose方法里面稍后的位置。

另外我可以看到,在调用SafeRelease之前,还有一个检查,检查是否需要为安全释放的本机DLL被释放already-并抛出一个异常。

底线,SQL-CE 4.0有2个解决方案同样的问题。

我的猜测是,这个问题是因为这个原因造成的。

对于现在的解决方案是保持在所有的应用程序生命周期的连接(没有连接字符串),这可能会使指针池,以保持本机DLL中的所有应用程序生命周期内存。

更好的解决方案是迁移到SQL-CE 4.0。

Application/Code description:

My application is based on c# and uses SQL Server CE and iv'e got this exception only twice at the same code location. the crash with this exception was not introduced till this version. the only change in this version was changing the .net framework to 4.5.2.

I'm getting access violation exception on the dispose of an SqlCeConnection with the following error:

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

This exception is not intercepted by the try catch clause of .net- it causes a crash.

In my code I use the following to run

try
{
    var connectionString = string.Format("{0}{1}{2}", "Data Source=", _localDB, ";File Mode=Read Write;Max Database Size=4000;Persist Security Info=False;");
    using (var sqlCeConnection = new SqlCeConnection(connectionString))
    {
        using (var sqlCeCommand = new SqlCeCommand())
        {
            sqlCeCommand.Connection = sqlCeConnection;
            sqlCeCommand.CommandText = "SELECT * FROM Application";
            sqlCeConnection.Open();
            var result = (string)sqlCeCommand.ExecuteScalar();
            isValid = !IsValid(result);
        }
    }
}
catch (Exception ex)
{
    _log.Error("exception", ex);
}

call stack for the first crash:

ntdll!ZwWaitForMultipleObjects+a 
KERNELBASE!WaitForMultipleObjectsEx+e8 
kernel32!WaitForMultipleObjectsExImplementation+b3 
kernel32!WerpReportFaultInternal+215 
kernel32!WerpReportFault+77 
kernel32!BasepReportFault+1f 
kernel32!UnhandledExceptionFilter+1fc 
ntdll! ?? ::FNODOBFM::`string'+2365 
ntdll!_C_specific_handler+8c 
ntdll!RtlpExecuteHandlerForException+d 
ntdll!RtlDispatchException+45a 
ntdll!KiUserExceptionDispatcher+2e 
sqlcese35!__SafeRelease+c 
sqlcese35!Column::`vector deleting destructor'+5c 
sqlcese35!Object::DeleteObjects+39 
sqlcese35!Table::`vector deleting destructor'+45 
sqlcese35!Table::Release+27 
sqlcese35!HashTable::~HashTable+2a 
sqlcese35!Store::~Store+12b 
sqlcese35!Store::Release+2a 
sqlceme35!ME_SafeRelease+17 
DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr ByRef)+78 
[[InlinedCallFrame] (System.Data.SqlServerCe.NativeMethods.SafeRelease)] System.Data.SqlServerCe.NativeMethods.SafeRelease(IntPtrByRef) 
System.Data.SqlServerCe.SqlCeConnection.ReleaseNativeInterfaces()+147 
System.Data.SqlServerCe.SqlCeConnection.Dispose(Boolean)+f1 
System_ni!System.ComponentModel.Component.Dispose()+18 

call stack for the second crash:

ntdll!NtWaitForMultipleObjects+a 
KERNELBASE!WaitForMultipleObjectsEx+e8 
kernel32!WaitForMultipleObjectsExImplementation+b3 
kernel32!WerpReportFaultInternal+215 
kernel32!WerpReportFault+77 
kernel32!BasepReportFault+1f 
kernel32!UnhandledExceptionFilter+1fc 
ntdll! ?? ::FNODOBFM::`string'+2335 
ntdll!_C_specific_handler+8c 
ntdll!RtlpExecuteHandlerForException+d 
ntdll!RtlDispatchException+45a 
ntdll!KiUserExceptionDispatcher+2e 
<Unloaded_sqlcese35.dll>+7c88c 
<Unloaded_sqlceqp35.dll>+102790 
0x06ccc898 
0x06f9efc8 
0x1eca8018 
0x1f207400 
<Unloaded_sqlcese35.dll>+228dc 
0x00000004 
0x2edff008 
0x00000002 
0x00000003 
0x00000004 
<Unloaded_sqlcese35.dll>+3fbd9 
0x06ccc898 
DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr ByRef)+78 
[[InlinedCallFrame] (System.Data.SqlServerCe.NativeMethods.SafeRelease)] System.Data.SqlServerCe.NativeMethods.SafeRelease(IntPtrByRef) 
System.Data.SqlServerCe.SqlCeConnection.ReleaseNativeInterfaces()+147 
System.Data.SqlServerCe.SqlCeConnection.Dispose(Boolean)+f1 
System_ni!System.ComponentModel.Component.Dispose()+1b 

I found some references on the internet that suggests some solutions:

  1. Probable solution: check multithreading issue on the same connection (attempted to read write protected memory. this is often an indication that other memory is corrupt)

    Rejection:
    a. the connection is created in the using brackets and doesn't get reused.
    b. the calling method is called every 5 minutes and verified via the dump file that it was not called simultaneously.

  2. Probable solution: sql ce version mismatch (http://blogs.msdn.com/b/sqlservercompact/archive/2009/05/06/troubleshooting-access-violation-exception-while-using-sql-server-compact-database-with-ado-net-provider.aspx)

    Probable Rejection: I can see in the version installed is 3.5 SP2 (3.5.8080.0) and from the modules located in the dump I can see the sqlceme35.dll, System.Data.SqlServerCe.dll DLL's are with version 3.05.8080.0

  3. Probable solution which is in question is the following: http://stackoverflow.com/a/20492181/1447518

    Probable Rejection: it doesn't sound right from a statistical perspective- the code crashed twice in the same place although there another place in the application code which writes and read to a different DB and the application didn't crash there.

  4. The last thing I was thinking about, may suggest a unload problem of DLLs (take a look at the second call stack). My guess is that the dll's are unloaded from the application while the application needed them in order to do a dispose, but it seams a bit blurry and a 'long shot'

My question is: what may cause the problem, and what is a probable solution?

解决方案

Although this solution is not yet verified, the solution is as follows:

From the second call stack i can see there is unload of native DLL's, my guess was that the dispose method of the SQL connection was using one of the methods it currently disposed. I verified thorough the Process dump that all the SqlCeConnection types were in the process of dispose.

Seeing ErikEj comment made me realize it's will be better if i will take a look in the code differences that was made between SQL-CE 3.5 to 4.0 (System.Data.SqlServerCe.dll).

after viewing the code, i could see that the method of the release was moved to a later position inside the dispose method.

In addition i could see that before calling SafeRelease there was another check that checks if the native DLLs that were needed for safe release was released already- and throw an exception.

bottom line, SQL-CE 4.0 has 2 solutions for the same issue.

my guess is that this issue was caused because of this.

the solution for now was to keep a connection during all the application life-cycle (which has no connection string), this cause the pointer pool to keep the native Dlls in the memory for all the application life-cycle.

the better solution is to move to SQL-CE 4.0 .

这篇关于在的SqlCeConnection处置访问冲突异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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