在奇怪的情况下抛出AccessViolationException

时间:2014-12-03 21:07:05

标签: c# asp.net .net iis access-violation

我在c#中待了很长时间,但我从来没有遇到过这种错误。首先,你是否看到关于这个单一代码块的任何错误(可能是错误的)(当然除了它的逻辑,我知道它总是返回0)?

public static int GetDecimals(MySimpleEnum val)
    {
        int result = 0;
        switch (val)
        {
            case MySimpleEnum.Base:
            case MySimpleEnum.Slow:
            case MySimpleEnum.Normal:
            case MySimpleEnum.Quick:
            case MySimpleEnum.Fastest:
                result = 0;
                break;
        }            
        return result;        
    }
  

发布项目设置: DEBUG constant = false; TRACE constant = true;优化Code​​ = true;输出/高级/调试信息=无;

     

IIS =版本7.5

此方法具有指定的版本设置会抛出“ System.AccessViolationException :尝试读取或写入受保护的内存。这通常表示其他内存已损坏。”

这是有趣的部分。这些情况是在它没有抛出此异常的情况下:

  1. 在IIS(Express和not-Express)8.5上运行它(不需要项目编辑)。
  2. 设置优化代码= false;和输出/高级/调试信息=错误;
  3. 将内部方法包装到try / catch块中(尝试使用catch块中的log4net记录异常 - 空日志)
  4. 用一些不同的代码替换方法的内部。
  5. 注意事项:

    • 必须在服务器上使用win调试器捕获异常(没有 调用常规.NET异常处理程序)
    • 异常后应用程序崩溃。
    • 此代码块几个月前正在运行(很长一段时间没有发布)。错误开始可能是一些更新。
    • 使用IIS 7.5和一台具有IIS 8.5和IIS Express(VS2012)的计算机进行了测试。相同的结果。
    • 我尝试了很多不同的项目设置组合。基本上,如果我没有像第2点那样设置设置,它会抛出 IIS 7.5上的异常。
    • 我的工作(和构建)计算机正在运行带有最新更新的Windows 8.1。
    • 代码块位于单独的项目(类库)中。

    我知道如何解决这个问题。但我不喜欢关闭问题,而不知道原因。另外,我想在将来避免这种情况。你认为你可以帮助我吗?如果它是一些空引用异常,为什么会发生这种情况?为什么它是特定于调试/发布或特定于IIS版本的?

    * Note2

    最近我在发布时遇到了丢失dll(System.Net.Http.Formatting.dll,System.Web.Http.dll,System.Web.Http.WebHost.dll)的问题。这是因为一些微软的安全更新。也许这是类似的东西。*

    修改1 添加枚举声明的结构。

    public enum MySimpleEnum
        {
            Base = 0,
            Slow = 1,
            Normal = 2,
            Quick = 3,
            Fastest = 4
        }
    

    另外,我刚尝试添加[MethodImpl(MethodImplOptions.NoInlining)],但没有帮助。

2 个答案:

答案 0 :(得分:3)

从托管代码中获取这些类型的访问冲突错误是非常典型的。它们来自内存损坏,可以指示硬件故障 - 在极少数情况下,这表明CLR本身存在错误。

此类错误的最可能原因来自其他地方,例如:如果此代码以某种方式使用本机代码 - 在不安全的上下文中调用本机代码或从本机代码调用。

引用MSDN AccessViolationException

  

在完全由可验证的托管代码组成的程序中,所有引用都是有效的或无效的,并且访问违规是不可能的。仅当可验证的托管代码与非托管代码或不安全的托管代码交互时,才会发生AccessViolationException。

在任何情况下,您通常需要查看代码中的其他位置以查找损坏内存的错误代码。不幸的是,这是一个非常难以解决的问题。祝你好运!

答案 1 :(得分:0)

我不确定这是否仍然与您相关,但我设法通过在完全托管的代码部分中更改非常小且无关紧要的bool来生成此AccessViolation错误。 然而,最好的部分,如果我在该子项目的编译器中禁用代码优化,一切运行正常。这似乎是编译器在非常特殊的情况下引入的错误,不需要任何逻辑意义。