我正在开发一个编译器,在扩展生成器的某些情况下,它会产生错误的输出。PEVerify只是简单地说“”,但没有给出任何解释。当我在过去看到这种情况时,通常是因为生成的类型有错误的泛型参数,但是这里的一切似乎都是匹配的。
有什么好的方法可以更详细地了解生成的类型出了什么问题吗?否则,有什么好的技巧和技巧来追踪错误吗?
来自PEVerify的输出:
C:\Build\Test>peverify testcase.exe /VERBOSE /UNIQUE 微软(R) .NET框架PE验证器。版本4.0.30319.0版权(c)微软公司。版权所有。 错误: Testing.Linq_operatorModule::IndexWhereImpl[T]offset 0x00000002无法解析令牌。 IL: C:\Build\Test\testcase.exe :C:\Build\Test\testcase.exe: HRESULT 0 x8007000B -尝试加载格式不正确的程序。 令牌0x02000004类型加载失败。 验证testcase.exe的3个错误
来自ILDasm的综合转储是这里,因为它太大了,不能放进这样的帖子。
发布于 2017-01-02 15:26:39
在生成此代码的任何代码中,类型参数的绑定都有问题。由此产生的IL可以组装,但是非常无效,以至于PEVerify完全阻塞了它(这可以说是PEVerify中的一个bug,但是像Mono.Cecil这样的东西也一点也不喜欢这段代码)。
例如:
.method /*06000002*/ private hidebysig static
class [mscorlib/*23000004*/]System.Collections.Generic.IEnumerable`1/*01000003*/<int32>
IndexWhereImpl<T>(class [mscorlib/*23000004*/]System.Collections.Generic.IEnumerable`1/*01000003*/<!!T> coll,
class [mscorlib/*23000004*/]System.Func`2/*01000004*/<!!T,bool> 'filter') cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: newobj instance void Testing.Linq_operatorModule/*02000002*//$IndexWhereImpl$3`1/*02000003*/::.ctor(class [mscorlib/*23000004*/]System.Collections.Generic.IEnumerable`1/*01000003*/<!!T>,
class [mscorlib/*23000004*/]System.Func`2/*01000004*/<!!T,bool>) /* 06000006 */
IL_0007: ret
} // end of method Linq_operatorModule::IndexWhereImpl反汇编构造函数调用无效;正确的调用将是
newobj instance void class Testing.Linq_operatorModule/$IndexWhereImpl$3`1<!!T>::.ctor(
class [mscorlib]System.Collections.Generic.IEnumerable`1<!0>,
class [mscorlib]System.Func`2<!0,bool>
)最初的调用适用于泛型方法,但我们不是调用泛型方法,而是调用泛型类的实例方法。
其余代码如下所示,包括具有无效参数引用的字段:
.field assembly !!0 $value$5!!0引用泛型方法的第一个类型参数,您不能在方法中声明字段,所以这总是错误的。它组装到0x1e 0x00 (ELEMENT_TYPE_MVAR 0),您需要0x13 0x00 (ELEMENT_TYPE_VAR 0),对应于
.field assembly !0 $value$5这让人有点惊讶,我希望他们能更有洞察力。显然,PEVerify的作者也是如此,尽管这不是借口。
我不确定您是如何生成这样的代码的;这可能是一个地方的错误,导致其他代码也无效。
https://stackoverflow.com/questions/41415355
复制相似问题