-
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
.NET SDK uses wrong libc name on musl libc #83779
Comments
This also propagates to programs built with such |
It is possible to build applications with this seemingly broken The .NET SDK musl version was probably supposed to be used on a glibc Linux system but for a musl packaging? |
We don't explicitly specify the libc name or path, we are using the system defaults (Alpine Linux): # use gcc to compile a hello world app
$ echo "int main(){}" | gcc -xc -
# inspect the executable
$ ldd ./a.out
/lib/ld-musl-x86_64.so.1 (0x7f15b41a7000)
libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f15b41a7000)
$ readelf -a ./a.out | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libc.musl-x86_64.so.1]
# compare with dotnet executable
$ ldd $(command -v dotnet)
/lib/ld-musl-x86_64.so.1 (0x7f088e769000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7f088e507000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f088e4e9000)
libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f088e769000)
$ readelf -a $(command -v dotnet) | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.musl-x86_64.so.1] Do you have a suggestion to improve Alternatively, you can create a Another alternative is to patch the ELF after the fact: # Prerequisite: emerge equivalent of 'apk add patchelf'
$ patchelf --replace-needed libc.musl-x86_64.so.1 libc.so $(command -v dotnet)
# or patch all ELF files under install dir
$ find /usr/share/dotnet/ -exec file {} \; | grep ELF | \
while IFS=: read name rest; do patchelf --replace-needed libc.musl-x86_64.so.1 libc.so $name; done
# (and ~/.nuget dir if needed)
# verify desired results
$ ldd $(command -v dotnet)
/lib/ld-musl-x86_64.so.1 (0x7f2186a5d000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7f21867f9000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f21867db000)
libc.so => /lib/ld-musl-x86_64.so.1 (0x7f2186a5d000)
$ readelf -a $(command -v dotnet) | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so] |
@am11 thank you for your quick response.
Currently we struggle with building .NET SDK from source under Portage mainly because the network restriction and huge build size, see: gentoo/gentoo#21112 So we are talking about binary distributed by Microsoft / .NET project now only.
I hope a person form Gentoo Toolchain Project or one of musl maintainers in Gentoo could comment on that.
I think this is what we will have to do. |
Im worried that subsequent application builds will also want to link to "wrong" musl libc name. |
Cc @richlander |
Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov Issue DetailsDescribe the bugOn a Gentoo system built with musl libc the library Expectations.NET SDK links to a more widely known musl library name. Further technical detailsmusl version is: 1.2.3-r7 See also https://bugs.gentoo.org/894760
|
@xgqt, I am not sure if that issue was just a lint warning or the app actually failed to run? In another issue (https://bugs.gentoo.org/894760#c3), I see this link:
which suggests that the link was resolved on gentoo. Try running that app. |
It must run since it can compile .NET applications, |
This is the logfile: https://894758.bugs.gentoo.org/attachment.cgi?id=851776 And quoting the build process:
|
Yup, I was referring to that |
Well, not really, "we" can not ignore it, But yes, this is not a critical issue in term of that the app can run. BUT it might be producing "garbage" applications --> #83779 (comment) |
Not sure I followed. If the app is running that means dynamic loader successfully loaded the libc among other dependencies at the startup. Otherwise you will get SIGABRT right away when you execute the app. libc is the first library dynamic linker loads at runtime (discounting the ELF interpreter). If you are not getting any error when running the app, then this is a bogus warning. QA tool should be fixed. |
Hi, We are running into a similar issue on void running musl as well with a missing |
@rmboggs, hello. I tested .NET 8 build in void-linux docker container, it seems to be running just fine. Full story: # interactively run the container:
# https://github.com/void-linux/void-docker/pkgs/container/void-linux/68157668?tag=20230204RC01-thin-bb-x86_64-musl
$ docker run -it ghcr.io/void-linux/void-linux:20230204RC01-thin-bb-x86_64-musl
# inside the container
# 1. install dependencies (for SDK commands)
$ xbps-install -Sy curl openssl icu-libs
# 2. download and install .NET
$ mkdir ~/.dotnet && \
curl -sSL https://aka.ms/dotnet/8.0.1xx/daily/dotnet-sdk-linux-musl-x64.tar.gz | tar xzf - -C ~/.dotnet && \
export PATH=$PATH:~/.dotnet
# 3. create a simple web api app and run it
$ dotnet new api -n api1 && cd api1
# add .NET 8 preview feed
$ cat > nuget.config <<EOF
<configuration>
<packageSources>
<add key="dotnet8" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />
</packageSources>
</configuration>
EOF
$ dotnet run
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: /api1
# 4. try AOT: first the prereqs
$ xbps-install -Sy clang zlib-devel
# 5. publish AOT app
$ dotnet publish -o dist -c Release -p:PublishAot=true
$ dist/api1
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: /api1 |
Hi @am11, |
Can you share the output of |
Hi @am11,
The file in question isn't there. However, I dug further and found the vstest.console file in the sdk files has this output for ldd:
I'm not sure how/why vstest.console is linking to that file when it isn't on my system. Especially when it looks like it is trying to link to the ld-musl-x86_64.so.1 above. Anything I can do to avoid the reference to the missing file for vstest.console? |
and
are resolving to the same "ELF intepreter". Which means if So the real question is, is the binary actually failing or some QA/linting took is complaining about the name? If it is former, then please explain a bit, when/how it fails, what's the exit code when it fails ( (replace aarch64 with x86_64) # first check the header
$ readelf -d that_binary
Dynamic section at offset 0x92f930 contains 34 entries:
Tag Type Name/Value
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/netcoredeps]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.musl-aarch64.so.1]
^^^
it will look something like this
....
# patch it (e.g. `apk add patchelf`)
$ patchelf --replace-needed libc.musl-aarch64.so.1 libc.so that_binary
# check the headers again
$ readelf -d that_binary
Dynamic section at offset 0x92f930 contains 34 entries:
Tag Type Name/Value
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/netcoredeps]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so]
^^^
it "looks" good but binary runs the same 😅
.... |
It's actually failing for the latter, during the install/package stage of the package process.
Thanks, tried this a bit yesterday without success. So there is either another binary in the sdk somewhere that i need to search for or the process that is failing is using something different to check. I'll see if I can keep digging into this. |
Currently this bothers us quite a bit in Gentoo, see https://bugs.gentoo.org/894760 and "Blocks:" tag. Short term solution is to |
@agocke Just curious, why do we not link to the more generic name? |
@xgqt, what does this report on gentoo: $ curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --quality daily --channel 9.0 --install-dir ~/.dotnet9
$ ldd ~/.dotnet9/dotnet
$ ~/.dotnet9/dotnet --info # does this fail? it works on alpine and void-linux (musl edition) As said, we do not explicitly link against any specific ABI version, we pick a minimal OS and link against its libc. Meaning if your libc is older or built differently (e.g. with a different or without the SONAME), then it may not be easy for static analyzer / linter etc. to distinguish that the mismatches it has found are not the real issues; the real dynamic loader will resolve this: |
Info returns:
ldd show:
... looks like no failure? ... but lddtree shows:
... and it can not find So I think that ldd should not be taken as a source of truth here. |
This is what ldd on libcoreclr.so returns
|
Thanks. So the binary is working flawlessly. Based on this info, you can open a bug with QA tool upstream which is raising false-negatives; assuming the QA tool is supposed to validate "whether or not the OS |
Could any .NET developer point to code that is used to determine what libc is linked when dotnet build/publish is used for producing executables? |
Pretty sure that the executable is build with the native runtime and only patched later with the logo and such. |
Hmm if so by patching runtime linkage "errors" we should get "correct" exes (for Gentoo). |
If there was any linkage error, none of the executables would run. If executables are running, ignore the naive QA tool. |
I tried to investigate my assumption and hack around with sos=(
/opt/dotnet-sdk-bin-8.0/dotnet
/opt/dotnet-sdk-bin-8.0/host/fxr/8.0.1/libhostfxr.so
/opt/dotnet-sdk-bin-8.0/packs/Microsoft.NETCore.App.Host.linux-musl-x64/8.0.1/runtimes/linux-musl-x64/native/apphost
/opt/dotnet-sdk-bin-8.0/packs/Microsoft.NETCore.App.Host.linux-musl-x64/8.0.1/runtimes/linux-musl-x64/native/libnethost.so
/opt/dotnet-sdk-bin-8.0/packs/Microsoft.NETCore.App.Host.linux-musl-x64/8.0.1/runtimes/linux-musl-x64/native/singlefilehost
/opt/dotnet-sdk-bin-8.0/sdk/8.0.101/AppHostTemplate/apphost
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/createdump
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/libSystem.Globalization.Native.so
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/libSystem.IO.Compression.Native.so
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/libSystem.Native.so
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/libSystem.Net.Security.Native.so
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/libSystem.Security.Cryptography.Native.OpenSsl.so
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/libclrgc.so
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/libclrjit.so
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/libcoreclr.so
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/libcoreclrtraceptprovider.so
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/libhostpolicy.so
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/libmscordaccore.so
/opt/dotnet-sdk-bin-8.0/shared/Microsoft.NETCore.App/8.0.1/libmscordbi.so
)
for so in ${sos[@]} ; do
patchelf --remove-needed libc.musl-x86_64.so.1 $so
patchelf --add-needed libc.so $so
done But with no success, building a example software - Coco in this case produced a binary still requiring the missing library: So probably the runtime libraries (if any) to build Coco come from core NuGet packages.
This also means if we compile .NET SDK on Gentoo with musl libc and the resulting package will not have no despondencies on Either that or .NET SDK hardcodes |
Bug: dotnet/runtime#83779 Closes: https://bugs.gentoo.org/894760 Closes: https://bugs.gentoo.org/825774 Signed-off-by: Maciej Barć <xgqt@gentoo.org>
Describe the bug
On a Gentoo system built with musl libc the library
libc.musl-x86_64.so.1
is inaccessible.Expectations
.NET SDK links to a more widely known musl library name.
Further technical details
musl version is: 1.2.3-r7
See also https://bugs.gentoo.org/894760
The text was updated successfully, but these errors were encountered: