Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redo IL Verification #90418

Merged
merged 1 commit into from
Aug 18, 2023

Conversation

mrvoorhe
Copy link
Contributor

@mrvoorhe mrvoorhe commented Aug 11, 2023

  • Now checks all assemblies in the output directory rather than just test.exe

  • Once again respects the the ability to skip verifying a single assembly via [SkipIlVerify("foo.dll")]

  • Now loads core libraries from the output directory (if they exist) instead of from the runtime install dir.

  • ALC logic was removed. I do not understand what value this provided.

  • The class libraries lead to a lot of errors. Rather than having to filter out a large number of errors, I added diff'ing. ILVerify will check the input assembly and remove any errors that existed in the input assembly. This makes verifying class libraries viable. Without it, you'd have to use [SkipIlverify] on every core link test or filter out a lot of VerifierError values.

  • Moved IL verification back to InitialChecking where PeVerifier was

  • Add a test to verify that il verification is mostly working. It doesn't give complete coverage over every behavior, but it's better than nothing.

  • SkipPeVerify renamed to SkipIlVerify

  • SkipPeVerifyForToolchian was removed. There is only 1 tool now.

  • Removed PeVerifier.

  • Remove many [SkipIlVerify] attributes. Diffing means they are no longer needed

  • ValidateTypeRefsHaveValidAssemblyRefs now runs regardless of whether or not the IL is verified. It wasn't clear to me why this logic would only be useful when il was verified.

  • Change UninitializedLocals to use ExpectIlFailure. This test seems to expect invalid il. Might as well assert that rather than skip ilverify entirely.

  • Remove the logic that disables ilverify when a test uses the unsafe argument. Diffing makes this obsolete.

  • Cut down on the number of VerifierError values that are filtered out. Diffing removes the need to filter them out.

  • IL Verification errors have been greatly improved.

  • will now output all IL errors in the failure message rather than just the first invalid IL.

  • Type and Method names are now displayed in the error message. I didn't do an exhaustive implementation, SRM is so tedious to use, but it's better than not having it

  • Tokens and Offsets are formatted nicely

  • Extension points opened up for Unity.

  • We need to supply different search directories.

  • We need to search for .winmd files since we support windows runtime.

  • In general I opened some things up in case we need to call them

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Aug 11, 2023
@mrvoorhe mrvoorhe changed the title Redo ILVerfificaiton Redo IL Verification Aug 11, 2023
@ghost ghost added linkable-framework Issues associated with delivering a linker friendly framework community-contribution Indicates that the PR has been added by a community member labels Aug 11, 2023
@ghost
Copy link

ghost commented Aug 11, 2023

Tagging subscribers to 'linkable-framework': @eerhardt, @vitek-karas, @LakshanF, @sbomer, @joperezr, @marek-safar
See info in area-owners.md if you want to be subscribed.

Issue Details
  • Now checks all assemblies in the output directory rather than just test.exe

  • Once again respects the the ability to skip verifying a single assembly via [SkipIlVerify("foo.dll")]

  • Now loads core libraries from the output directory (if they exist) instead of from the runtime install dir.

  • ALC logic was removed. I do not understand what value this provided.

  • The class libraries lead to a lot of errors. Rather than having to filter out a large number of errors, I added diff'ing. ILVerify will check the input assembly and remove any errors that existed in the input assembly. This makes verifying class libraries viable. Without it, you'd have to use [SkipIlverify] on every core link test or filter out a lot of VerifierError values.

  • Moved IL verification back to InitialChecking where PeVerifier was

  • Add a test to verify that il verification is mostly working. It doesn't give complete coverage over every behavior, but it's better than nothing.

  • SkipPeVerify renamed to SkipIlVerify

  • SkipPeVerifyForToolchian was removed. There is only 1 tool now.

  • Removed PeVerifier.

  • Remove many [SkipIlVerify] attributes. Diffing means they are no longer needed

  • ValidateTypeRefsHaveValidAssemblyRefs now runs regardless of whether or not the IL is verified. It wasn't clear to me why this logic would only be useful when il was verified.

  • Change UninitializedLocals to use ExpectIlFailure. This test seems to expect invalid il. Might as well assert that rather than skip ilverify entirely.

  • Remove the logic that disables ilverify when a test uses the unsafe argument. Diffing makes this obsolete.

  • IL Verification errors have been greatly improved. ** will now output all IL errors in the failure message rather than just the first invalid IL. ** Type and Method names are now displayed in the error message. I didn't do an exhaustive implementation, SRM is so tedious to use, but it's better than not having it ** Tokens and Offsets are formatted nicely

  • Extension points opened up for Unity. ** We need to supply different search directories. ** We need to search for .winmd files since we support windows runtime. ** In general I opened some things up in case we need to call them

Author: mrvoorhe
Assignees: -
Labels:

linkable-framework, needs-area-label

Milestone: -

@jkotas jkotas added the area-Tools-ILLink .NET linker development as well as trimming analyzers label Aug 11, 2023
@ghost
Copy link

ghost commented Aug 11, 2023

Tagging subscribers to this area: @agocke, @sbomer, @vitek-karas
See info in area-owners.md if you want to be subscribed.

Issue Details
  • Now checks all assemblies in the output directory rather than just test.exe

  • Once again respects the the ability to skip verifying a single assembly via [SkipIlVerify("foo.dll")]

  • Now loads core libraries from the output directory (if they exist) instead of from the runtime install dir.

  • ALC logic was removed. I do not understand what value this provided.

  • The class libraries lead to a lot of errors. Rather than having to filter out a large number of errors, I added diff'ing. ILVerify will check the input assembly and remove any errors that existed in the input assembly. This makes verifying class libraries viable. Without it, you'd have to use [SkipIlverify] on every core link test or filter out a lot of VerifierError values.

  • Moved IL verification back to InitialChecking where PeVerifier was

  • Add a test to verify that il verification is mostly working. It doesn't give complete coverage over every behavior, but it's better than nothing.

  • SkipPeVerify renamed to SkipIlVerify

  • SkipPeVerifyForToolchian was removed. There is only 1 tool now.

  • Removed PeVerifier.

  • Remove many [SkipIlVerify] attributes. Diffing means they are no longer needed

  • ValidateTypeRefsHaveValidAssemblyRefs now runs regardless of whether or not the IL is verified. It wasn't clear to me why this logic would only be useful when il was verified.

  • Change UninitializedLocals to use ExpectIlFailure. This test seems to expect invalid il. Might as well assert that rather than skip ilverify entirely.

  • Remove the logic that disables ilverify when a test uses the unsafe argument. Diffing makes this obsolete.

  • IL Verification errors have been greatly improved.

  • will now output all IL errors in the failure message rather than just the first invalid IL.

  • Type and Method names are now displayed in the error message. I didn't do an exhaustive implementation, SRM is so tedious to use, but it's better than not having it

  • Tokens and Offsets are formatted nicely

  • Extension points opened up for Unity.

  • We need to supply different search directories.

  • We need to search for .winmd files since we support windows runtime.

  • In general I opened some things up in case we need to call them

Author: mrvoorhe
Assignees: -
Labels:

linkable-framework, community-contribution, area-Tools-ILLink, needs-area-label

Milestone: -

@jkotas jkotas removed the linkable-framework Issues associated with delivering a linker friendly framework label Aug 11, 2023
@ghost ghost added the linkable-framework Issues associated with delivering a linker friendly framework label Aug 11, 2023
@jkoritzinsky jkoritzinsky removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners linkable-framework Issues associated with delivering a linker friendly framework labels Aug 11, 2023
@ghost ghost added the linkable-framework Issues associated with delivering a linker friendly framework label Aug 11, 2023
@ghost
Copy link

ghost commented Aug 11, 2023

Tagging subscribers to 'linkable-framework': @eerhardt, @vitek-karas, @LakshanF, @sbomer, @joperezr, @marek-safar
See info in area-owners.md if you want to be subscribed.

Issue Details
  • Now checks all assemblies in the output directory rather than just test.exe

  • Once again respects the the ability to skip verifying a single assembly via [SkipIlVerify("foo.dll")]

  • Now loads core libraries from the output directory (if they exist) instead of from the runtime install dir.

  • ALC logic was removed. I do not understand what value this provided.

  • The class libraries lead to a lot of errors. Rather than having to filter out a large number of errors, I added diff'ing. ILVerify will check the input assembly and remove any errors that existed in the input assembly. This makes verifying class libraries viable. Without it, you'd have to use [SkipIlverify] on every core link test or filter out a lot of VerifierError values.

  • Moved IL verification back to InitialChecking where PeVerifier was

  • Add a test to verify that il verification is mostly working. It doesn't give complete coverage over every behavior, but it's better than nothing.

  • SkipPeVerify renamed to SkipIlVerify

  • SkipPeVerifyForToolchian was removed. There is only 1 tool now.

  • Removed PeVerifier.

  • Remove many [SkipIlVerify] attributes. Diffing means they are no longer needed

  • ValidateTypeRefsHaveValidAssemblyRefs now runs regardless of whether or not the IL is verified. It wasn't clear to me why this logic would only be useful when il was verified.

  • Change UninitializedLocals to use ExpectIlFailure. This test seems to expect invalid il. Might as well assert that rather than skip ilverify entirely.

  • Remove the logic that disables ilverify when a test uses the unsafe argument. Diffing makes this obsolete.

  • Cut down on the number of VerifierError values that are filtered out. Diffing removes the need to filter them out.

  • IL Verification errors have been greatly improved.

  • will now output all IL errors in the failure message rather than just the first invalid IL.

  • Type and Method names are now displayed in the error message. I didn't do an exhaustive implementation, SRM is so tedious to use, but it's better than not having it

  • Tokens and Offsets are formatted nicely

  • Extension points opened up for Unity.

  • We need to supply different search directories.

  • We need to search for .winmd files since we support windows runtime.

  • In general I opened some things up in case we need to call them

Author: mrvoorhe
Assignees: -
Labels:

linkable-framework, community-contribution, area-Tools-ILLink

Milestone: -

@mrvoorhe
Copy link
Contributor Author

mrvoorhe commented Aug 14, 2023

Locally I can reproduce the test failures on main. I also don't see how these failures could be related to my changes. So I suspect the linker tests are broken on main.

I believe this PR is ready to go @marek-safar @vitek-karas

@vitek-karas
Copy link
Member

The failures are real now - I checked out this branch and rebased to main and it fails locally with:

Attributes.OnlyKeepUsed.NullableOnConstraints​9s 17ms
Error:
Internal.TypeSystem.TypeSystemException+TypeLoadException : Failed to load type 'System.String' from assembly 'System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'

Stack trace:
   at Internal.TypeSystem.ThrowHelper.ThrowTypeLoadException(ExceptionStringID id, String typeName, String assemblyName) in F:\dotnet\runtime\src\coreclr\tools\Common\TypeSystem\Common\ThrowHelper.cs:line 17
   at Internal.TypeSystem.ThrowHelper.ThrowTypeLoadException(String namespace, String name, ModuleDesc module) in F:\dotnet\runtime\src\coreclr\tools\Common\TypeSystem\Common\ThrowHelper.Common.cs:line 21
   at Internal.TypeSystem.ResolutionFailure.Throw() in F:\dotnet\runtime\src\coreclr\tools\Common\TypeSystem\Common\ResolutionFailure.cs:line 93
   at Internal.TypeSystem.Ecma.EcmaModule.GetType(String nameSpace, String name, NotFoundBehavior notFoundBehavior) in F:\dotnet\runtime\src\coreclr\tools\Common\TypeSystem\Ecma\EcmaModule.cs:line 369
   at Internal.TypeSystem.ModuleDesc.GetType(String nameSpace, String name, Boolean throwIfNotFound) in F:\dotnet\runtime\src\coreclr\tools\Common\TypeSystem\Common\ModuleDesc.cs:line 38
   at Internal.TypeSystem.MetadataTypeSystemContext.SetSystemModule(ModuleDesc systemModule) in F:\dotnet\runtime\src\coreclr\tools\Common\TypeSystem\Common\MetadataTypeSystemContext.cs:line 74
   at ILVerify.Verifier.SetSystemModuleName(AssemblyName name) in F:\dotnet\runtime\src\coreclr\tools\ILVerification\Verifier.cs:line 44
   at Mono.Linker.Tests.TestCasesRunner.ILVerification.ILVerifier..ctor(NPath[] searchDirectories, String systemModuleName) in F:\dotnet\runtime\src\tools\illink\test\Mono.Linker.Tests\TestCasesRunner\ILVerification\ILVerifier.cs:line 36
   at Mono.Linker.Tests.TestCasesRunner.ILVerification.ILChecker.CreateILVerifier(NPath directory) in F:\dotnet\runtime\src\tools\illink\test\Mono.Linker.Tests\TestCasesRunner\ILVerification\ILChecker.cs:line 159
   at Mono.Linker.Tests.TestCasesRunner.ILVerification.ILChecker.Check(LinkedTestCaseResult linkResult, AssemblyDefinition original) in F:\dotnet\runtime\src\tools\illink\test\Mono.Linker.Tests\TestCasesRunner\ILVerification\ILChecker.cs:line 25
   at Mono.Linker.Tests.TestCasesRunner.ResultChecker.InitialChecking(LinkedTestCaseResult linkResult, AssemblyDefinition original, AssemblyDefinition linked) in F:\dotnet\runtime\src\tools\illink\test\Mono.Linker.Tests\TestCasesRunner\ResultChecker.cs:line 282
   at Mono.Linker.Tests.TestCasesRunner.ResultChecker.Check(LinkedTestCaseResult linkResult) in F:\dotnet\runtime\src\tools\illink\test\Mono.Linker.Tests\TestCasesRunner\ResultChecker.cs:line 96
   at Mono.Linker.Tests.TestCases.All.Run(TestCase testCase) in F:\dotnet\runtime\src\tools\illink\test\Mono.Linker.Tests\TestCases\TestSuites.cs:line 299
   at Mono.Linker.Tests.TestCases.All.AttributesTests(TestCase testCase) in F:\dotnet\runtime\src\tools\illink\test\Mono.Linker.Tests\TestCases\TestSuites.cs:line 34
   at InvokeStub_All.AttributesTests(Object, Span`1)
   at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)

@vitek-karas
Copy link
Member

Note that without rebase to main everything passes - so it has to be some interaction with very recent changes.

@mrvoorhe
Copy link
Contributor Author

Note that without rebase to main everything passes - so it has to be some interaction with very recent changes.

Thanks for checking on that. I did not think to recheck the errors after the rebase. I will take a look

@mrvoorhe
Copy link
Contributor Author

mrvoorhe commented Aug 16, 2023

@vitek-karas NullableOnConstraints should be fixed now. It has [SetupLinkerTrimMode ("link")] which means the ILVerifier is going to load the trimmed core lib. System.String is in fact gone which IlVerifier is not happy about. Adding [IgnoreDescriptors (false)] ensures the basis survive.

@mrvoorhe
Copy link
Contributor Author

@vitek-karas I'm not sure what to make of CI. Are the failures related to my changes?

@vitek-karas
Copy link
Member

The non-wasm failures were already fixed by #90699 - I don't know why rerunning doesn't bet that. We would have to restart the whole CI probably - not worth it.

The wasm failures are definitely unrelated - they occur in other PRs as well.

@mrvoorhe
Copy link
Contributor Author

@vitek-karas Great. This PR is ready to go then.

Copy link
Member

@vitek-karas vitek-karas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks good - it's a lot of new code... but if it works and effectively enabled IL Verification everywhere (or almost), that's a big win.

@sbomer, could you please also take a quick look?

The one thing we could improve (eventually) is to avoid having to implement the TypeSystem->String conversions - we have that in the ILC type system.


public static class Extensions
{
public static string GetMethodSignature (this MethodDefinitionHandle handler, MetadataReader metadataReader)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for writing this - eventually we might migrate this to use the internal type system from the ILCompiler (it's in the same repo, so taking a project reference is very cheap) which has full implementation of this. But that's for some other time.

if (!DisableILDiffing (linkResult, original)) {
var inputResults = inputVerifier.VerifyByName (file.FileNameWithoutExtension);

outputResults = Diff (outputResults, inputResults);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice idea and I like it. My only hesitation is perf - if it makes tests a lot slower that would be something to think about... Did you try to get at least some rough understanding how much it costs to run the verifying twice effectively?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a high level check of the performance impact. Running the same command CI does to run tests I got
Before

Time Elapsed 00:06:15

And with this PR

Time Elapsed 00:06:31

So it's essentially insignificant.

* Now checks all assemblies in the output directory rather than just `test.exe`
* Once again respects the the ability to skip verifying a single assembly via `[SkipIlVerify("foo.dll")]`
* Now loads core libraries from the output directory (if they exist) instead of from the runtime install dir.
* ALC logic was removed.  I do not understand what value this provided.
* The class libraries lead to a lot of errors.  Rather than having to filter out a large number of errors, I added diff'ing.  ILVerify will check the input assembly and remove any errors that existed in the input assembly.  This makes verifying class libraries viable.  Without it, you'd have to use `[SkipIlverify]` on every core link test or filter out a lot of `VerifierError` values.
* Moved IL verification back to `InitialChecking` where `PeVerifier` was
* Add a test to verify that il verification is mostly working.  It doesn't give complete coverage over every behavior, but it's better than nothing.
* `SkipPeVerify` renamed to `SkipIlVerify`
* `SkipPeVerifyForToolchian` was removed.  There is only 1 tool now.
* Removed `PeVerifier`.
* Remove many [SkipIlVerify] attributes.  Diffing means they are no longer needed
* `ValidateTypeRefsHaveValidAssemblyRefs` now runs regardless of whether or not the IL is verified.  It wasn't clear to me why this logic would only be useful when il was verified.
* Change `UninitializedLocals` to use `ExpectIlFailure`.  This test seems to expect invalid il.  Might as well assert that rather than skip ilverify entirely.
* Remove the logic that disables ilverify when a test uses the unsafe argument.  Diffing makes this obsolete.

* IL Verification errors have been greatly improved.
** will now output all IL errors in the failure message rather than just the first invalid IL.
** Type and Method names are now displayed in the error message.  I didn't do an exhaustive implementation, SRM is so tedious to use, but it's better than not having it
** Tokens and Offsets are formatted nicely

* Extension points opened up for Unity.
** We need to supply different search directories.
** We need to search for `.winmd` files since we support windows runtime.
** In general I opened some things up in case we need to call them
return true;
}

protected string[] PossibleAssemblyExtensions => new[] { ".dll", ".exe", ".winmd" };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added .winmd here as well.

@vitek-karas
Copy link
Member

The test failures are either known or unrelated.

@vitek-karas vitek-karas merged commit 6229f5f into dotnet:main Aug 18, 2023
127 of 132 checks passed
@ghost ghost locked as resolved and limited conversation to collaborators Sep 17, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Tools-ILLink .NET linker development as well as trimming analyzers community-contribution Indicates that the PR has been added by a community member linkable-framework Issues associated with delivering a linker friendly framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants