-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Enable single file analyzer in the runtime #50894
Conversation
Resolve warnings on single file dangerous patterns by: - Annotating with RequiresAssemblyFiles - Suppressing the warning - Fixing the issue on code - Opening an issue to track fix and either annotate/suppress the current behavior
Tagging subscribers to this area: @agocke, @vitek-karas, @VSadov Issue DetailsDelete ruleset for single file related warnings IL3000 and IL3001
|
Sending to CI to catch possible misses caused by:
Also, APICompat didn't fail on my computer although I added several Custom Attributes so I'm letting the CI run directly on the changes |
src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextLoader.cs
Outdated
Show resolved
Hide resolved
@@ -74,6 +75,7 @@ public DependencyContext Merge(DependencyContext other) | |||
); | |||
} | |||
|
|||
[RequiresAssemblyFiles(Message = "Calls GetDepsJsonPath")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be propagated to the public API (Default property) - I would expect the analyzer to generate some warnings around this. If not it's a bug in the analyzer which we should fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried a little bit today to debug this, seems like a more complicated scenario than I expected. The analyzer is only able to see System.Lazy.Value.get but I have not found a way to connect it with the function is calling (LoadDefault). Also, I tested a similar scenario to see how does the linker behaves using RequiresUnreferencedCode and I found that they both have the same testing hole and don't produce the warning.
public static void Main ()
{
TestCallsLazyInitializer ();
}
public static Lazy<RequiresUnreferencedCodeCapability> lazyRUC = new Lazy<RequiresUnreferencedCodeCapability> (InitRUC);
[RequiresUnreferencedCode ("Message for --RequiresUnreferencedCodeWithLazyInit--")]
public static RequiresUnreferencedCodeCapability InitRUC ()
{
RequiresUnreferencedCodeCapability objectRUC = new RequiresUnreferencedCodeCapability ();
return objectRUC;
}
[ExpectedWarning ("IL2026", "--RequiresUnreferencedCodeWithLazyInit--")]
public static void TestCallsLazyInitializer ()
{
RequiresUnreferencedCodeCapability objectRUC = lazyRUC.Value;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks like dotnet/linker#1912 and related.
We should get a warning in the static constructor, when the Lazy instance is getting constructed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With dotnet/linker#1964 now the Lazy call showed a warning, but since it warns on an implicit static constructor (I cannot annotate the static constructor unless I implement it) and then gets assigned to a field (which is a target that RequiresAssembly files don't support) I couldn't mark it with RequiresAssemblyFiles. I ended up refactoring the code and not make use of the Lazy call.
Add additional wasm pattern
…ollo/runtime into SingleFileAnalyzerOnRuntime
src/libraries/Microsoft.NETCore.Platforms/src/AssemblyResolver.cs
Outdated
Show resolved
Hide resolved
…ileAnalyzerOnRuntime
…ileAnalyzerOnRuntime
…ileAnalyzerOnRuntime Change pragmas for UnconditionalSuppressMessage Suppress wasm error and open an issue about it
NetCoreAppCurrent
System.Reflection.MetadataLoadContext
@eerhardt What is your take on some of the cases where we suppress warnings and file issues on them. I'm not a fan since those are real problems we're hiding. On the other hand propagating these warnings feels like it would affect too large of an API surface. |
src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextLoader.cs
Outdated
Show resolved
Hide resolved
src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextLoader.cs
Outdated
Show resolved
Hide resolved
src/libraries/Microsoft.NETCore.Platforms/src/AssemblyResolver.cs
Outdated
Show resolved
Hide resolved
....ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs
Outdated
Show resolved
Hide resolved
[UnconditionalSuppressMessage("Single file", "IL3000: Avoid accessing Assembly file path when publishing as a single file", | ||
Justification = "Suppressing the warning until gets fixed, see https://github.com/dotnet/runtime/issues/50821")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would happen if we didn't suppress this - how much would it spread (propagating the attribute to affected public APIs).
The functionality will not work in single-file - so silencing it until it gets fixed is wrong. The warnings are there for this specific reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding [RequiresAssemblyFiles] in this function doesn't propagate to other places. I think is a limitation in the analyzer, because the attribute is on an override, but the methods call a virtual function in LicenseContext.cs
If propagated to the callers, then GetCurrentContextInfo uses LicenseUsageMode.Designtime and it's called by COM so it doesn't propagate more.
The other caller is GetLicense which uses LicenseUsageMode.Runtime, for me is uncertain if that will result in calling the override in DesigntimeLicenseContext. But that method has about 10 different call sites that would need to be annotated most of them in System.ComponentModel.LicenseManger.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and it's called by COM so it doesn't propagate more.
Well - it doesn't propagate in the analyzer - but functionally it does propagate - so this is the killer argument for me. It would basically mean we should potentially annotate the entire COM this way.
Regarding the analyzer: We should add a similar check to what RequiresUnreferencedCode has (at least in the linker) - that is, all methods in a virtual override chain should have the same annotations. So if an override has the attribute, the base method should have it as well, and vice-versa. If this is not the case, please file a bug for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened dotnet/linker#1985 to track work for virtual calls in the analyzers
src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs
Outdated
Show resolved
Hide resolved
src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextLoader.cs
Outdated
Show resolved
Hide resolved
Since this PR has been passing a couple of times the only question that I have is why API compat doesn't warn on these new attributes, I didn't add any code to the ref assemblies shouldn't this suppose to break the build? |
…ollo/runtime into SingleFileAnalyzerOnRuntime
src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj
Outdated
Show resolved
Hide resolved
Yes this should be failing. Let me try and reproduce this locally and debug it to see what's going on. |
It seems like the APICompat issue was a regression I introduced when adding support to diff attributes on type parameters and method parameters. I put up a fix for this regression: dotnet/arcade#7376 |
…ileAnalyzerOnRuntime
…ileAnalyzerOnRuntime
…ileAnalyzerOnRuntime
analysis is not made by a GlobalAnalysis tool and there is no reason to have extra IL with the attribute Add ref assembly attributes Fix a single file incompatible pattern issue found in System.IO.IsolatedStorage
I changed the attributes from UnconditionalSuppressMessage to SuppressMessage since there is no reason at this moment to have the extra IL, since the analysis is being conducted via analyzers is not necessary. |
For the System.IO.IsolatedStorage I will need review and guidance on how to test that my changes don't change the way the app behaves for both single-file and non single-file |
This means NativeAOT will not be able to implement the single file warnings since the attributes need to be in IL as per #50894 (comment). SuppressMessage is no different from |
Can we rely on the analyzers instead?
For now we've been thinking about this as very similar to all the other analyzers - most specifically the platform analyzer, which is basically identical ("viral" as well). And the outcome was that unless we can solve this for all of the analyzers, it makes little sense to try to solve it for one specific one alone. (Note: Trimming is different in that it needs to run on IL and needs to be global) I'm a bit split on this one - it would help in NativeAOT with a more predictable experience... but to be fully predictable we would also have to support global analysis for things like platform compatibility and so on... |
I look at the single file analyzer as a stopgap until we have a better spot for this. I'll just quote from #50894 (comment). "From my past experience, every time someone hit an issue with APIs like Assembly.Location and couldn't figure it out, it was in a third party NuGet. If they hit it in their own code, they could usually just debug into it. E.g. the CoreRT repo is full of them; here's one: dotnet/corert#7756." Basically you get a lot more payoff from the analyzer warning if it warns you about code that is not yours. The null from Assembly.Location results in so many ArgumentNullException that I always start my investigations with that - and as someone fluent with ILSpy I can usually debug it in 2 minutes. Here's another grpc/grpc#18188 loooong thread with a lot of angry/frustrated people. It would be much better if we could just issue a warning that the NuGet package they're using is not compatible with single file deployments than trying to get a message across a busy thread with a lot of frustrated people and package maintainers uninterested in fixing the issue of their users. |
(The interesting part of the GRPC thread starts at grpc/grpc#18188 (comment) where what was a .NET Native bug that we fixed made forward progress to hit a GRPC bug) |
OK - makes sense. I still hate the fact that we're solving these things as one-offs (platform analyzer has this problem as well, without any solution) - also this will only work in native AOT - JITed single-file will not show any warning and break anyway. @tlakollo Sorry for the back and forth on this - can you please revert back to using |
…ileAnalyzerOnRuntime Change SuppressMessage for UnconditionalSuppressMessage to support AOT scenarios
I was able to test that executing in
After the code change the 267 test passed, although I'm not 100% sure that there is a test that exercises the particular scenario, I will update this PR with a change in runtime/src/libraries/tests.proj to enable running System.IO.IsolatedStorage tests as a single file. |
…ileAnalyzerOnRuntime Enable single file testing in System.IO.IsolatedStorage
Delete ruleset for single file related warnings IL3000 and IL3001
Add ILLinkRoslyn analyzer and EnableSingleFileAnalyzer flag
Resolve warnings on single file dangerous patterns by: