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

ResolveAssemblyReference fails in invariant mode on Alpine linux with error MSB3095 #3066

Closed
natemcmaster opened this issue Mar 8, 2018 · 15 comments
Assignees
Labels
Area: Tasks Issues impacting the tasks shipped in Microsoft.Build.Tasks.Core.dll. bug triaged
Milestone

Comments

@natemcmaster
Copy link
Contributor

Steps to reproduce

Create a dockerfile with these contents:

FROM microsoft/dotnet:2.1-runtime-deps-alpine
WORKDIR /code/build

RUN apk add --no-cache \
        curl \
        icu-libs \
        openssl

ENV DOTNET_SDK_VERSION=2.1.300-preview2-008251
RUN curl -fsSL -o /tmp/dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-alpine.3.6-x64.tar.gz \
    && mkdir -p /usr/share/dotnet \
    && tar xzf /tmp/dotnet.tar.gz -C /usr/share/dotnet \
    && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet \
    && dotnet help

RUN dotnet new console --no-restore \
    && dotnet restore --source https://dotnet.myget.org/F/dotnet-core/api/v3/index.json \
    && dotnet build --no-restore

And execute docker build . -t test

Expected behavior

I should be able to build a simple console application.

Actual behavior

RAR fails with "error MSB3095: Invalid argument. SafeHandle cannot be null".

/usr/share/dotnet/sdk/2.1.300-preview2-008251/Microsoft.Common.CurrentVersion.targets(2052,5): error MSB3095: Invalid argument. SafeHandle cannot be null. [/code/build/build.csproj]
/usr/share/dotnet/sdk/2.1.300-preview2-008251/Microsoft.Common.CurrentVersion.targets(2052,5): error MSB3095: Parameter name: pHandle [/code/build/build.csproj]

https://github.com/Microsoft/msbuild/blob/vs15.6/src/Tasks/Microsoft.Common.CurrentVersion.targets#L2052

Environment data

msbuild /version output: Microsoft (R) Build Engine version 15.6.82.30579 for .NET Core

OS info: Alpine 3.6 x64
dotnet: 2.1.300-preview2-008251

@rainersigwald rainersigwald added this to the MSBuild 15.7 milestone Mar 8, 2018
@rainersigwald rainersigwald added bug Area: Tasks Issues impacting the tasks shipped in Microsoft.Build.Tasks.Core.dll. labels Mar 8, 2018
@ghost
Copy link

ghost commented Mar 9, 2018

Related to https://github.com/dotnet/cli/issues/8290

btw, in interactive mode, this works for me

docker run -it microsoft/dotnet:2.1-sdk-alpine

this is dotnet runtime with SDK. After hitting enter, when you get into the container:

dotnet new console -n test
cd test
dotnet run

# 'Hello World!' is printed

cc @MichaelSimons

@MichaelSimons
Copy link
Member

@kasper3 - the difference between your scenario and Nate's is a difference in the globalization invariant mode. The runtime images run with the globalization invariant mode enabled while the sdk image doesn't.

@ghost
Copy link

ghost commented Mar 11, 2018

Cool, so currently the workaround is to add:

ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT false
ENV LC_ALL en_US.UTF-8
ENV LANG en_US.UTF-8

in Dockerfile and

export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT false
export LC_ALL en_US.UTF-8
export LANG en_US.UTF-8

if you are using interactive shell.

@MichaelSimons
Copy link
Member

@kasper3 - you would also need to add icu-libs

@ghost
Copy link

ghost commented Mar 13, 2018

Yes icu-libs are required even if we use alpine 3.6 tarball on a regular/official alpine docker (non microsoft/dotnet one): https://github.com/dotnet/cli/issues/8767 (I used icu but only icu-libs is required which is a dependency of icu).

@natemcmaster natemcmaster changed the title ResolveAssemblyReference fails on Alpine linux with error MSB3095 ResolveAssemblyReference fails in invariant mode on Alpine linux with error MSB3095 Mar 13, 2018
@rainersigwald rainersigwald self-assigned this Mar 13, 2018
@rainersigwald
Copy link
Member

I avoided the catch clause that sucked all the information away and got

Invalid argument. System.ArgumentNullException: SafeHandle cannot be null. [/code/build/build.csproj]
Parameter name: pHandle [/code/build/build.csproj]
   at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success) [/code/build/build.csproj]
   at Interop.Globalization.GetSortKey(SafeSortHandle sortHandle, String str, Int32 strLength, Byte* sortKey, Int32 sortKeyLength, CompareOptions options) [/code/build/build.csproj]
   at System.Globalization.CompareInfo.GetHashCodeOfStringCore(String source, CompareOptions options) [/code/build/build.csproj]
   at System.Collections.Hashtable.GetHash(Object key) [/code/build/build.csproj]
   at System.Collections.Hashtable.InitHash(Object key, Int32 hashsize, UInt32& seed, UInt32& incr) [/code/build/build.csproj]
   at System.Collections.Hashtable.ContainsKey(Object key) [/code/build/build.csproj]
   at Microsoft.Build.Tasks.ReferenceTable.BuildSimpleNameTable() [/code/build/build.csproj]
   at Microsoft.Build.Tasks.ReferenceTable.ResolveConflictsBetweenReferences() [/code/build/build.csproj]
   at Microsoft.Build.Tasks.ReferenceTable.ResolveConflicts(DependentAssembly[]& idealRemappings, AssemblyNameReference[]& conflictingReferences) [/code/build/build.csproj]
   at Microsoft.Build.Tasks.ResolveAssemblyReference.Execute(FileExists fileExists, DirectoryExists directoryExists, GetDirectories getDirectories, GetAssemblyName getAssemblyName, GetAssemblyMetadata getAssemblyMetadata, GetLastWriteTime getLastWriteTime, GetAssemblyRuntimeVersion getRuntimeVersion, GetAssemblyPathInGac getAssemblyPathInGac, IsWinMDFile isWinMDFile, ReadMachineTypeFromPEHeader readMachineTypeFromPEHeader) [/code/build/build.csproj]

So it's a non-generic Hashtable that's throwing.

@rainersigwald
Copy link
Member

Changing it to a generic Dictionary doesn't help, though. Same stack in CompareInfo.

@rainersigwald
Copy link
Member

Ok, so the microsoft/dotnet:2.1-runtime-deps-alpine image comes with

export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT='true'

Which opts every running application into the globalization invariant mode.

Those docs say

The drawback of running in the invariant mode is applications will get poor globalization support. This new option is only recommended for developers that understand globalization and the impact of its absence.

When enabling the invariant mode, all cultures behave like the invariant culture.

So it seems odd that opting into a CurrentCultureIgnoreCase comparer would cause a problem.

I think this is a corefx bug so I filed https://github.com/dotnet/corefx/issues/28021 with a small repro.

@ghost
Copy link

ghost commented Mar 13, 2018

The bug in corefx aside, I am not sure why we need to set invariant globalization in Alpine Linux docker, since ICU package is available in their packages for ages and dotnet console/mvc apps just work fine with full globalization support.

@natemcmaster
Copy link
Contributor Author

@kasper3 you don't have to set invariant mode in Alpine. That just happens to be the default chosen by https://github.com/dotnet/dotnet-docker. Presumably, this bug would happen in any Linux distro with invariant mode enabled.

@ghost
Copy link

ghost commented Mar 13, 2018

In https://github.com/dotnet/corefx/issues/28021 @rainersigwald has shown that with invariant set in Ubuntu, it works fine. On Alpine, invariant globalization seems to have some issue. Both Ubuntu and Alpine are tested with 2.1 package.

@MichaelSimons
Copy link
Member

MichaelSimons commented Mar 13, 2018

@kasper3 The reason invariant mode is the default in the dotnet/dotnet-docker Alpine images is to keep the size of the runtime image to a minimal. See dotnet/dotnet-docker-nightly#500 for more details.

@ghost
Copy link

ghost commented Mar 13, 2018

I take it back @natemcmaster, it is reproducible on Debian as well as Alpine: https://github.com/dotnet/corefx/issues/28021#issuecomment-372843375

@rainersigwald
Copy link
Member

Yeah, sorry that was confusing: I used Ubuntu + runtime 2.0 and Alpine + runtime 2.1 for my examples.

@rainersigwald
Copy link
Member

Just checked with 2.1.300-preview2-008510 and everything worked, so the CoreFX fix looks sufficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Tasks Issues impacting the tasks shipped in Microsoft.Build.Tasks.Core.dll. bug triaged
Projects
None yet
Development

No branches or pull requests

4 participants