dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.62k stars 4.56k forks source link

.NET SDK uses wrong libc name on musl libc #83779

Open xgqt opened 1 year ago

xgqt commented 1 year ago

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

xgqt commented 1 year ago

This also propagates to programs built with such dotnet exe.

See: https://bugs.gentoo.org/894758

xgqt commented 1 year ago

It is possible to build applications with this seemingly broken dotnet since it ALSO links to a libc library: libc.so.6 => /lib64/libc.so.6 (0x00007f16a4d49000).

The .NET SDK musl version was probably supposed to be used on a glibc Linux system but for a musl packaging? Is this correct? How should the musl version be used on Linux systems without glibc?

am11 commented 1 year ago

.NET SDK links to a more widely known musl library name.

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 DT_NEEDED at build time? If you built everything on gentoo-musl (.NET Runtime + SDK) then it should use whatever defaults were there on the build machine.

Alternatively, you can create a libc.musl-x86_64.so.1 -> /usr/lib/libc.so symlink on your system if it is missing it.

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]
xgqt commented 1 year ago

@am11 thank you for your quick response. Unfortunately you will have to take my words with a grain of salt because I am not a toolchain expert.

Do you have a suggestion to improve DT_NEEDED at build time? If you built everything on gentoo-musl (.NET Runtime + SDK) then it should use whatever defaults were there on the build machine.

Currently we struggle with building .NET SDK from source under Portage mainly because the network restriction and huge build size, see: https://github.com/gentoo/gentoo/pull/21112

So we are talking about binary distributed by Microsoft / .NET project now only.

Alternatively, you can create a libc.musl-x86_64.so.1 -> /usr/lib/libc.so symlink on your system if it is missing it.

I hope a person form Gentoo Toolchain Project or one of musl maintainers in Gentoo could comment on that.

Another alternative is to patch the ELF after the fact:

I think this is what we will have to do. Thanks for the snippet :D

xgqt commented 1 year ago

Im worried that subsequent application builds will also want to link to "wrong" musl libc name. Do you know if this is taken from some place defined by .NET SDK? Im taking about this issue: https://bugs.gentoo.org/894758

danmoseley commented 1 year ago

Cc @richlander

ghost commented 1 year ago

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

Issue Details
### 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
Author: xgqt
Assignees: -
Labels: `area-Host`, `untriaged`
Milestone: -
am11 commented 1 year ago

@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:

        /lib/ld-musl-x86_64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007f16a5287000)

which suggests that the link was resolved on gentoo. Try running that app.

xgqt commented 1 year ago

@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:

        /lib/ld-musl-x86_64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007f16a5287000)

which suggests that the link was resolved on gentoo. Try running that app.

It must run since it can compile .NET applications, in https://bugs.gentoo.org/894758 it compiles csharp-language-server.

xgqt commented 1 year ago

@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:

        /lib/ld-musl-x86_64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007f16a5287000)

which suggests that the link was resolved on gentoo. Try running that app.

It must run since it can compile .NET applications, in https://bugs.gentoo.org/894758 it compiles csharp-language-server.

This is the logfile: https://894758.bugs.gentoo.org/attachment.cgi?id=851776

And quoting the build process:

>>> Unpacking source...
>>> Unpacking csharp-language-server-0.5.7.tar.gz to /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work
>>> Unpacking csharp-language-server-0.5.7-prebuilt.tar.xz to /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work
>>> Source unpacked in /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work
>>> Preparing source in /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7 ...
>>> Source prepared.
>>> Configuring source in /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7 ...
 * Running dotnet restore /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7/src --source /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/nuget_packages -p:TargetFramework=net6.0 ...
=  Determining projects to restore...
=========  Restored /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7/src/CSharpLanguageServer.Tests/CSharpLanguageServer.Tests.fsproj (in 475 ms).
  Restored /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7/src/CSharpLanguageServer/CSharpLanguageServer.fsproj (in 474 ms).
 [ ok ]
>>> Source configured.
>>> Compiling source in /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7 ...
 * Running dotnet build --configuration Debug --no-restore --no-self-contained --nologo --output /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7_net6.0_Debug/csharp-language-server -maxCpuCount:1 -p:TargetFramework=net6.0 /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7/src ...
==  CSharpLanguageServer -> /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7_net6.0_Debug/csharp-language-server/CSharpLanguageServer.dll
  CSharpLanguageServer -> /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7_net6.0_Debug/csharp-language-server/CSharpLanguageServer.dll
/var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7/src/CSharpLanguageServer.Tests/DocumentationTests.fs(102,1): warning FS0988: Main module of program is empty: nothing will happen when it is run [/var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7/src/CSharpLanguageServer.Tests/CSharpLanguageServer.Tests.fsproj]
=  CSharpLanguageServer.Tests -> /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7_net6.0_Debug/csharp-language-server/CSharpLanguageServer.Tests.dll

Build succeeded.

/var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7/src/CSharpLanguageServer.Tests/DocumentationTests.fs(102,1): warning FS0988: Main module of program is empty: nothing will happen when it is run [/var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/work/csharp-language-server-0.5.7/src/CSharpLanguageServer.Tests/CSharpLanguageServer.Tests.fsproj]
    1 Warning(s)
    0 Error(s)

Time Elapsed 00:00:07.48
 [ ok ]
>>> Source compiled.
>>> Test phase [not enabled]: dev-dotnet/csharp-language-server-0.5.7

>>> Install dev-dotnet/csharp-language-server-0.5.7 into /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/image
>>> Completed installing dev-dotnet/csharp-language-server-0.5.7 into /var/tmp/portage/dev-dotnet/csharp-language-server-0.5.7/image

 * Final size of build directory: 1084284 KiB ( 1.0 GiB)
 * Final size of installed tree:    57832 KiB (56.4 MiB)

 * QA Notice: Unresolved soname dependencies:
 * 
 *  /usr/share/csharp-language-server/CSharpLanguageServer: libc.musl-x86_64.so.1
 * 
strip: x86_64-gentoo-linux-musl-strip --strip-unneeded -N __gentoo_check_ldflags__ -R .comment -R .GCC.command.line -R .note.gnu.gold-version
   /usr/share/csharp-language-server/CSharpLanguageServer
>>> Done.
am11 commented 1 year ago

Yup, I was referring to that QA Notice, if the app runs, that means dynamic linker is happy. You can ignore the lint / QA warning.

xgqt commented 1 year ago

Yup, I was referring to that QA Notice, if the app runs, that means dynamic linker is happy. You can ignore the lint / QA warning.

Well, not really, "we" can not ignore it, in Gentoo we care very much to have no QA warnings, mislinked or missing libraries.

But yes, this is not a critical issue in term of that the app can run.

BUT it might be producing "garbage" applications --> https://github.com/dotnet/runtime/issues/83779#issuecomment-1479622855

am11 commented 1 year ago

BUT it might be producing "garbage" applications

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.

rmboggs commented 1 year ago

Hi,

We are running into a similar issue on void running musl as well with a missing libc.musl-x86_64.so.1 link. Is there any way to switch that dependency to something more generic, like libc.so instead?

am11 commented 1 year ago

@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
rmboggs commented 1 year ago

Hi @am11, I am actually working on packaging dotnet 7 for a void package on x64-musl. It builds fine but fails during the package step for SDK because it can't find the package containing libc.musl-x86_64.so.1 because the musl package for void doesn't contain that sym link. I'm hoping that, because the file in question is just a link anyway, that this can be updated to point to the libc.so file instead. Does this make sense?

am11 commented 1 year ago

Can you share the output of ldd $(command -v dotnet)?

rmboggs commented 1 year ago

Hi @am11, I just did the command you asked and it comes up as follows for dotnet:

    /lib/ld-musl-x86_64.so.1 (0x7f8e0be1c000)
    /usr/lib/libswmhack.so.0.0 => /usr/lib/libswmhack.so.0.0 (0x7f8e0be03000)
    libstdc++.so.6 => /lib/libstdc++.so.6 (0x7f8e0ba00000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x7f8e0bde5000)
    libc.so => /lib/ld-musl-x86_64.so.1 (0x7f8e0be1c000)
    libX11.so.6 => /lib/libX11.so.6 (0x7f8e0b8be000)
    libxcb.so.1 => /lib/libxcb.so.1 (0x7f8e0bdbc000)
    libXau.so.6 => /lib/libXau.so.6 (0x7f8e0bdb7000)
    libXdmcp.so.6 => /lib/libXdmcp.so.6 (0x7f8e0bdaf000)

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:

    /lib/ld-musl-x86_64.so.1 (0x7f2fd7af2000)
    /usr/lib/libswmhack.so.0.0 => /usr/lib/libswmhack.so.0.0 (0x7f2fd7ad7000)
    libstdc++.so.6 => /lib/libstdc++.so.6 (0x7f2fd7600000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x7f2fd7ab9000)
    libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f2fd7af2000) <-- Here is the reference
    libX11.so.6 => /lib/libX11.so.6 (0x7f2fd7977000)
    libxcb.so.1 => /lib/libxcb.so.1 (0x7f2fd794e000)
    libXau.so.6 => /lib/libXau.so.6 (0x7f2fd7949000)
    libXdmcp.so.6 => /lib/libXdmcp.so.6 (0x7f2fd7941000)

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?

am11 commented 1 year ago
    libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f2fd7af2000) <-- Here is the reference

and

    libc.so => /lib/ld-musl-x86_64.so.1 (0x7f8e0be1c000)

are resolving to the same "ELF intepreter". Which means if dotnet or vstest.console are not terminating with SIGABRT etc. it shouldn't matter which name was encoded in DT_NEEDED header, as long as dynamic loader can make sense of it. Dynamic loader is smart and looks beyond the verbatim names on the filename.

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 (echo $?) etc. If it is latter, then let me show you how to patch the DT_NEEDED header to get by the bogus lint warnings:

(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 😅
....
rmboggs commented 1 year ago
  libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f2fd7af2000) <-- Here is the reference

and

  libc.so => /lib/ld-musl-x86_64.so.1 (0x7f8e0be1c000)

are resolving to the same "ELF intepreter". Which means if dotnet or vstest.console are not terminating with SIGABRT etc. it shouldn't matter which name was encoded in DT_NEEDED header, as long as dynamic loader can make sense of it. Dynamic loader is smart and looks beyond the verbatim names on the filename.

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 (echo $?) etc. If it is latter, then let me show you how to patch the DT_NEEDED header to get by the bogus lint warnings:

It's actually failing for the latter, during the install/package stage of the package process.

(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 😅
....

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.

xgqt commented 5 months ago

Currently this bothers us quite a bit in Gentoo, see https://bugs.gentoo.org/894760 and "Blocks:" tag.

Short term solution is to patchelf all .NET-produced binaries conditionally for musl installations.

danmoseley commented 5 months ago

@agocke Just curious, why do we not link to the more generic name?

am11 commented 5 months ago

@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: libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1

xgqt commented 5 months ago

@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: libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1

@am11

Info returns:

.NET SDK:
 Version:           9.0.100-alpha.1.24070.2
 Commit:            cac6c93287
 Workload version:  9.0.100-manifests.0d37fe7a

Runtime Environment:
 OS Name:     gentoo
 OS Version:  2.14
 OS Platform: Linux
 RID:         linux-musl-x64
 Base Path:   /root/.dotnet9/sdk/9.0.100-alpha.1.24070.2/

.NET workloads installed:
There are no installed workloads to display.

Host:
  Version:      9.0.0-alpha.1.24066.33
  Architecture: x64
  Commit:       dbb335c6ba

.NET SDKs installed:
  9.0.100-alpha.1.24070.2 [/root/.dotnet9/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 9.0.0-alpha.1.24068.16 [/root/.dotnet9/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 9.0.0-alpha.1.24066.33 [/root/.dotnet9/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

ldd show:

 /lib/ld-musl-x86_64.so.1 (0x7f7264a80000)
        libstdc++.so.6 => /usr/lib/gcc/x86_64-gentoo-linux-musl/13/libstdc++.so.6 (0x7f7264816000)
        libgcc_s.so.1 => /usr/lib/gcc/x86_64-gentoo-linux-musl/13/libgcc_s.so.1 (0x7f72647f3000)
        libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f7264a80000)

... looks like no failure? ...

but lddtree shows:

dotnet => /root/.dotnet9/dotnet (interpreter => /lib/ld-musl-x86_64.so.1)
    libstdc++.so.6 => /usr/lib/gcc/x86_64-gentoo-linux-musl/13/libstdc++.so.6
        libc.so => /usr/lib/libc.so
    libgcc_s.so.1 => /usr/lib/gcc/x86_64-gentoo-linux-musl/13/libgcc_s.so.1
    libc.musl-x86_64.so.1 => not found

... and it can not find libc.musl-x86_64.so.1

So I think that ldd should not be taken as a source of truth here.

xgqt commented 5 months ago

This is what ldd on libcoreclr.so returns

foxylady ~ # ldd ~/.dotnet9/shared/Microsoft.NETCore.App/9.0.0-alpha.1.24066.33/libcoreclr.so
        ldd (0x7f589ffbe000)
        libgcc_s.so.1 => /usr/lib/gcc/x86_64-gentoo-linux-musl/13/libgcc_s.so.1 (0x7f589f8a9000)
        libstdc++.so.6 => /usr/lib/gcc/x86_64-gentoo-linux-musl/13/libstdc++.so.6 (0x7f589f653000)
        libc.musl-x86_64.so.1 => ldd (0x7f589ffbe000)
foxylady ~ # lddtree ~/.dotnet9/shared/Microsoft.NETCore.App/9.0.0-alpha.1.24066.33/libcoreclr.so
libcoreclr.so => /root/.dotnet9/shared/Microsoft.NETCore.App/9.0.0-alpha.1.24066.33/libcoreclr.so (interpreter => none)
    libgcc_s.so.1 => /usr/lib/gcc/x86_64-gentoo-linux-musl/13/libgcc_s.so.1
        libc.so => /usr/lib/libc.so
    libstdc++.so.6 => /usr/lib/gcc/x86_64-gentoo-linux-musl/13/libstdc++.so.6
    libc.musl-x86_64.so.1 => not found
foxylady ~ #
am11 commented 5 months ago

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 ld will be able to load the binary and its linked dependencies" (which is what ldd utility reports).

xgqt commented 5 months ago

@agocke Just curious, why do we not link to the more generic name?

What do you think @am11 of what @agocke suggested?

xgqt commented 5 months ago

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?

MichalPetryka commented 5 months ago

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.

xgqt commented 5 months ago

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).

am11 commented 5 months ago

If there was any linkage error, none of the executables would run. If executables are running, ignore the naive QA tool.

xgqt commented 5 months ago

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).

@MichalPetryka

I tried to investigate my assumption and hack around with patchelf

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:

image

So probably the runtime libraries (if any) to build Coco come from core NuGet packages. Which means one would have to patch the following NuGets:

This also means if we compile .NET SDK on Gentoo with musl libc and the resulting package will not have no despondencies on libc.musl-x86_64.so.1 the software produced by it will gain them! Because a probuilt microsoft.netcore.app.host.linux-musl-x64.8.0.1.nupkg is used.

Either that or .NET SDK hardcodes libc.musl-x86_64.so.1 dependency. I have no other ides for now.