artempyanykh / marksman

Write Markdown with code assist and intelligence in the comfort of your favourite editor.
MIT License
1.91k stars 34 forks source link

helix + alpine + distrobox #209

Open crawfordlong opened 1 year ago

crawfordlong commented 1 year ago

Environment: Fedora Silverblue 38 (host) Alpine distrobox container

Observed Behavior:

First, this may be a case of user error. This is my first go with an lsp solution and helix.

Second, I downloaded the latest (as of yesterday) marksman binary, placed it in ~/.local/bin, and confirmed that it is in the path both by confirming the path and executing hx --health markdown. This command shows the presence of marksman in both the base system and within the distrobox container.

If I execute hx test.md in the base system (where I don't do any work), everything works smoothly. If, however, I execute the same command or open an existing markdown file from within the container (where I am doing primary work), marksman does not appear to start, though there is a long (3-5 second) lag exiting helix in the container that does not occur on the base system.

Edit: I ran the same hx test.md in a Fedora 38 distrobox container, and I received a hard crash indicating that libicu was not installed. After installing libicu, helix started fine and marksman worked perfectly. So this does hint at a possible Alpine issue. If I run marksman server -v 5 in the alpine container, I get the following output, but it's important to note that the first output appears almost 20 seconds after I execute the command (appears instantly in the Fedora base and container):

$ marksman server -v 5
[09:56:59 INF] <LSP Entry> Starting Marksman LSP server: {}
[09:57:00 VRB] <BackgroundAgent> Preparing to start background agent: {}
[09:57:00 VRB] <StatusAgent> StatusAgent starting: {}

Questions:

  1. Does marksman (or any language server) have problems when executed within a container? This might just be a basic user error on my part. (Edit: Works fine in a Fedora container, but that may not be the whole story.)
  2. Does marksman have any dependencies that might not be present in an Alpine container?

If neither of these applies and it looks like we have a bug of some sort, I will start gathering logs and whatnot. Thank you!

artempyanykh commented 1 year ago

Hi @crawfordlong ! Thanks for raising this. I'm not super familiar with Alpine, TBH. At first I though that perhaps problem might be around either missing or different versions of shared libs. Although, marksman is a mostly-statically linked binary it still links dynamically against some base libs:

$ ldd marksman-linux
    linux-vdso.so.1 (0x00007ffe227d5000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f8c7c600000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f8c7c200000)
    libz.so.1 => /lib64/libz.so.1 (0x00007f8c7be00000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f8c7ba00000)
    librt.so.1 => /lib64/librt.so.1 (0x00007f8c7b600000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f8c7b200000)
    libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f8c7ae00000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f8c7aa00000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f8c7d600000)

So I thought maybe something is missing in Alpine? (Have you tried building from source in an Alpine container?)

However, given that the server actually start (albeit with quite a delay), I'm curious what exactly does not work?


Oh, and thanks for reminding me about libicu problem. It's a bit unfortunate that dotnet wants while Marksman doesn't actually make use of it. So, it's been on my todo list to reconfigure the build to avoid requiring libicu.

crawfordlong commented 1 year ago

I’m not terribly familiar with Alpine either, lol. It’s great as a lightweight container though.

I’m going to do some investigation when I have a minute and will report back.

On May 30, 2023 at 5:22 AM, <Artem Pianykh @.***)> wrote:

Hi @crawfordlong (https://github.com/crawfordlong) ! Thanks for raising this. I'm not super familiar with Alpine, but I'd imagine that the problem might be around either missing or different versions of shared libs. Although, marksman is a mostly-statically linked binary it still links dynamically against some base libs:

$ ldd marksman-linux linux-vdso.so.1 (0x00007ffe227d5000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f8c7c600000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f8c7c200000) libz.so.1 => /lib64/libz.so.1 (0x00007f8c7be00000) libm.so.6 => /lib64/libm.so.6 (0x00007f8c7ba00000) librt.so.1 => /lib64/librt.so.1 (0x00007f8c7b600000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f8c7b200000) libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f8c7ae00000) libc.so.6 => /lib64/libc.so.6 (0x00007f8c7aa00000) /lib64/ld-linux-x86-64.so.2 (0x00007f8c7d600000)

Perhaps something is missing in Alpine? Have you tried to build from source in an Alpine container?

— Reply to this email directly, view it on GitHub (https://github.com/artempyanykh/marksman/issues/209#issuecomment-1568092191), or unsubscribe (https://github.com/notifications/unsubscribe-auth/ATWGBHIZJPTNFBFSRSW33S3XIW33PANCNFSM6AAAAAAYKPCBLE). You are receiving this because you were mentioned.Message ID: @.***>

pbnj commented 1 year ago

Alpine is based on musl, whereas other linux images/distros are based on glibc.

Based on @artempyanykh's previous comment, it seems that marksman has dependencies on libgcc and other system libraries that are not available on Alpine.

Here is an example output:

$ docker run --rm -it alpine:latest
/ # apk add curl
fetch https://dl-cdn.alpinelinux.org/alpine/v3.18/main/aarch64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.18/community/aarch64/APKINDEX.tar.gz
curl(1/7) Installing ca-certificates (20230506-r0)
(2/7) Installing brotli-libs (1.0.9-r14)
(3/7) Installing libunistring (1.1-r1)
(4/7) Installing libidn2 (2.3.4-r1)
(5/7) Installing nghttp2-libs (1.55.1-r0)
(6/7) Installing libcurl (8.2.1-r0)
(7/7) Installing curl (8.2.1-r0)
Executing busybox-1.36.1-r0.trigger
Executing ca-certificates-20230506-r0.trigger
OK: 12 MiB in 22 packages
/ # curl -LO https://github.com/artempyanykh/marksman/releases/download/2023-07-25/marksman-linux-arm64
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 17.7M  100 17.7M    0     0   595k      0  0:00:30  0:00:30 --:--:--  566k

/ # chmod u+x ./marksman-linux-arm64

/ # ldd marksman-linux-arm64
        /lib/ld-linux-aarch64.so.1 (0xffff99f0e000)
        libpthread.so.0 => /lib/ld-linux-aarch64.so.1 (0xffff99f0e000)
        libdl.so.2 => /lib/ld-linux-aarch64.so.1 (0xffff99f0e000)
        libz.so.1 => /lib/libz.so.1 (0xffff994f3000)
        libm.so.6 => /lib/ld-linux-aarch64.so.1 (0xffff99f0e000)
        librt.so.1 => /lib/ld-linux-aarch64.so.1 (0xffff99f0e000)
Error loading shared library libgcc_s.so.1: No such file or directory (needed by marksman-linux-arm64)
Error loading shared library libstdc++.so.6: No such file or directory (needed by marksman-linux-arm64)
        libc.so.6 => /lib/ld-linux-aarch64.so.1 (0xffff99f0e000)
Error loading shared library ld-linux-aarch64.so.1: No such file or directory (needed by marksman-linux-arm64)

I was able to resolve these missing shared libraries by installing:

/ # apk add build-base gcompat

But now, I get a different error:

/ # ./marksman-linux-arm64
Segmentation fault

On a debian image, I still could not run the pre-built binary:

root@6e9c73cb2746:/# curl -LO https://github.com/artempyanykh/marksman/releases/download/2023-07-25/marksman-linux-arm64
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 17.7M  100 17.7M    0     0   583k      0  0:00:31  0:00:31 --:--:--  602k

root@6e9c73cb2746:/# chmod u+x ./marksman-linux-arm64

root@6e9c73cb2746:/# ./marksman-linux-arm64
Failed to load System.Private.CoreLib.dll (error code 0x80070002)
Path: /System.Private.CoreLib.dll
Error message: Could not load file or assembly '/System.Private.CoreLib.dll'. The system cannot find the file specified.
 (0x80070002)
Failed to create CoreCLR, HRESULT: 0x80070002

root@6e9c73cb2746:/# ldd ./marksman-linux-arm64
        linux-vdso.so.1 (0x0000ffffa7385000)
        libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffffa6920000)
        libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000ffffa68f0000)
        libz.so.1 => /lib/aarch64-linux-gnu/libz.so.1 (0x0000ffffa68b0000)
        libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffffa6810000)
        librt.so.1 => /lib/aarch64-linux-gnu/librt.so.1 (0x0000ffffa67e0000)
        libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000ffffa67a0000)
        libstdc++.so.6 => /lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000ffffa6580000)
        libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffffa63d0000)
        /lib/ld-linux-aarch64.so.1 (0x0000ffffa7348000)
foxyseta commented 2 months ago

I am a musl user, too, and I use Alpine as well. I was more lucky and have not encountered any segfaults so far, but gcompat is not that reliable in my experience: compatibility with binaries linked against different C libraries implementations is just plain difficult.

I think for starters it should be documented that the binaries are build against glibc. Some projects even add a -glibc suffix to the binaries filename.