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

问题描述 投票:116回答:21

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

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

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

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

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

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

c# .net multithreading memory-management
21个回答
45
投票

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


3
投票

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

你在运行什么操作系统和服务包?


3
投票

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

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


3
投票

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


3
投票

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

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

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

它奏效了。

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

去搞清楚...


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);
    }

1
投票

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

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

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

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

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

我大多发现它更容易看一下腐败的东西(比如一个特定的指针),然后对代码进行手动静态分析,以查看可能已损坏的代码,检查上面显示的常见罪魁祸首。然而,即使这样也不会遇到长链问题。

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


1
投票

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


1
投票

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


1
投票

在VS1017中随机获得此错误,当尝试构建一个前一天构建完美的项目时。重新启动PC修复了问题(我还事先运行了以下命令,不确定是否需要:netsh winsock reset)


1
投票

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

代替

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

使用更大的容量:

StringBuilder windowText = new StringBuilder(3000);

19
投票

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

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


0
投票

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

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

为了解决这个问题,我们不得不在项目中添加以下post-build事件:

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

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


0
投票

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

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

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/


14
投票

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

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

enter image description here


11
投票

尝试运行此命令

netsh winsock重置

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


8
投票

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

转到Visual Studio调试程序以绕过此异常:

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

希望它会有所帮助。


8
投票

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


5
投票

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

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

将项目移动到新计算机时,我建议您续订该项目中添加的所有引用。


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


3
投票

您是否尝试为您的应用程序关闭DEP (Data Execution Prevention)

© www.soinside.com 2019 - 2024. All rights reserved.