【发布时间】:2021-05-08 05:49:20
【问题描述】:
全部,
环境: 服务器操作系统:Windows Server 2012R2(64位)
服务器硬件:使用虚拟化软件
基于 .net 框架构建的应用程序:4.6.1(编译=任何 CPU),WinForms 应用程序
我有一个连接到 SQL 服务器的应用程序。当应用程序尝试打开 SQL 服务器连接时,我得到 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 应用 vs 控制台应用
- 崩溃的应用程序通过工作线程(使用后台工作线程)执行连接
我不知道是什么导致了这个异常,我什至无法用我的控制台应用程序重现这个异常。 任何帮助将不胜感激。
===================== 更新1(测试结果)=================== ==
-
我确实创建了另一个 winforms 应用程序,并运行了为 SQL 服务器连接的代码,它工作正常,...然后我做了 #2
-
我编辑了崩溃的应用程序的 Program.cs 并添加了以下几行
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 应用程序运行完全相同的代码?
【问题讨论】:
-
我查看了那个线程并尝试了winsock重置,没有什么不同。请注意,虽然我的情况可能有点不同,因为控制台应用程序运行良好,但我的 Winform 应用程序做同样的事情会崩溃。
-
控制台应用程序和winforms之间的DLL差异?
-
您使用的是哪个框架版本?您是否尝试过任何其他版本
-
可能不行,但你能写一个 MRE 吗?其他人可以运行以重现该问题吗?另外,您是否使用连接池?我在堆栈跟踪中看到它。
标签: c# .net sql-server database-connection memory-access