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

AppDomain configuration is serialized without using BinFmt #9320

Merged
merged 25 commits into from
Oct 18, 2023

Conversation

MichalPavlik
Copy link
Member

@MichalPavlik MichalPavlik commented Oct 11, 2023

Fixes #8922

Context

MSBuild uses binary formatter for AppDomainSetup serialization. We can transfer only configuration bytes.

Changes Made

Byte array representing the configuration is used instead of serialization of the AppDomainSetup type.

Testing

New unit tests are passing.

Notes

The change is behind a 17.10 changewave and IsBinaryFormatterSerializationAllowed trait.

@MichalPavlik
Copy link
Member Author

I guess this change should be reversable by env variable/change wave...

Copy link
Member

@JanKrivanek JanKrivanek left a comment

Choose a reason for hiding this comment

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

Looks good.

Do we have any existing tests executing this code path?

@JanKrivanek
Copy link
Member

I guess this change should be reversable by env variable/change wave...

Let's put it behind 17_10 ChangeWave introduced by #9318

Copy link
Member

@ladipro ladipro left a comment

Choose a reason for hiding this comment

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

The documentation says that GetConfigurationBytes() returns null if SetConfigurationBytes() has not been called. So it doesn't look like it's a replacement for serialization, unfortunately.

https://dotnetfiddle.net/Zi96aB

@JanKrivanek
Copy link
Member

The documentation says that GetConfigurationBytes() returns null if SetConfigurationBytes() has not been called. So it doesn't look like it's a replacement for serialization, unfortunately.

https://dotnetfiddle.net/Zi96aB

@MichalPavlik - can you look into whether there can be any viable serialization alternative? Alternatively what are all the codepaths that leverage the AppDomainSetup and what feature(s) would be affected (and how) by the lack of transfering of this

@JanKrivanek
Copy link
Member

JanKrivanek commented Oct 12, 2023

The documentation says that GetConfigurationBytes() returns null if SetConfigurationBytes() has not been called. So it doesn't look like it's a replacement for serialization, unfortunately.

https://dotnetfiddle.net/Zi96aB

@ladipro - I'll need to look once again once I have some free cycles (or @MichalPavlik can look in the meantime) - but IIRC from my past (though a very quick and possibly errorneous) investigation - the only place where transfered AppDomainSetup was actually used is this:

// Make sure we copy the appdomain configuration and send it to the appdomain we create so that if the creator of the current appdomain
// has done the binding redirection in code, that we will get those settings as well.
AppDomainSetup appDomainInfo = new AppDomainSetup();
// Get the current app domain setup settings
byte[] currentAppdomainBytes = appDomainSetup.GetConfigurationBytes();
// Apply the appdomain settings to the new appdomain before creating it
appDomainInfo.SetConfigurationBytes(currentAppdomainBytes);

where it uses just the Get/Set ConmfigurationBytes. If that's really the only usage - then serializing the config bytes upfront (whether they have been set or not) should be OK, correct? The other question is if that preexisting code is correct - but we have no complains about the functionality currently.

@ladipro
Copy link
Member

ladipro commented Oct 12, 2023

@JanKrivanek I believe that the ultimate source of appDomainSetup in the code you linked is here:

, AppDomain.CurrentDomain.SetupInformation

The Get/SetConfigurationBytes calls are done for completeness but we definitely rely on the rest as well.

To hit the relevant code path, build the following project with MSBUILDNOINPROCNODE=1:

<Project>
  <Target Name='Build'>
    <RegisterAssembly Assemblies="nonexistent.dll" />
  </Target>
</Project>

With the changes in the PR is fails with

error MSB4061: The "RegisterAssembly" task could not be instantiated from "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". Object reference not set to an instance of an object.

@ladipro
Copy link
Member

ladipro commented Oct 12, 2023

Needless to say, we should add the missing test coverage as part of this work.

@JanKrivanek
Copy link
Member

100% agree on the need to have the associated codepaths covered by the tests - @MichalPavlik can you please ensure those are added? And then compare results prior and after change?

I'd like to see what code is consuming the remoted AppDomainSetup (to confirm there is any beyond the TaskLoader getting the configuration bytes) and ideally what specifically is it accessing. Then we should think about how to extract and transfer such additional state.

src/Shared/TaskHostConfiguration.cs Outdated Show resolved Hide resolved
src/Shared/TaskHostConfiguration.cs Outdated Show resolved Hide resolved
@ladipro
Copy link
Member

ladipro commented Oct 12, 2023

The Get/SetConfigurationBytes calls are done for completeness but we definitely rely on the rest as well.

I take this back, I couldn't find anything else consuming the AppDomainSetup as a whole. The build is failing because we don't always create the AppDomainSetup on the receiving side - the bug you just pointed out.

What do you think about refactoring the code a bit so that only the byte[] is passed around? This would help both readability (it's clearer what's actually used) and a tiny bit of perf (no need to create an instance of AppDomainSetup when the only thing it carries are the configuration bytes).

@JanKrivanek
Copy link
Member

What do you think about refactoring the code a bit so that only the byte[] is passed around? This would help both readability (it's clearer what's actually used) and a tiny bit of perf (no need to create an instance of AppDomainSetup when the only thing it carries are the configuration bytes).

Absolutely!

MichalPavlik and others added 13 commits October 17, 2023 10:42
RoslynTools.MSBuild 17.7.2 caused two CG alerts when doing signing validation. dotnet/arcade#14055 and its linked PRs have more context.
Fixes policheck:Error

Changes Made

Skip the non en-us locale resource files.
Skip the file that contains the specified entity names in the deprecated folder
Change country to country/region based on https://policheck.microsoft.com/Pages/TermInfo.aspx?LCID=9&TermID=79570

Testing
Test with MSBuild pipeline build https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=8509007&view=logs&j=7d9eef18-6720-5c1f-4d30-89d7b76728e9&t=c5a86041-9185-53e8-42a2-1cadc4486f0d&l=5251. There are no active results now.
* Mention unification in RAR found-conflicts message

Consider a message like

```
warning MSB3277: Found conflicts between different versions of "System.Runtime.InteropServices.RuntimeInformation" that could not be resolved.
    There was a conflict between "System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" and "System.Runtime.InteropServices.RuntimeInformation, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
    "System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" was chosen because it was primary and "System.Runtime.InteropServices.RuntimeInformation, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" was not.
    References which depend on "System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" [C:\VisualStudio\VS17PrevPublic\Common7\IDE\PublicAssemblies\System.Runtime.InteropServices.RuntimeInformation.dll].
        C:\VisualStudio\VS17PrevPublic\Common7\IDE\PublicAssemblies\System.Runtime.InteropServices.RuntimeInformation.dll
            Project file item includes which caused reference "C:\VisualStudio\VS17PrevPublic\Common7\IDE\PublicAssemblies\System.Runtime.InteropServices.RuntimeInformation.dll".
                System.Runtime.InteropServices.RuntimeInformation
    References which depend on "System.Runtime.InteropServices.RuntimeInformation, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" [].
        C:\Users\user\.nuget\packages\azure.core\1.25.0\lib\net461\Azure.Core.dll
            Project file item includes which caused reference "C:\Users\user\.nuget\packages\azure.core\1.25.0\lib\net461\Azure.Core.dll".
                C:\Users\user\.nuget\packages\azure.core\1.25.0\lib\net461\Azure.Core.dll
                C:\Users\user\.nuget\packages\azure.identity\1.8.0\lib\netstandard2.0\Azure.Identity.dll
                C:\Users\user\.nuget\packages\azure.security.keyvault.secrets\4.4.0\lib\netstandard2.0\Azure.Security.KeyVault.Secrets.dll
                C:\Users\user\.nuget\packages\nuget.services.keyvault\2.111.0\lib\net472\NuGet.Services.KeyVault.dll
                C:\Users\user\.nuget\packages\nuget.services.configuration\2.111.0\lib\net472\NuGet.Services.Configuration.dll
```

What the message _means_ is that the first reference is the winner, and
what was chosen there will require unification for all the other
assemblies listed in the second part of the message. But what it says is
that the list of assemblies in the second part of the message depend on
the second version, which is not necessarily true--in fact, that's the
list of  references that _can be unified_ to that version.

This isn't a full fix for #4757 but hopefully makes the message a bit
less misleading.

* Update tests

* fixup! Update tests
* Correct success

This is not yet a problem but only because neither /preprocess nor /targets are supported for solution files.

The root of the problem is if someone chooses to specify both /preprocess and /targets. If /preprocess fails but /targets succeeds, it currently will erroneously display success. This fixes that.

As I said, that scenario doesn't currently exist but only because /targets cannot succeed unless /preprocess succeeded, but that is not guaranteed going forward. Notably, if /preprocess is extended to support solution files before /targets is, this will become an issue.

* Make isTargets not run if !success

---------

Co-authored-by: Forgind <Forgind@users.noreply.github.com>
Fixes #7330
(plus one subtask of #8329)

Changes Made
Based on Add ability to create temp mapped drive for integration tests #8366 fixes to enable other Drive enumeration integration tests with a dummy folder in windows
Remove one test data https://github.com/dotnet/msbuild/blob/fecef0fdffe59ba8b0251701a23be48bbd552726/src/Build.OM.UnitTests/Instance/ProjectItemInstance_Tests.cs#L1010-L1012C45 since there is no warning when inlude is not null and exclude with enumerating wildcards. The related logical code is
msbuild/src/Build/Utilities/EngineFileUtilities.cs

Line 339 in fecef0f

 private static void LogDriveEnumerationWarningWithTargetLoggingContext(TargetLoggingContext targetLoggingContext, IElementLocation includeLocation, IElementLocation excludeLocation, bool excludeFileSpecIsEmpty, bool disableExcludeDriveEnumerationWarning, string fileSpec) 
. There is no condition satisfied.
Associate unix Enumeration Tests long time run with issue Unix drive enumeration imports not expanded? #8373
Preliminary design proposal for the Packages Sourcing feature
Fixes #8762

Context
Catch the exceptions when extensionsPathPropValue is null or importExpandedWithDefaultPath is empty.
In NET Framework, Path.* function also throws exceptions if the path contains invalid characters

Changes Made
Catch the exception.

Testing
FallbackImportWithInvalidProjectValue

Notes
.NET (Core) stuff is implied by ManagedDesktop now, and we require only
"some .NET Framework SDK", so no need to specify explicitly as one will
be delivered by ManagedDesktop.

We do still target .NET Framework 3.5, though . . .
…004.4 (#9314)

Microsoft.Net.Compilers.Toolset
 From Version 4.8.0-3.23501.1 -> To Version 4.8.0-3.23504.4

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
…ngTargetExceptions (#9253)

Fixes #9245

Context
The test was disabled to unblock PR CI.

Changes Made
Increased the relevant timeout.

Testing
The test is reliably passing now.

Notes
This turned out to be an issue with the sleep command we use on Windows. In some cases PowerShell can take a super long time to start. I have been able to reproduce locally by enabling Fusion logging. Thread times of the powershell process:

image

We spend almost 10 seconds just loading assemblies, so the timeout of 10 seconds for the entire build was not enough.

I don't have a full understanding of the mechanism that slows down PowerShell this much. At this point I'm happy we were able to confirm it's not a product issue, although I'm wondering if there is a better and more light-weight sleep command we could use on Windows instead (e.g. ping 127.0.0.1 -n <seconds>). Reviewers please opine.

EDIT: In my trace, file system operations block extensively with wdfilter.sys on the stack, so the likely explanation for the issue appearing all of a sudden is a Defender update.
Context
The ExcludeFromStyleCop is not effective anymore. Even if it was, it's not clear why we would want to exclude so many files from style checks.

Changes Made
Deleted all occurrences of <ExcludeFromStyleCop>true</ExcludeFromStyleCop> from project files.

Testing
Build (CLI and VS).
Added IDE0305 to `.editorconfig` as a suggestion.
AR-May and others added 6 commits October 17, 2023 12:48
…9309)

Context
We need to add an extra job to .exp-insertions.yml pipeline for creating experimental Framework MSBuild.

Changes Made
Pipeline refactored, a job added
Fixed bug in deploy script code path for Framework MSBuild
Testing
Manual run of the pipeline
…: Build ID 8527872 (#9316)

* Localized file check-in by OneLocBuild Task: Build definition ID 9434: Build ID 8509770

* Localized file check-in by OneLocBuild Task: Build definition ID 9434: Build ID 8514818
…010.8 (#9333)

Microsoft.Net.Compilers.Toolset
 From Version 4.8.0-3.23504.4 -> To Version 4.8.0-3.23510.8

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Context
The sole purpose of introducing the type seems to have been silencing a legacy code analyzer rule. The rule does not exist anymore / has not been brought over to Roslyn (dotnet/roslyn-analyzers#722) and it's now hurting performance, if anything. Types like HashSet<int> are part of the mscorlib native image and it's wasteful to duplicate the code in our binaries. The rest is handled by IBC/OptProf.

Changes Made
Deleted NGen and its uses.

Testing
Experimental insertion to confirm no regressions.
src/Shared/TaskHostConfiguration.cs Outdated Show resolved Hide resolved
src/Build/BackEnd/Node/NodeConfiguration.cs Outdated Show resolved Hide resolved
@ladipro ladipro self-requested a review October 17, 2023 11:21
src/Build/BackEnd/Node/NodeConfiguration.cs Outdated Show resolved Hide resolved
src/Shared/TaskHostConfiguration.cs Outdated Show resolved Hide resolved
src/Shared/TaskHostConfiguration.cs Show resolved Hide resolved
Copy link
Member

@JanKrivanek JanKrivanek left a comment

Choose a reason for hiding this comment

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

Looks great now! Plus we have assurance by the tests - perfect!
I'd want to see the changewave documented in userfacing .md, plus quick offline confirmation we want to preserve the AppDomainSetup outside the TaskLoader. Then I'll sign-off

MichalPavlik and others added 4 commits October 18, 2023 09:52
Copy link
Member

@JanKrivanek JanKrivanek left a comment

Choose a reason for hiding this comment

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

Thank you for all the effort! ;-)
:shipit:

@MichalPavlik MichalPavlik merged commit 867e260 into main Oct 18, 2023
8 checks passed
@MichalPavlik MichalPavlik deleted the dev/mipavlik/task-appdomainconfig-serialization branch October 18, 2023 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BinFmt] AppDomainSetup
9 participants