尝试读取或写入受保护的内存。这通常表明其他内存已损坏

时间:2010-11-02 02:47:02

标签: c# .net multithreading memory-management

我希望有人可以告诉我可能导致此错误的原因:

  

尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

我无法真正发布代码,因为此错误似乎会在应用程序的任何随机区域中抛出。应用程序将在抛出错误之前的12-48小时内运行。有时它会在一个看似随机的位置停止并抛出上述错误,其他时候整个应用程序停止并且我得到一个错误的屏幕,上面写着“有一个致命的错误......这可能是一个CLR中的错误或...“关于PInvoke或其他非相关信息的内容。发生这种情况时,所有线程都显示终止,并且没有可用的调试信息。

简而言之,这就是应用程序的作用:

它是一个完全用C#编写的多线程服务器应用程序。客户端通过套接字连接到服务器。服务器为客户端运行虚拟“环境”,以便他们可以相互交互并与环境进行交互。它消耗了相当多的内存,但我没有看到它泄漏。它通常消耗大约1.5GB。我认为它没有泄漏,因为内存使用在应用程序运行的整个时间内保持相对稳定。即使客户端没有做任何事情,它也会不断运行代码来维护环境。它不使用第三方软件或其他API。此应用程序使用的唯一外部资源是套接字连接和SQL数据库连接。它运行在64位服务器上。我试过在VS2008& VS2010使用.net 2.0,3.5和4.0以及多个服务器,问题最终仍会发生。

我试过关闭编译器优化和几个微软热修复。似乎没有什么能让这个问题消失。如果有人知道任何可能的原因,或某种方式来确定导致问题的原因,将不胜感激。

30 个答案:

答案 0 :(得分:42)

我刚刚在VS 2013 .NET 4.5中使用MapInfo DLL遇到了这个问题。事实证明,问题是我将Build for Build从x86更改为Any CPU,这足以触发此错误。将它改回x86就可以了。可以帮助别人。

答案 1 :(得分:18)

最后在WinDBG和SOS的帮助下追踪了这一点。某些未知的DLL正在抛出访问冲突。原来一个名为“Nvidia Network Manager”的软件导致了这个问题。我无数次读过这个问题是如何由防火墙或防病毒引起的,我没有使用它,所以我驳回了这个想法。此外,我假设它不是环境因为它发生在使用不同硬件的多个服务器上。原来我测试过的所有机器都在运行“NVidia Network Manager”。我相信它与其他主板驱动程序一起安装。

希望这可以帮助某人,因为这个问题困扰我的应用程序很长一段时间。

答案 2 :(得分:13)

我还遇到了Visual Studio 2010的这个问题。更有趣的是,我在我的解决方案中有几个项目(控制台应用程序,WPF应用程序,Windows窗体应用程序),但只有在我设置类型的项目时失败了“控制台应用程序”作为启动项目(即使是那些没有任何代码或任何其他程序集与项目模板本身附带的默认程序集相比)。

以下更改最终帮助我解决了这个问题:转到控制台应用程序项目的项目属性 - >转到Debug标签 - >转到右侧窗格中的Enable Debuggers部分 - >选中Enable unmanaged code debugging复选框,如下面的快照所示。我为什么还不知道为什么会发生这种情况的根本原因。我观察到的唯一事情是前一天晚上我的机器上安装了很多Windows更新,主要是办公室更新和操作系统更新(超过十几篇文章)。

enter image description here

答案 3 :(得分:11)

尝试运行此命令

  

netsh winsock reset

来源:https://stackoverflow.com/a/20492181/1057791

答案 4 :(得分:8)

问题可能是由于项目中的混合构建平台DLL。即您将项目构建到任何CPU,但在已为x86平台构建的项目中有一些DLL。由于32位和64位架构的不同内存映射,这些将导致随机崩溃。如果所有DLL都是为一个平台构建的,那么问题就可以解决了。

答案 5 :(得分:7)

托管代码中不应发生此错误。这可能会解决问题:

转到Visual Studio Debugger以绕过此异常:

Tools menu ->Options -> Debugging -> General -> Uncheck this option "Suppress JIT optimization on module load"

希望它会有所帮助。

答案 6 :(得分:5)

最近,当我更改了项目的开发服务器时,我遇到了这个问题。我在代码行中收到此错误,我在其中声明了一个新的OracleConnection变量。

尝试了很多东西,包括安装修补程序后,我尝试在项目中更改引用Oracle.DataAccess和System.Data.OracleClient并且它有效!

当项目移动到新机器时,我建议您更新该项目中添加的所有引用。

答案 7 :(得分:5)

我已经遇到过,并且今天找到了解决这个例外的问题。当我尝试调试在抽象类上调用虚方法的单元测试(NUnit)时,就会发生这种情况。

问题似乎与.NET 4.5.1安装有关。

我已下载.NET 4.5.2并已安装(我的项目仍然引用.NET 4.5.1),问题已解决。

解决方案来源:

https://connect.microsoft.com/VisualStudio/feedback/details/819552/visual-studio-debugger-throws-accessviolationexception

答案 8 :(得分:3)

我遇到了同样的问题。我的代码是在AutoCAD 2012中运行的.NET dll(AutoCAD扩展)。我也在使用Oracle.DataAccess,我的代码在ExecuteNonQuery()期间抛出相同的异常。我幸运地通过更改我正在使用的ODP的.net版本(即Oracle.DataAccess的2.x)解决了这个问题。

答案 9 :(得分:3)

可验证的代码不应该破坏内存,所以有一些不安全的事情发生。您是否在任何地方使用任何不安全的代码,例如在缓冲区处理中?此外,关于PInvoke的东西可能并不相关,因为PInvoke涉及到非托管代码和相关编组的转换。

我最好的建议是附加到崩溃的实例并使用WinDBG and SOS深入了解崩溃时发生的事情。这不适合胆小的人,但在这一点上你可能需要打破更强大的工具来确定究竟出现了什么问题。

答案 10 :(得分:3)

好吧,这可能是毫无用处的,只是轶事,但是......

我们在项目中使用的一些Twain32库一直抛出这个异常,但只会发生在我的机器上。

我在互联网上尝试了很多建议的解决方案,但无济于事......直到我拔掉我的手机(它通过USB连接)。

它有效。

事实证明Twain32库试图将我的手机列为Twain兼容设备,并且在此过程中所做的事情导致了该异常。

去图......

答案 11 :(得分:3)

它可能是硬件。这可能是一件很复杂的事情......但是我会建议你的线程代码不会用适当的锁来保护某些集合(例如字典)。

您运行的操作系统和服务包是什么?

答案 12 :(得分:3)

您是否尝试为申请关闭DEP (Data Execution Prevention)

答案 13 :(得分:2)

在我的情况下,文件已打开,因此被锁定。

我在尝试使用也在Excel中打开的LinqToExcel加载Excel文件时得到了它。

这就是我所需要的一切

    var maps = from f in book.Worksheet<NavMapping>()
                select f;
    try {
        foreach (var m in maps)
            if (!string.IsNullOrEmpty(m.SSS_ID) && _mappings.ContainsKey(m.SSS_ID))
                _mappings.Add(m.SSS_ID, m.CDS_ID);
    } catch (AccessViolationException ex) {
        _logger.Error("mapping file error. most likely this file is locked or open. " + ex);
    }

答案 14 :(得分:1)

在对StringBuilder进行引用的方法上使用pinvoke时出现此错误。我使用了默认构造函数,它显然只分配16个字节。 Windows试图在缓冲区中放入16个以上的字节,并导致缓冲区溢出。

代替

StringBuilder windowText = new StringBuilder(); // Likely overflow of default capacity of 16

使用更大的容量:

StringBuilder windowText = new StringBuilder(3000);

答案 15 :(得分:1)

在尝试构建前一天完全正常的项目时,在VS1017中随机获得了此错误。重新启动PC可以解决此问题(我也预先运行了以下命令,不确定是否需要:netsh winsock reset)

答案 16 :(得分:1)

我也有这个问题。 我使用visual studio同时运行不同的解决方案,当关闭其他解决方案并运行目标解决方案时,它运行正常,没有错误。

答案 17 :(得分:1)

我在VB.NET中使用的项目中遇到了同样的错误。检查属性页面上的“启用应用程序框架”为我解决了这个问题。

答案 18 :(得分:1)

这个问题几乎总是一个简单的问题。代码很糟糕。仅从统计分析来看,它很少是工具。数以百万计的人每天都在使用Visual Studio,也许有些人正在使用你的代码 - 哪些代码正在获得更好的测试?我保证,如果这是VS的问题,我们可能已经找到了它。

该语句的含义是,当您尝试访问不属于您的内存时,通常是因为您使用来自其他地方的损坏指针来执行此操作。这就是它说明这一迹象的原因。

由于内存损坏,错误的捕获很少接近错误的根本原因。而且效果正如你所描述的那样,看似随意。你只需看看通常的罪魁祸首,比如:

  • 未初始化的指针或其他值。
  • 将更多内容写入缓冲区而不是其大小。
  • 由不受互斥锁保护的线程共享的资源。

从这样的问题向后工作找到根本原因难以置信困难,因为在问题的创建和问题的检测之间可能发生了很多。

我大多发现查看 损坏的内容(比如说特定指针)更容易,然后对代码进行手动静态分析,看看哪些内容可能已损坏,检查通常的罪魁祸首,如上所示。然而,即使这样也不会遇到长链问题。

我对VS不太熟悉,但您可能还想研究使用内存跟踪工具(如valgrind for Linux)的可能性,看看它是否能发现任何明显的问题。

答案 19 :(得分:0)

我的回答在很大程度上取决于您的方案,但是我们在尝试为客户端升级.NET应用程序时遇到了一个问题,即&gt; 10岁,所以他们可以使它在Windows 8.1上运行。 @ alhazen的答案对我来说是正确的球场。该应用程序依赖于客户端不想支付更新的第三方DLL(Pegasus / Accusoft ImagXpress)。我们重新定位了.NET 4.5的应用程序,但每次执行以下行时,我们收到了AccessViolationException was unhandled消息:

UnlockPICImagXpress.PS_Unlock (1908228217,373714400,1341834561,28447);

要修复它,我们必须将以下后期构建事件添加到项目中:

call "$(DevEnvDir)..\tools\vsvars32.bat"
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\editbin.exe" /NXCOMPAT:NO "$(TargetPath)"

这明确指定可执行文件与数据执行保护不兼容。有关详细信息,请参阅here

答案 20 :(得分:0)

在某些情况下,这可能会在以下情况下发生:

obj = new obj();
...
obj.Dispose();  // <-----------------    Incorrect disposal causes it
obj.abc...

答案 21 :(得分:0)

在我的情况下,我必须使用P / Invoke引用C / C ++库,但必须确保首先使用fixed为输出数组分配内存:

[DllImport("my_c_func_lib.dll", CharSet = CharSet.Ansi)]
public static extern unsafe int my_c_func(double input1, double input2, double pinput3, double *outData);

    public unsafe double[] GetMyUnmanagedCodeValue(double input1, double input2, double input3)
    {
        double[] outData = new double[24];

        fixed (double* returnValue = outData)
        {
            my_c_func(input1, input2, pinput3, returnValue);
        }

        return outData;
    }

有关详细信息,请参见:https://www.c-sharpcorner.com/article/pointers-in-C-Sharp/

答案 22 :(得分:0)

这是我在Visual Studio中调试C#WinForms应用程序时发生的。我的应用程序通过DllImport调用Win32内容,例如

[DllImport("Secur32.dll", SetLastError = false)]
private static extern uint LsaEnumerateLogonSessions(out UInt64 LogonSessionCount, out IntPtr LogonSessionList);

“以管理员身份”运行Visual Studio为我解决了这个问题。

答案 23 :(得分:0)

我有相同的错误消息:

  

System.AccessViolationException:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

就我而言,在清理并重新构建解决方案后错误消失了。

答案 24 :(得分:0)

就我而言,FTDI实用程序FT Prog在扫描USB设备时抛出了错误。从PC上拔下蓝牙耳机即可解决此问题。

答案 25 :(得分:0)

我在使用Linq过滤对象集合的lambda表达式上收到了此错误消息。当我检查集合时,我发现它的成员没有被填充-在Locals窗口中,展开它们只是显示“ ...”。最终,问题出在最初填充集合的存储库方法中-Dapper试图自动映射嵌套对象的属性。我修复了Dapper查询以处理多重映射,并修复了内存错误。

答案 26 :(得分:0)

这可能不是上述问题的最佳答案,但我的问题是无效的处置语法和缓冲区对象的 lock(this) 用法。事实证明,由于“使用”语法,该对象正在从另一个线程中处理。并且处理 lock() 属于松散类型。

// wrong lock syntax
lock(this) {
    // modify buffer object
}

我把锁改成了

private static readonly object _lockObject = new object();

lock(_lockObject) {
    // modify buffer object
}

并使用了建议的 C# 处理语法,问题消失了。

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposed)
            return;

        if (disposing)
        {
            // Free any managed objects here
            buffer?.Free();
        }

        disposed = true;
    }

答案 27 :(得分:0)

我在 IIS 下本地运行 .Net Framework Web API 应用程序时遇到了同样的问题。

问题是我之前已将 IIS 应用程序池的托管管道模式更新为“经典”。将其设置回“集成”为我解决了这个问题。

答案 28 :(得分:0)

对于 Xamarin Forms,可以将代码包装在

Device.BeginInvokeOnMainThread(() => 
{
 //your code
});

我在 UWP 中从错误的线程更新 UI 时发生的事情。

答案 29 :(得分:0)

我遇到了同样的问题,因为我在 Angular 服务上更新时试图覆盖我的模型。

var nu: ExtendedUserSettingModel = this.addUserForm1.value;
// nu.createdOn = this.date; //this was what caused the issue

确保不要覆盖任何写入的数据