编译时使用的Bug?导致PEVerify失败的错误图像

Joh*_*ohn 16 c# roslyn c#-6.0 visual-studio-2015

我偶然发现了一些奇怪的事情:我BadImageFormatException不知道它可能会引用什么图像(汇编).

我减少了解决方案,使它只包含一个没有依赖项的项目:

在此输入图像描述

如您所见,它只使用System(和mscorlib),当然我不会在运行时加载程序集.

它编译为AnyCpu与.NET 4.5.2,VS 2015与C#6,虽然这些都不重要.

我尝试使用C#5制作样本,但是一旦我替换了所有的"?".运营商,它停止发生.

我主持了这个项目,以便人们可以自己尝试:

git clone -b crash-sample https://github.com/jtheisen/moldinium.git
Run Code Online (Sandbox Code Playgroud)

我在4台机器上进行了清洁和测试,所有这些都显示出相同的效果.

崩溃的堆栈跟踪是:

Ex.: System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
   at IronStone.Moldinium.LiveList.<>c__DisplayClass10_0`1.<Where>b__2(ListEvent`1 v)
   at IronStone.Moldinium.ActionObserver`1.OnNext(T value) in C:\Source\Repos\moldinium\ConsoleApplication1\Rx.cs:line 51
...snipped...
Run Code Online (Sandbox Code Playgroud)

在输出上运行PEVerify会产生以下错误:

[IL]:错误:[C:\ Source\Repos\moldinium\ConsoleApplication1\bin\Debug\Bad.exe:IronStone.Moldinium.LiveList + <> c__DisplayClass10_0`1 [TSource] :: b__2] [offset 0x0000013B]无法解析令牌.

?.从Select.cs文件中删除所有操作符可以解决该问题.

使用ILSpy我已将问题隔离到:

IronStone.Moldinium.LiveList.<>c__DisplayClass10_0`1.<Where>b__2
Run Code Online (Sandbox Code Playgroud)

您可以在主旨看(通过ILSpy)方法的IL转储这里.Bad IL是使用?.Good IL时的C#5.0风格.

这是用VS2015.3构建的

CSC版本:Microsoft(R)Visual C#编译器版本1.3.1.60616

Dud*_*eti 3

我帮不了你,因为这确实是一个错误。但我可以带你到错误发生的地方,它可能会帮助你用几行代码重现错误。

namespace ElvisBugInNullableGenericStructWithNestedTypeParameter
{
    struct MyGenericStruct<T> { }
    class Program
    {
        static void Main() { }

        void Test<T>()
        {
            Func<T, bool> func = (arg =>
                {
                    MyGenericStruct<T>? v1 = null;
                    return v1?.ToString() == null;
                });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

MyGenericStruct<T>?如果我用它替换MyGenericStruct<int>?就会起作用。

问题是,由于某种原因,当我们在可为 null 的结构中使用外部T,然后尝试使用 Elvis 运算符时,?类型未知(无法解析令牌)。

更新 如果您想修复您的情况,则无需删除所有 Elvis 运算符,只需将它们从方法Subscribe内的操作中删除即可public static ILiveList<TSource> Where<TSource>(this ILiveList<TSource> source, Func<TSource, Boolean> predicate)