Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何诊断;类型“加载失败”;来自PEVerify_C#_.net_Cil_Ildasm_Peverify - Fatal编程技术网

C# 如何诊断;类型“加载失败”;来自PEVerify

C# 如何诊断;类型“加载失败”;来自PEVerify,c#,.net,cil,ildasm,peverify,C#,.net,Cil,Ildasm,Peverify,我正在开发一个编译器,它在扩展生成器的某些情况下会产生不好的输出。PEVerify只是简单地说“类型加载失败”,而没有解释原因。当我在过去看到这一点时,通常是因为生成的类型具有错误数量的泛型参数,但这里的一切似乎都匹配 有没有什么好方法可以获得关于生成的类型出了什么问题的更详细信息?除此之外,对于如何追踪错误,有什么好的技巧和技巧吗 PEVerify的输出: C:\Build\Test>peverify testcase.exe/VERBOSE/UNIQUE Microsoft(R).NET F

我正在开发一个编译器,它在扩展生成器的某些情况下会产生不好的输出。PEVerify只是简单地说“类型加载失败”,而没有解释原因。当我在过去看到这一点时,通常是因为生成的类型具有错误数量的泛型参数,但这里的一切似乎都匹配

有没有什么好方法可以获得关于生成的类型出了什么问题的更详细信息?除此之外,对于如何追踪错误,有什么好的技巧和技巧吗

PEVerify的输出:

C:\Build\Test>peverify testcase.exe/VERBOSE/UNIQUE

Microsoft(R).NET Framework PE验证程序。版本4.0.30319.0 版权所有(c)微软公司。版权所有

[IL]:错误:[C:\Build\Test\testcase.exe:Testing.Linq_operatorModule::IndexWhereImpl[T]][mdToken=0x6000002][offset 0x00000002]无法解析令牌

[IL]:错误:[C:\Build\Test\testcase.exe:Testing.Linq_operatorModule+$IndexWhereImpl$3`1[T]::.ctor][mdToken=0x600006][HRESULT 0 x8007000B]-试图加载格式不正确的程序

[令牌0x02000004]类型加载失败

验证testcase.exe时出现3个错误


来自ILDasm的全面转储是错误的,因为它太大,无法放入SO post。

在生成此代码的任何程序中绑定类型参数都有问题。由此产生的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
!!0
引用泛型方法的第一个类型参数,并且不能在方法中声明字段,因此这总是错误的。它组合到
0x1e 0x00
元素类型0
),您想要
0x13 0x00
元素类型0
),对应于

.field assembly !0 $value$5
ilasm和ildasm甚至允许这样做,这有点令人惊讶,我希望他们能更敏锐一点。很明显,PEVerify的作者也证实了这一点,尽管这不是借口


我不确定如何生成这样的代码;这可能是一个地方的错误,导致其他地方也无效。

我用CCI生成这样的代码,这将很高兴地生成完全、可笑的无效IL。。。但与Reflection.Emit不同,它实际上会生成它,而不是因为类型问题而窒息,并给我一个黑盒错误,无法运行ILDasm和PEVerify来找出哪里出了问题。所以,谢谢。我将研究泛型类型绑定。这实际上是有道理的。编译器正在将泛型方法转换为生成器,并将方法局部变量提升到生成器类的字段中,这意味着它们仍然被标识为使用来自原始方法的泛型类型参数。是时候解决这个问题了。在你的例子中,这不是一个原因,但我得到了一个“类型加载失败”,因为我忘了向一个方法添加“newslot”修饰符。
.field assembly !!0 $value$5
.field assembly !0 $value$5