dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
18.91k stars 4.01k forks source link

Microsoft.Cci.PdbWriter.GetAssemblyReferenceAlias throws Null Reference exception #74872

Open WindingWinter opened 3 weeks ago

WindingWinter commented 3 weeks ago

This happens with VS 2022 ( 17.11.1 version).

I have a solution, that will throw me Null Reference Exception because I'm using Global Usings. Here's the stack trace:

13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error : Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.Cci.PdbWriter.GetAssemblyReferenceAlias(IAssemblyReference assembly, HashSet`1 declaredExternAliases)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.Cci.PdbWriter.TryEncodeImport(UsedNamespaceOrType import, HashSet`1 declaredExternAliasesOpt, Boolean isProjectLevel)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.Cci.PdbWriter.DefineNamespaceScopes(IMethodBody methodBody)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.Cci.PdbWriter.SerializeDebugInfo(IMethodBody methodBody, StandaloneSignatureHandle localSignatureHandleOpt, CustomDebugInfoWriter customDebugInfoWriter)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.Cci.MetadataWriter.SerializeMethodBodies(BlobBuilder ilBuilder, PdbWriter nativePdbWriterOpt, Blob& mvidStringFixup)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.Cci.MetadataWriter.BuildMetadataAndIL(PdbWriter nativePdbWriterOpt, BlobBuilder ilBuilder, PooledBlobBuilder& mappedFieldDataBuilder, PooledBlobBuilder& managedResourceDataBuilder, Blob& mvidFixup, Blob& mvidStringFixup)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.Cci.PeWriter.WritePeToStream(EmitContext context, CommonMessageProvider messageProvider, Func`1 getPeStream, Func`1 getPortablePdbStreamOpt, PdbWriter nativePdbWriterOpt, String pdbPathOpt, Boolean metadataOnly, Boolean isDeterministic, Boolean emitTestCoverageData, Nullable`1 privateKeyOpt, CancellationToken cancellationToken)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.Compilation.SerializePeToStream(CommonPEModuleBuilder moduleBeingBuilt, DiagnosticBag metadataDiagnostics, CommonMessageProvider messageProvider, Func`1 getPeStream, Func`1 getMetadataPeStreamOpt, Func`1 getPortablePdbStreamOpt, PdbWriter nativePdbWriterOpt, String pdbPathOpt, RebuildData rebuildData, Boolean metadataOnly, Boolean includePrivateMembers, Boolean isDeterministic, Boolean emitTestCoverageData, Nullable`1 privateKeyOpt, CancellationToken cancellationToken)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.Compilation.SerializeToPeStream(CommonPEModuleBuilder moduleBeingBuilt, EmitStreamProvider peStreamProvider, EmitStreamProvider metadataPEStreamProvider, EmitStreamProvider pdbStreamProvider, RebuildData rebuildData, Func`2 testSymWriterFactory, DiagnosticBag diagnostics, EmitOptions emitOptions, Nullable`1 privateKeyOpt, CancellationToken cancellationToken)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.CommonCompiler.CompileAndEmit(TouchedFileLogger touchedFilesLogger, Compilation& compilation, ImmutableArray`1 analyzers, ImmutableArray`1 generators, ImmutableArray`1 additionalTextFiles, AnalyzerConfigSet analyzerConfigSet, ImmutableArray`1 sourceFileAnalyzerConfigOptions, ImmutableArray`1 embeddedTexts, DiagnosticBag diagnostics, ErrorLogger errorLogger, CancellationToken cancellationToken, CancellationTokenSource& analyzerCts, AnalyzerDriver& analyzerDriver, Nullable`1& generatorTimingInfo)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.CommonCompiler.RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, CancellationToken cancellationToken)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.CommonCompiler.Run(TextWriter consoleOutput, CancellationToken cancellationToken)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.CSharp.CommandLine.Csc.<>c__DisplayClass1_0.<Run>b__0(TextWriter tw)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.CommandLine.ConsoleUtil.RunWithUtf8Output[T](Func`2 func)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.CSharp.CommandLine.Csc.Run(String[] args, BuildPaths buildPaths, TextWriter textWriter, IAnalyzerAssemblyLoader analyzerLoader)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.CommandLine.BuildClient.RunLocalCompilation(String[] arguments, BuildPaths buildPaths, TextWriter textWriter)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.CommandLine.BuildClient.RunCompilation(IEnumerable`1 originalArguments, BuildPaths buildPaths, TextWriter textWriter, String pipeName)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.CommandLine.BuildClient.Run(IEnumerable`1 arguments, RequestLanguage language, CompileFunc compileFunc, CompileOnServerFunc compileOnServerFunc, ICompilerServerLogger logger)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.CSharp.CommandLine.Program.MainCore(String[] args)
13>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(85,5): error :    at Microsoft.CodeAnalysis.CSharp.CommandLine.Program.Main(String[] args)

The workaround that I can have is that I stop using global usings. Eg: I remove the GlobalUsings.cs file that contains the following two lines of code

extern alias Data;
global using Data::XXX.YYY.Data;

And the problem goes away.

But the problem is that when I try to create a scale down project, I can't reproduce the error. I thought it's a simple case of using extern alias with global using, but I was wrong.

I am pretty sure that this is a bug from Rosyln compiler. Any idea how to reproduce an actionable bug report?

jjonescz commented 3 weeks ago

Instead of creating a minimal example, you could create a complog and send it to us for investigation. Note that it will contain all inputs, but you can send it privately via VS feedback (just link the ticket here then).

WindingWinter commented 2 weeks ago

@jjonescz . here's the VS feedback link

AlekseyTs commented 1 week ago

https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2225493

AlekseyTs commented 1 week ago
        [WorkItem("https://github.com/dotnet/roslyn/issues/74872")]
        [Fact]
        public void ExternAliases6()
        {
            string sourceA =
@"
namespace N
{
    public class A { }
}
";
            var comp = CreateCompilation(sourceA, assemblyName: "A1");
            var refA = comp.EmitToImageReference(aliases: ImmutableArray.Create("A2"));

            string sourceB =
@"
class B
{
    static void F(A x) { }
}
";
            string sourceC =
@"
extern alias A2;
global using A2::N;
";
            comp = CreateCompilation([sourceB, sourceC], references: new[] { refA }, options: TestOptions.DebugDll);
            comp.VerifyDiagnostics();
            comp.VerifyPdb(
@"
<symbols>
  <files>
    <file id=""1"" name="""" language=""C#"" />
  </files>
  <methods>
    <method containingType=""B"" name=""F"" parameterNames=""x"">
      <customDebugInfo>
        <using>
          <namespace usingCount=""1"" />
        </using>
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""4"" startColumn=""24"" endLine=""4"" endColumn=""25"" document=""1"" />
        <entry offset=""0x1"" startLine=""4"" startColumn=""26"" endLine=""4"" endColumn=""27"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0x2"">
        <namespace qualifier=""A2"" name=""N"" />
        <externinfo alias=""A2"" assembly=""A1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"" />
      </scope>
    </method>
  </methods>
</symbols>
");
        }

        [WorkItem("https://github.com/dotnet/roslyn/issues/74872")]
        [Fact]
        public void ExternAliases7()
        {
            string sourceA =
@"
namespace N
{
    public class A { }
}
";
            var comp = CreateCompilation(sourceA, assemblyName: "A1");
            var refA = comp.EmitToImageReference(aliases: ImmutableArray.Create("A2"));

            string sourceB =
@"
class B
{
    static void F(N2.A x) { }
}
";
            string sourceC =
@"
extern alias A2;
global using N2 = A2::N;
";
            comp = CreateCompilation([sourceB, sourceC], references: new[] { refA }, options: TestOptions.DebugDll);
            comp.VerifyDiagnostics();
            comp.VerifyPdb(
@"
<symbols>
  <files>
    <file id=""1"" name="""" language=""C#"" />
  </files>
  <methods>
    <method containingType=""B"" name=""F"" parameterNames=""x"">
      <customDebugInfo>
        <using>
          <namespace usingCount=""1"" />
        </using>
      </customDebugInfo>
      <sequencePoints>
        <entry offset=""0x0"" startLine=""4"" startColumn=""27"" endLine=""4"" endColumn=""28"" document=""1"" />
        <entry offset=""0x1"" startLine=""4"" startColumn=""29"" endLine=""4"" endColumn=""30"" document=""1"" />
      </sequencePoints>
      <scope startOffset=""0x0"" endOffset=""0x2"">
        <alias name=""N2"" qualifier=""A2"" target=""N"" kind=""namespace"" />
        <externinfo alias=""A2"" assembly=""A1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"" />
      </scope>
    </method>
  </methods>
</symbols>
");
        }
AlekseyTs commented 1 week ago

@tmat Could you please advise what import information should be emitted for the scenarios above? Note that PdbValidation.VerifyPdb helper doesn't like references to undefined aliases: "PDB0007: token 0x35000002: An extern alias was not defined for assembly reference 23000002". At the same time it feels like defining an alias used by a global using would be incorrect because it is not in "scope" within sourceB.

tmat commented 6 days ago

Interesting corner case. I need to dig deeper into the code that reports the error.