发生异常时如何获取IL指令偏移量?
How to get IL instruction offset when exception happens?
我想在发生异常时获取 IL 指令偏移量(从方法开始)。
例如我有对象初始值设定项:
var obj = new SomeObject {
F1 = something.A,
F2 = something.B,
F3 = something.C,
F4 = something2.A,
F5 = something.D
};
如果 something2
将是 null
- 将抛出异常。
异常堆栈跟踪将指向第一行:
var obj = new SomeObject {
我能否获得问题对象的准确 IL 代码偏移量?
在这个例子中,我想得到这条指令的偏移量:
callvirt instance void SomeClass2::get_A(class SomeClass2)
更新:已发布的答案 here(通过 PDB)在这种情况下不起作用,因为线会指向同一个地方。
不确定它是否能准确解决您的问题,但如果您使用 ildasm
获取程序集的 IL 列表,那么您可以重构程序集并使用以下方法生成新的 .pdb:ilasm /PDB /DEBUG ...
(程序集应该在功能上等同于原始程序集,尽管不是逐字节相同)。
这个过程的有趣之处在于生成的 .pdb 将 IL 列表视为 "source",因此只要您的 IDE 可以找到 .pdb 和 IL 列表,您可以像单步执行普通 C# 一样逐条执行 IL 指令,并且您还会看到它们发生的 IL 指令异常(即使对于 属性 初始值设定项,如您的示例)。
如果遇到异常中断,您可以在监视 window 中创建一个 StackTrace 对象,将异常传递到其构造函数并在第一帧调用 GetILOffset()
(类似于 new StackTrace($exception).GetFrame(0).GetILOffset()
IIRC)。
话虽如此,JIT 可能最终会将所有为该语句生成的本机代码映射到相同的 IL 偏移量,在这种情况下,除了分解该语句之外,您无能为力。
我想在发生异常时获取 IL 指令偏移量(从方法开始)。
例如我有对象初始值设定项:
var obj = new SomeObject {
F1 = something.A,
F2 = something.B,
F3 = something.C,
F4 = something2.A,
F5 = something.D
};
如果 something2
将是 null
- 将抛出异常。
异常堆栈跟踪将指向第一行:
var obj = new SomeObject {
我能否获得问题对象的准确 IL 代码偏移量?
在这个例子中,我想得到这条指令的偏移量:
callvirt instance void SomeClass2::get_A(class SomeClass2)
更新:已发布的答案 here(通过 PDB)在这种情况下不起作用,因为线会指向同一个地方。
不确定它是否能准确解决您的问题,但如果您使用 ildasm
获取程序集的 IL 列表,那么您可以重构程序集并使用以下方法生成新的 .pdb:ilasm /PDB /DEBUG ...
(程序集应该在功能上等同于原始程序集,尽管不是逐字节相同)。
这个过程的有趣之处在于生成的 .pdb 将 IL 列表视为 "source",因此只要您的 IDE 可以找到 .pdb 和 IL 列表,您可以像单步执行普通 C# 一样逐条执行 IL 指令,并且您还会看到它们发生的 IL 指令异常(即使对于 属性 初始值设定项,如您的示例)。
如果遇到异常中断,您可以在监视 window 中创建一个 StackTrace 对象,将异常传递到其构造函数并在第一帧调用 GetILOffset()
(类似于 new StackTrace($exception).GetFrame(0).GetILOffset()
IIRC)。
话虽如此,JIT 可能最终会将所有为该语句生成的本机代码映射到相同的 IL 偏移量,在这种情况下,除了分解该语句之外,您无能为力。