内联函数的堆栈跟踪是否在抛出的异常中保留?

问题描述:

Release 模式编译可执行文件时-启用了代码优化功能-编译器可能会选择内联满足某些条件的函数以提高性能.

When compiling an executable in Release mode -with code optimizations enabled- the compiler may opt to inline functions that meet certain criteria in order to improve performance.

我的问题是:当内联函数的主体中引发异常时,无论内联扩展如何,都将保留stacktrace信息吗?换句话说,它将显示吗?原始函数是错误的根源,还是会显示调用函数?

My question is this: when an exception is thrown in the body of a function that has been inlined, will the stacktrace information be preserved regardless of the inline expansion? In other words, will it show the original function as the source of error, or will it show the calling function instead?

这取决于引发异常的方式.如果使用 throw 语句,那么就没有问题,抖动不会内联包含throw的方法.需要注意的一点是,何时需要快速使用属性设置器.

It depends how the exception was thrown. If you use the throw statement then you don't have a problem, the jitter won't inline methods that contain a throw. Something to be aware of when you need a property setter to be fast btw.

但是,如果异常是由正常执行引起的,例如NullReferenceException或IndexOutOfRangeException等,那么是的,如果该方法是内联的,则不会在堆栈跟踪中看到该方法的名称.这可能有些令人困惑,但是通常您可以从调用方法的源代码和异常类型中找出来.希望它相对较小. [MethodImpl(MethodImplOptions.NoInlining)]属性可用于禁止内联.到您发现这会有所帮助时,通常为时已晚;)

However, if the exception is caused by normal execution, like a NullReferenceException or IndexOutOfRangeException etc, then yes, you don't see the name of the method on the stack trace if it was inlined. This can be a bit bewildering but you usually figure it out from the source code of the calling method and the exception type. Hopefully it is relatively small. The [MethodImpl(MethodImplOptions.NoInlining)] attribute is available to suppress inlining. By the time you discover it would be helpful it is usually too late ;)