繁体   English   中英

用于登录.NET的堆栈跟踪

[英]Stack Trace for logging in .NET

我编写了一个logger / exceptionfactory模块,它使用System.Diagnostics.StackTrace来获取调用方法及其声明类型的属性。 但是我注意到,如果我在发布模式下运行Visual Studio之外的代码,我的一些较短的方法会从堆栈跟踪中内联并丢失。 现在我无法测试一个方法是否会在运行时内联,但我不想[MethodImpl(MethodImplOptions.NoInlining)]每个重要的方法。 但是如果我的基类中的方法因此而丢失,我可能会误读层和操作信息,这可能导致错误的日志或错误参数化的异常。

是否有一条经验法则是何时何地内联? 虚方法,静态方法,基类方法是否有任何不同? 我只需要担心内部装配内联吗? 内部名称空间

是的,有一些规则,但它们是JIT编译器使用的启发式方法,这些启发式方法可能会在瞬间发生变化。

  1. 无法内联虚拟方法。
  2. 另一方面,接口方法可能是内联的,尽管我不能100%确定这是否会使堆栈跟踪崩溃。
  3. 当然可以内联静态方法和非虚拟实例方法。
  4. 内联可能跨越名称空间(当然)和程序集(不那么明显),因为它发生在运行时,当JIT编译方法调用时。
  5. “重”方法不会被内联。 这取决于“重”的定义,并且是JIT适用的启发式的一部分。

我所知道的一些“沉重”的启发式:

  • 不使用异常处理(即try-catch或try-finally块)的方法。
  • 没有内联使用大代码(大约32个IL字节,但我可能记得这个错误)的方法。
  • 没有内联循环的方法(除非循环可以完全展开或消除)。

启发式算法都是抖动的实现细节,这意味着它们没有正式记录,并且可能随时会发生变化。

话虽如此,这里有一些你可能会感兴趣的文章(虽然其中一些现在有点长):

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM