- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在解释来自 C# Windows Phone 应用程序的异常报告。方法抛出 NullReferenceException
。方法是:
public void OnDelete(object o, EventArgs a)
{
if (MessageBox.Show(Res.IDS_AREYOUSURE, Res.IDS_APPTITLE, MessageBoxButton.OKCancel) == MessageBoxResult.OK)
m_Field.RequestDelete();
}
这与 m_Field
为 null 是一致的 - 那里根本没有其他可能为 null 的东西。但这是神秘的部分。
异常对象的 StackTrace
中的 StackFrame
中的 GetILOffset()
返回 0x13。如 ILDASM 所示,该方法的 MSIL 为:
IL_0000: call string App.Res::get_IDS_AREYOUSURE()
IL_0005: call string App.Res::get_IDS_APPTITLE()
IL_000a: ldc.i4.1
IL_000b: call valuetype (...) System.Windows.MessageBox::Show(...)
IL_0010: ldc.i4.1
IL_0011: bne.un.s IL_001e
IL_0013: ldarg.0
IL_0014: ldfld class App.Class2 App.Class1::m_Field
IL_0019: callvirt instance void App.Class2::RequestDelete()
IL_001e: ret
这是我不明白的地方。如果偏移确实是 0x13,则意味着 ldarg
行导致了异常。但该命令被记录为不抛出任何异常。应该抛出的是 callvirt
,不是吗?或者是相对于方法开始以外的其他东西的偏移量? ldfld
也可以抛出,但前提是 this
对象为空;这在 C# AFAIK 中是不可能的。
文档提到调试信息可能会影响偏移量,但这是一个发布版本。
我正在使用 ILDASM 检查的 DLL 正是我作为 XAP 的一部分发送到 Windows Phone Store 的那个。
最佳答案
当 JIT 生成机器代码时,它还会生成 MSIL <--> 机器代码映射。当您在生成的代码中遇到异常时,运行时将使用映射来识别 IL 偏移量。
JIT 被允许重新排序机器指令作为其优化的一部分(当它们被启用时),这可能导致映射变得更加近似和细化。如果字段访问被提前(内存访问相对较慢,有时在您需要它之前就开始加载它是很好的),那么异常可能看起来是由更早的 IL 指令抛出的。
我使用了一个调试实用程序来执行以下操作:
然后我在一个虚拟进程上运行该工具,该进程大致执行您在问题中显示的内容,并获得以下内容(发布版本):
IL_0000: call 0600000B
IL_0005: call 0600000A
IL_000A: ldc.i4.1
IL_000B: call 0A000014
IL_0010: ldc.i4.1
IL_0011: bne.un.s 30
----
IL_0013: ldarg.0
IL_0014: ldfld 04000001
IL_0019: callvirt 06000004
----
IL_001E: ret
如您所见,ldarg.0
、ldfld
和 callvirt
指令都包含在同一个映射中,因此如果这些触发异常,它们将全部映射回相同的 IL 偏移量 (0x13)。
关于c# - NullReferenceException 与 MSIL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36682208/
我正在编写一个“弱事件工厂” - 将任何 Delegate 转换为具有相同签名的新委托(delegate)的代码,但在目标上实现 WeakReference。我正在使用 MSIL 来避免对 Deleg
两个混淆相关的问题: 1) 是否有任何工具可以将 F# 从 MSIL 目标形式反汇编回其源形式或接近它的形式?这不是通过默默无闻来实现安全性的尝试,但我想保护某些源代码免遭“盗窃”。 2) 我简要地查
关于 SO 上的 MSIL 有很多问题,但没有一个直接回答这个问题。 我一直在用 Textpad它确实有 MSIL 的语法定义文件,然后在命令提示符窗口中使用 ILASM。 我确实找到了对 ILIDE
我正在尝试为 .NET 平台创建我的语言的后端。前端和解释器用Delphi编写。非托管 API 只允许类型定义,但不允许发出 MSIL。 有哪些方法可以从非托管代码生成 MSIL?不使用 Reflec
是否有任何可读的最新(.net 4)MSIL 引用手册? 最佳答案 有一堆可下载的引用文档here . 包括 2006 年 6 月的 ECMA-335 公共(public)语言基础结构文档 (pdf)
在 VB.NET 中,您可以添加文件引用或项目引用。例如,如果您想使用 SQLConnection 类,那么您可以添加对 System.Data.SQLClient 的引用并导入命名空间。 这在 MS
请查看下面的 MSIL 代码: IL_00: ldstr "Hello World" IL_05: call void [mscorlib]System.Console::W
在 VB.NET 中,您可以添加文件引用或项目引用。例如,如果您想使用 SQLConnection 类,那么您将添加对 System.Data.SQLClient 的引用并导入命名空间。 这在 MSI
假设我的解决方案中有一个 C# Windows 类库,我在 VS2010 IDE 中构建它。我的 bin 目录中的输出是 X.dll 1) X.dll现阶段不包含MSIL,而是“压缩字节码”。 这是真
我正在使用 RemotingLite 库 ( see at github ) 并且 Proxy 类工厂有问题。简而言之,问题是在生成代码以返回 ValueType 对象(如用户定义的结构)时。 部分原
我正在尝试使用 Reflection.Emit(在 c# 中)创建一个新类型。 我要创建的代码类似于 public class { public static int[] A = new int
我试图弄清楚 MSIL 如何能够通过仅存储一个整数来表示对静态函数的调用。 例如,如果您添加对 Interlocked.Increment(ref someVariable) 的调用,您的 IL 将包
我只是想知道这是否可以做到。如果它不包含一些显着的性能优势,我不打算这样做。我是一名网络和游戏开发人员,但我通常不使用 c# 开发游戏。 最佳答案 是的,有可能 - 您可以使用 ilasm (附带 .
有人可以解释这几行 MSIL 吗?为什么它将评估堆栈中的值移到局部变量中,只是立即将其移回并返回? 以下 MSIL 代码加载单个参数(字符串),调用返回 bool 的方法,然后返回该 bool 值。我
这些问题似乎找不到好的答案。 以下是我认为我知道的和我不清楚的。 评估堆栈是一个类似于 C 风格堆栈的内存缓冲区(它是原生 int/size_t 的堆栈)吗? 评估堆栈元素可以是 32 位或 64 位
我可以访问这样的函数体中间语言: byte[] ilCodes = NestedFooInfo.GetMethodBody().GetILAsByteArray(); 我可以修改它的 IL 代码,以便
考虑以下C#代码段: static string input = null; static string output = null; static void Main(string[] args)
我有一组 MSIL/CLR 应用程序(用 C# 编写)。我正在寻找一种将它们刻录到纯硬件平台上的方法。我已经看到 Altera 有一个名为 NIOS II 的嵌入式处理器,它似乎支持 eCLR(嵌入式
在某种同行评审期间调试一些 C# 代码时,我注意到一种奇怪的行为,乍一看似乎是某种范围界定违规,但回想起来,编译器可能试图通过重用引用来节省内存。代码是: for(int i = 0; i < 10;
我尝试使用谷歌搜索和搜索 StackOverFlow,但没有看到明确的答案。如何查看我的 C# 编译成的 IL 代码?我想比较两种方法,看看它们是否产生相同的 IL。我曾看过一个非常棒的视频,内容是这
我是一名优秀的程序员,十分优秀!