【问题标题】:In .NET, why can't a BadImageFormatException be caught inside the method that throws it?在 .NET 中,为什么不能在抛出它的方法中捕获 BadImageFormatException?
【发布时间】:2013-12-23 02:42:47
【问题描述】:

我对声明一个在引用的 Visual C++ 程序集中定义的 Visual C++ 类型的变量时引发的 BadImageFormatException 不感兴趣,但我对异常未被捕获的事实很感兴趣try-catch 语句的 catch 子句紧接在变量声明周围,但由 try-catch 语句的 catch 子句包围对声明变量的方法的方法调用。

    public static void method()
    {
        try
        {
            Some_Visual_Cpp_Type o;
        }
        catch (Exception)
        {
            Console.WriteLine("caught inside the method");//apparently not called
        }
    }
    public static void Main()
    {
        try
        {
            method();
        }
        catch (BadImageFormatException)
        {
            Console.WriteLine("caught outside the method");//prints "caught outside the method"
        }
    }

有人可以解释一下这种行为吗?

【问题讨论】:

    标签: c# c++ exception visual-c++


    【解决方案1】:

    当方法被 JITted 时,在它的 catch 块存在之前抛出这个异常。

    【讨论】:

    • 这对我来说是新的。你知道我在哪里可以找到关于这个主题的更多信息吗?
    • @JSmith 关于什么主题,一般的 JITing 或更具体的东西?
    • 关于由于某种原因引发的异常,但由于代码“JITed”的方式只能由调用代码捕获。
    • @JSmith:其他示例包括加载程序集或静态初始化程序的异常
    【解决方案2】:

    以@Slaks 回答为基础

    在这种特殊情况下,导致BadImageFormatException 的项目确实在方法内部,但这不一定是真的。如果 Some_Visual_Cpp_Type 值被声明为参数会怎样?然后,catch 块将可以访问首先导致BadImageFormatException 的值。

    当可执行文件中的特定位置被确定为不可运行时,会引发BadImageFormatException。 JIT 并没有尝试在方法中选择一个安全点来抛出异常,而是完全放弃了该方法。试图将方法的好的部分与坏的部分区分开来,几乎没有什么收获。对于 JIT 和开发人员来说,将方法声明为完全错误并从那里继续前进要简单得多。

    还请注意,不能保证 BadImageFormatException 在调用方法中甚至是可捕获的。如果 JIT 决定将 method 内联到 Main 内,那么在调用 Main 时将抛出异常,因此在其中无法捕获

    【讨论】:

    • JITter 是否可以在加载方法之前决定内联方法?在那个决定之前不会抛出异常吗?
    猜你喜欢
    • 1970-01-01
    • 2011-11-22
    • 2010-09-17
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    相关资源
    最近更新 更多