microsoft / win32metadata

Tooling to generate metadata for Win32 APIs in the Windows SDK.
Other
1.32k stars 113 forks source link

When finding a type def from a type ref, search all assemblies #1919

Closed dpaoliello closed 2 months ago

dpaoliello commented 2 months ago

We were seeing a crash in ClangSharpSourceToWinmd when we had an interface inheriting another interface from a different assembly:

3001>Unhandled exception: System.InvalidOperationException: Sequence contains no matching element
3001>   at System.Linq.ThrowHelper.ThrowNoMatchException()
3001>   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)
3001>   at MetadataUtils.WinmdUtils.InternalGetImplementedMethodCount(TypeDefinition typeDef)
3001>   at MetadataUtils.WinmdUtils.GetTypes()+MoveNext()
3001>   at ClangSharpSourceToWinmd.ClangSharpSourceWinmdGenerator.<PopulateMetadataBuilder>g__GatherInterfaceTypes|60_1()
3001>   at ClangSharpSourceToWinmd.ClangSharpSourceWinmdGenerator.PopulateMetadataBuilder()
3001>   at ClangSharpSourceToWinmd.ClangSharpSourceWinmdGenerator.GenerateWindmdForCompilation(ClangSharpSourceCompilation compilation, Dictionary`2 typeImports, HashSet`1 reducePointerLevels, HashSet`1 forceGuidConsts, Version version, String outputFileName)
3001>   at ClangSharpSourceToWinmd.Program.Run(InvocationContext context)

ClangSharpSourceToWinmd was only searching for matching named types within the current assembly when it encountered a TypeReference, however TypeReference is specifically used when referencing a type from a foreign assembly.

This fix for this is to provide the complete set of metadata readers to GetTypes so that it can search through all of them to find the type definition for a given TypeReference

mikebattista commented 2 months ago

Thanks for the fix.

mikebattista commented 2 months ago

There is a test failure here. Could you take a look?

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:05.42]     Windows.Win32.Tests.IntegrityTests.NoInvalidEmptyDelegates [FAIL]
  Failed Windows.Win32.Tests.IntegrityTests.NoInvalidEmptyDelegates [491 ms]
  Error Message:
   Assert.Equal() Failure
Expected: 0
Actual:   1
  Stack Trace:
     at Windows.Win32.Tests.IntegrityTests.ExecWinmdUtils(String args) in D:\a\1\s\tests\Windows.Win32.Tests\IntegrityTests.cs:line 85
   at Windows.Win32.Tests.IntegrityTests.NoInvalidEmptyDelegates() in D:\a\1\s\tests\Windows.Win32.Tests\IntegrityTests.cs:line 45
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
  Standard Output Messages:
 Calling: dotnet "D:\a\1\s\bin\Release\net8.0\winmdutils.dll" showEmptyDelegates --winmd "D:\a\1\s\bin\windows.win32.winmd" "@D:\a\1\s\bin\Release\net8.0\assets\emptyDelegatesAllowList.rsp"
 Unhandled exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Could not find definition for 'Windows.Win32.System.Com.IUnknown'   at MetadataUtils.WinmdUtils.GetDefinitionFromReference(TypeReference typeReference, List`1 allWinmds) in D:\a\1\s\sources\MetadataUtils\WinmdUtils.cs:line 260   at MetadataUtils.WinmdUtils.InternalGetImplementedMethodCount(TypeDefinition typeDef, List`1 allWinmds) in D:\a\1\s\sources\MetadataUtils\WinmdUtils.cs:line 223   at MetadataUtils.WinmdUtils.GetTypes(List`1 allWinmds)+MoveNext() in D:\a\1\s\sources\MetadataUtils\WinmdUtils.cs:line 188   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()   at WinmdUtilsProgram.Program.ShowEmptyDelegates(FileInfo winmd, String[] allowItem, IConsole console) in D:\a\1\s\sources\WinmdUtils\Program.cs:line 698   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)   --- End of inner exception stack trace ---   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)   at System.Delegate.DynamicInvokeImpl(Object[] args)   at System.CommandLine.Invocation.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)   at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()--- End of stack trace from previous location ---   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass23_0.<<UseParseErrorReporting>b__0>d.MoveNext()--- End of stack trace from previous location ---   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseHelp>b__0>d.MoveNext()--- End of stack trace from previous location ---   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass27_0.<<UseVersionOption>b__1>d.MoveNext()--- End of stack trace from previous location ---   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass25_0.<<UseTypoCorrections>b__0>d.MoveNext()--- End of stack trace from previous location ---   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__24_0>d.MoveNext()--- End of stack trace from previous location ---   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseParseDirective>b__0>d.MoveNext()--- End of stack trace from previous location ---   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass11_0.<<UseDebugDirective>b__0>d.MoveNext()--- End of stack trace from previous location ---   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__10_0>d.MoveNext()--- End of stack trace from previous location ---   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass14_0.<<UseExceptionHandler>b__0>d.MoveNext()
dpaoliello commented 2 months ago

There is a test failure here. Could you take a look?

I have a fix: https://github.com/microsoft/win32metadata/pull/1921