MethodBase.GetCurrentMethod 何时可靠/可预测?
方法可以内联;有一个属性可以防止这种情况(“有一个 att ”)。然而,显然,由于 JITter 的尾部调用优化,方法也可能无法在 x64 上获得自己的堆栈帧(http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInlinedInReleaseBuildCallStacks.aspx)。这会影响 MethodBase.GetCurrentMethod 的行为吗?
我能找到的讨论主要是关于内联的(什么时候方法可以被 CLR 内联?)。虽然这些讨论本身很有趣,但我的问题实际上是在什么情况下(如果有的话)可以依赖 MethodBase.GetCurrentMethod
来识别程序员调用的相同方法(例如,对于后期绑定到当前方法实际上是代理的方法)。内联是一种可以欺骗 MethodBase.GetCurrentMethod
的方法,但我想知道这是否是唯一的方法?
A method could get inlined; there is an attribute to prevent that ("there's an att for that"). However, apparently a method may also not get its own stack frame on x64 due to tail-call optimization by the JITter (http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx). Would this affect the behavior of MethodBase.GetCurrentMethod
?
The discussions that I can find are mostly about inlining (When is a method eligible to be inlined by the CLR?). While those discussions are interesting in their own right, my problem is really about under what circumstances -- if any -- that MethodBase.GetCurrentMethod
can be relied upon to identify the same method where the programmer placed the call (e.g., for late binding to a method for which the current method is really a surrogate). Inlining is a way that MethodBase.GetCurrentMethod
could be fooled, but I wonder if it is the only way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
否 - 方法要么在运行时内联,要么不内联。
我相信,如果有人要实现自己的运行时,它可能会被愚弄 - 因为
MethodBase.GetCurrentMethod
最终归结为在RuntimeMethodHandle
中声明的:在自定义运行时中,它可以做任何事情 - 将来它也可以做任何事情。目前,我认为 Microsoft 运行时不会返回正确方法的唯一方法是内联代码;例如,不能代表 Mono。然而,我认为,始终依赖这种情况就像依赖始终存在的内部类型的反射私有字段来使一段代码能够工作一样。
在几乎所有我尝试过的情况下(我现在不再担心它)或者有人试图证明需要能够可靠地识别调用方法,除了分析之外,内联方法的问题总是会出现。
但现实是,担心这些方法有多重要?
如果可靠性绝对至关重要,那么您会更幸运 使用 IL 重写器后编译来注入日志记录调用;这可能必然是方法感知的,因此可能会破坏内联,即使它发生了(如果重写的 IL 变得足够大,从而损害性能,则可能不会)。或者,如果您不喜欢自己开发,可以使用 AOP 库 - 例如 PostSharp。
No - a method is either inlined at run time or it isn't.
It can be fooled, I believe, if somebody were to implement their own runtime - as
MethodBase.GetCurrentMethod
ultimately boils down to this, declared inRuntimeMethodHandle
:In a custom runtime, that could do anything - and in the future it could also do anything too. At the moment, I believe the only way that the Microsoft runtime(s) will not return the correct method is if the code is inlined; can't speak for Mono, for example. Relying on that always to be the case, however, is like relying on a reflected private field of an internal type always to be present to enable a piece of code to work, I think.
In nearly every case where I have tried (I no longer worry about it now) or someone tries to justify needing to be able to reliably identify the calling method, outside of profiling, the issue of inlined methods always comes up.
The reality is, though, how important is it to worry about those methods?
If reliability is absolutely crucial, you will get more luck Using an IL-rewriter post compilation to inject the logging calls; this can be necessarily method-aware and therefore can subvert the inlining, even if it takes place (which it might not if the rewritten IL becomes bulky enough, thus hurting performance). Or if you don't fancy rolling your own, an AOP library might be in order - such as PostSharp.