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


144

我希望有人能启发我有关可能导致此错误的原因:

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

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

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

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

我尝试关闭编译器优化和几个Microsoft修补程序。似乎没有什么可以解决这个问题。如果有人知道任何可能的原因,或某种方式识别导致问题的原因,将不胜感激。


请发布完整的通话堆栈...
Mitch Wheat


大约有一半的时间我无法获得调用堆栈。如果抛出致命执行错误,则根本没有调试信息。它实际上确实停止在代码中某处的时间,似乎没有异常。我什至遍历了所有活动线程,还没有看到任何可能引起冲突的内容。我假设内存损坏在引发错误之前发生了一段时间。
其他人

检查是否使用了cr脚的旧COM和ActiveX组件。我也知道SQLCE在多线程环境中会出现这种情况。
嬉皮

没有COM或ActiveX组件。
别人

Answers:


50

我刚刚在带有MapInfo DLL的VS 2013 .NET 4.5中遇到了此问题。原来,问题是我将构建平台从x86更改为Any CPU,足以触发此错误。把它改回x86就可以了。可能会帮助某人。


1
您如何用x86改回来的。我只是对这个指令感到同样的问题CSingleLock lock(&m_csMember, TRUE);有关更多详细信息,这是我的帖子
ABCmo 2014年

在VS 2012/2013中,转到“项目属性”->“构建”,然后将“平台目标”更改为所需的内容。尽管我认为可以在另一个地方进行更改,但是我似乎找不到它,但是我认为这两种方法都应达到相同的结果。
谢尔盖(Sergey)2014年

我实际上使用的是VS 2013,它的配置为x86:/
ABCmo 2014年

1
您的问题可能是由许多原因引起的,我很惊讶通过更改构建平台解决了我的问题。您可以说是个幸运的逃生。
谢尔盖

此解决方案结合此答案为我解决了它。
Zach Posten

23

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

进行更改最终使我确定了问题所在:转到控制台应用程序项目的项目属性(或者,在解决方案资源管理器中选择项目文件,然后按Alt+ Enter组合键)->转到Debug选项卡->滚动到Enable Debuggers右窗格中的部分->检查在Enable unmanaged code debugging如下所示的快照复选框- >点击Floppy工具栏中的按钮保存项目属性。我为什么还不知道为什么会发生这种情况的根本原因。我观察到的唯一一件事是,前一天晚上在我的计算机上安装了许多Windows更新,这些更新主要由Office更新和OS更新组成(有十几篇KB文章)。

在此处输入图片说明

更新:VS 2017起,设置名称已更改,如以下屏幕截图所示:

在此处输入图片说明


1
从VS 2017开始,此名称已重命名为“ 启用本机代码调试
Chiramisu

1
感谢@Chiramisu提供最新信息并为社区提供帮助。我已经更新了答案,使其适用于Visual Studio的较新版本。
RBT

19

最终在WinDBG和SOS的帮助下进行了跟踪。某些未知的DLL引发访问冲突。原来是一个名为“ Nvidia Network Manager”的软件引起了问题。我已经读过无数次有关防火墙或防病毒引起的问题的信息,而我都没有使用它们,所以我拒绝了这个想法。另外,我还假设它不是环境的,因为它发生在使用不同硬件的多于一台服务器上。原来我测试过的所有机器都运行“ NVidia Network Manager”。我相信它会与其余的主板驱动程序一起安装。

希望这对某人有帮助,因为这个问题困扰了我的应用很长时间。


1
在我的情况下,当我频繁地从设备读取数据引发异常时,我使用Thread.Sleep(1000)停止了一段时间的读取。和完美的工作。
JRB 2014年

6
我以为治愈是“卸载NVidia网络管理器”
paulm 2014年

79
投票最多的答案,不提供任何逻辑答案。
Teoman shipahi 2015年

我怀疑我的主板或软件中是否存在与nvidia相关的内容。我正在使用Visual Studio2010。此问题仅在从VS调试项目期间发生。它的输出exe从debug文件夹运行良好。
RBT

1
我正在访问导致问题的我自己进程的线程。
穆罕默德·萨奇布

13

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



8

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

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

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

希望会有所帮助。


3
抱歉,它不适用于您。我认为,由于许多原因引发此错误,如果原因是JIT优化,我发布的解决方案可能会为其他人解决问题。
curiousBoy 2013年


5

可能是硬件。这可能很复杂...但是我建议您的线程代码没有使用适当的锁保护某个集合(例如字典)的地方。

您正在运行什么操作系统和Service Pack?


1
运行XP 64 SP2。但是,这已在多台服务器上发生。我已经经历了很多次,而且我看不到任何线程安全的问题。我也不会收到集合修改错误而不是访问冲突吗?
其他人

5

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

在尝试了许多事情(包括安装修补程序)之后,我尝试了在项目中更改对Oracle.DataAccess和System.Data.OracleClient的引用,并且它起作用了!

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


4

您是否尝试为应用程序关闭DEP(数据执行保护)


2
我不确定这是个好主意。它可能会延迟崩溃的时间,但是会造成更大的损失。我认为,如果您要崩溃,最好的主意是尽早崩溃:-)
paxdiablo 2010年

1
关闭DEP是不明智的,但却是有用的诊断练习。
vcsjones

4

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


我面临着同样的问题-autocad .net dll-您能详细说明问题和解决方法是什么吗?
BKSpurgeon

3

这个问题几乎总是一个简单的问题。该代码是错误的。仅从统计分析来看,它很少是工具。每天都有成千上万的人在使用Visual Studio,也许只有少数人在使用您的代码-哪一部分代码得到了更好的测试?我保证,如果这是VS的问题,我们可能已经找到了。

该语句的意思是,当您尝试访问不是您自己的内存时,通常是因为您正在使用损坏的指针执行此操作,而该指针来自其他地方。这就是为什么要说明指示的原因。

由于内存损坏,错误的捕获很少接近错误的根本原因。效果正是您所描述的,看似随机。您只需要查看常见的问题,例如:

  • 未初始化的指针或其他值。
  • 向缓冲区写入的内容超出其大小。
  • 不受互斥量保护的线程共享的资源。

鉴于在问题的产生与发现之间已经发生了太多的事情,从这样的问题中进行反向工作以找到根本原因非常困难。

我主要是觉得它更容易来看看什么腐败(比如,一个特定的指针),然后执行代码的手工静态分析,看看有什么可能损坏它,如上图所示为通常的罪魁祸首检查。但是,即使这样也不会遇到很长的问题。

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


3
您也可以从错误的内存中获取损坏的指针。如果在具有ECC内存的服务器上没有发生这种情况,请尝试长时间运行的内存测试实用程序以消除造成硬件问题的原因。
cdonner

12
我知道它不是硬件问题,因为它发生在多台服务器上。感谢您指出代码船长中有明显的问题。我不是在怪视觉工作室。如前所述,应用程序可以在随机的一段时间内正常运行。它不容易重现,并且我已经尝试找出问题了好几个星期了。
其他人

5
@Someone Else:我几乎不认为打电话给您会获得很大帮助。
米奇小麦

2
@Someone Else,鉴于您所提供的信息有限,我已竭尽所能。即使是世界上最好的医生也不能对一个只说“我受伤”的患者做很多事情:-)如果您想提供更多具体信息,那么也许我们可以提供更多帮助。
paxdiablo

5
错误的答案,但是方法,无耻的猜测,不合理的假设,没有提供解决方案...为什么这个答案仍然存在?究竟有3个人可能对此答案表示赞同?
ThunderGr 2014年

3

可验证的代码不应能够破坏内存,因此存在一些不安全的情况。您是否在任何地方使用任何不安全的代码,例如在缓冲区处理中?同样,有关PInvoke的内容可能也不是无关紧要的,因为PInvoke涉及到向非托管代码和相关封送处理的过渡。

我最好的建议是附加到崩溃的实例上,并使用WinDBG和SOS来更深入地了解崩溃时发生的情况。这不是出于胆小,但此时,您可能需要使用更强大的工具来确定到底出了什么问题。


它在错误消息中提到PInvoke是可能的原因。没有不安全的代码。我将尝试WinDBG。谢谢。
某人

3

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

我们在项目中使用的某些Twain32库始终抛出此异常,但只会在我的计算机中发生。

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

而且有效。

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

去搞清楚...


3

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

代替

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

使用更大的容量:

StringBuilder windowText = new StringBuilder(3000);

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

2

我在VB.NET中使用的项目中遇到了相同的错误。检查属性页上的“启用应用程序框架”可以为我解决。


1

我也有这个问题 。我使用Visual Studio同时运行不同的解决方案,当关闭其他解决方案并仅运行目标解决方案时,它运行良好,没有出现该错误。


1

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


1
VS 2017正是我的情况-System.AccessViolationException:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。我只是重新启动PC即可解决此问题,而无需执行其他任何操作。

0

我的答案在很大程度上取决于您的方案,但是我们尝试为超过10年的客户端升级.NET应用程序时遇到问题,以便他们可以使其在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)"

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


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/


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为我解决了该问题。


0

我有同样的错误信息:

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

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


0

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


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.