大家好,
环境:
服务器操作系统:Windows Server 2012R2(64位)
服务器硬件:使用虚拟化软件
应用程序构建在 .net framework 上:4.6.1(编译=Any CPU),WinForms 应用程序
我有一个连接到 SQL server 的应用程序。当应用程序尝试打开 SQL server 连接时,会出现 System.AccessViolationException 异常(以下为堆栈跟踪)。这仅发生在该服务器上。该应用程序在其他服务器/工作站上运行良好。我已经进行了以下测试-请阅读以下内容以获取更多信息(在堆栈跟踪之后)。
异常详细信息:
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
Application: UpdateCenter.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
at SNINativeMethodWrapper.SNIPacketAllocate(System.Runtime.InteropServices.SafeHandle, IOType, IntPtr ByRef)
at System.Data.SqlClient.SNIPacket..ctor(System.Runtime.InteropServices.SafeHandle)
at System.Data.SqlClient.TdsParserStateObject.GetResetWritePacket()
at System.Data.SqlClient.TdsParserStateObject.WriteSni(Boolean)
at System.Data.SqlClient.TdsParserStateObject.WritePacket(Byte, Boolean)
at System.Data.SqlClient.TdsParser.SendPreLoginHandshake(Byte[], Boolean)
at System.Data.SqlClient.TdsParser.Connect(System.Data.SqlClient.ServerInfo, System.Data.SqlClient.SqlInternalConnectionTds, Boolean, Int64, Boolean, Boolean, Boolean, Boolean, Boolean, System.Data.SqlClient.SqlAuthenticationMethod, Boolean, System.Data.SqlClient.SqlAuthenticationProviderManager)
at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(System.Data.SqlClient.ServerInfo, System.String, System.Security.SecureString, Boolean, System.Data.ProviderBase.TimeoutTimer, Boolean, Boolean, Boolean)
at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(System.Data.SqlClient.ServerInfo, System.String, System.Security.SecureString, Boolean, System.Data.SqlClient.SqlConnectionString, System.Data.SqlClient.SqlCredential, System.Data.ProviderBase.TimeoutTimer)
at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(System.Data.ProviderBase.TimeoutTimer, System.Data.SqlClient.SqlConnectionString, System.Data.SqlClient.SqlCredential, System.String, System.Security.SecureString, Boolean)
at System.Data.SqlClient.SqlInternalConnectionTds..ctor(System.Data.ProviderBase.DbConnectionPoolIdentity, System.Data.SqlClient.SqlConnectionString, System.Data.SqlClient.SqlCredential, System.Object, System.String, System.Security.SecureString, Boolean, System.Data.SqlClient.SqlConnectionString, System.Data.SqlClient.SessionData, System.Data.ProviderBase.DbConnectionPool, System.String, Boolean, System.Data.SqlClient.SqlAuthenticationProviderManager)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(System.Data.Common.DbConnectionOptions, System.Data.Common.DbConnectionPoolKey, System.Object, System.Data.ProviderBase.DbConnectionPool, System.Data.Common.DbConnection, System.Data.Common.DbConnectionOptions)
at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(System.Data.ProviderBase.DbConnectionPool, System.Data.Common.DbConnection, System.Data.Common.DbConnectionOptions, System.Data.Common.DbConnectionPoolKey, System.Data.Common.DbConnectionOptions)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(System.Data.Common.DbConnection, System.Data.Common.DbConnectionOptions, System.Data.ProviderBase.DbConnectionInternal)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(System.Data.Common.DbConnection, System.Data.Common.DbConnectionOptions, System.Data.ProviderBase.DbConnectionInternal)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(System.Data.Common.DbConnection, UInt32, Boolean, Boolean, System.Data.Common.DbConnectionOptions, System.Data.ProviderBase.DbConnectionInternal ByRef)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(System.Data.Common.DbConnection, System.Threading.Tasks.TaskCompletionSource`1<System.Data.ProviderBase.DbConnectionInternal>, System.Data.Common.DbConnectionOptions, System.Data.ProviderBase.DbConnectionInternal ByRef)
at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(System.Data.Common.DbConnection, System.Threading.Tasks.TaskCompletionSource`1<System.Data.ProviderBase.DbConnectionInternal>, System.Data.Common.DbConnectionOptions, System.Data.ProviderBase.DbConnectionInternal, System.Data.ProviderBase.DbConnectionInternal ByRef)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(System.Data.Common.DbConnection, System.Data.ProviderBase.DbConnectionFactory, System.Threading.Tasks.TaskCompletionSource`1<System.Data.ProviderBase.DbConnectionInternal>, System.Data.Common.DbConnectionOptions)
at System.Data.SqlClient.SqlConnection.TryOpenInner(System.Threading.Tasks.TaskCompletionSource`1<System.Data.ProviderBase.DbConnectionInternal>)
at System.Data.SqlClient.SqlConnection.TryOpen(System.Threading.Tasks.TaskCompletionSource`1<System.Data.ProviderBase.DbConnectionInternal>)
at System.Data.SqlClient.SqlConnection.Open()
at PrlSystems.ProductUpdateLibrary.Schema.Drivers.MsSql.SqlServerDataLayerDriver.OpenConnection(System.String)
at PrlSystems.ProductUpdateLibrary.Schema.DataLayerUpdater.TestConnection(PrlSystems.ProductUpdateLibrary.Schema.DataLayerSettings, System.String ByRef)
at PrlSystems.UpdateCenter.Forms.Wizard.DatabaseConnectionForm.ctlTestDatabaseConnectionWorker_DoWork(System.Object, System.ComponentModel.DoWorkEventArgs)
at System.ComponentModel.BackgroundWorker.WorkerThreadStart(System.Object)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr, System.Object[], System.Object, System.Object[] ByRef)
at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage, System.Runtime.Remoting.Messaging.IMessageSink)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
引发此异常的代码行是:
connection.Open();
我决定远程连接并调试应用程序,以查看使用的连接字符串(这是完全合法的连接字符串)。接下来,我编写了一个快速而简单的控制台应用程序,使用相同的连接字符串/使用相同的SQL连接对象创建了一个SQL连接,并在同一台服务器上运行它,它可以正常工作。
崩溃应用程序和控制台应用程序之间唯一的区别是:
- 崩溃的应用程序是WinForms应用程序而不是控制台应用程序。 - 崩溃的应用程序在工作线程中执行连接(使用BackgroundWorker)。
我对导致此异常的原因感到无言以对,甚至无法使用我的控制台应用程序重现此异常。任何帮助将不胜感激。
===================== 更新1(测试结果) =====================
I did create another winforms app, and ran the code that does the connection for SQL server and it works fine, ... then I did #2
I edited Program.cs of the app that's crashing and added the following few lines
static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // connection that causes access violation exception var conn = new SqlConnection(); conn.ConnectionString = @"Server=.\sqlexpress;Connection Timeout=5;Integrated Security=True"; conn.Open(); // <= Will get exception after this line executes! conn.Close(); }
当应用程序运行时,我仍然遇到访问冲突异常。看起来像这个程序被诅咒或列入黑名单!
===================== 更新2(测试结果)=====================
大家好,我已经将整个应用程序精简到只有Program.cs文件,并在Main()函数中只包含连接数据库的几行代码(并引用了几个标准程序集)。即使如此,当应用程序运行时,我仍然看到相同的异常。
然后我将其重新编译为 .NET 2、3.5 版本,它可以工作!但一旦切换到 .NET 4 或更高版本,异常就会回来。您可能认为服务器上安装了错误的软件,但是为什么其他 .NET 4 应用程序运行相同的代码却能正常工作呢?