VS Code Liveshare

I’m trying to use VS Code Liveshare, which is a proprietary thing, and comes with a binary. It needs libstdc++.so:

-rwxr--r-- 1 wmertens users 86584 Apr 30 18:17 /home/wmertens/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent
$ ldd -d ~/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent
	linux-vdso.so.1 (0x00007ffd2e5ae000)
	libpthread.so.0 => /nix/store/an6bdv4phxsz14q2sk57iscl2dc7bnj1-glibc-2.30/lib/libpthread.so.0 (0x00007f834c1b5000)
	libdl.so.2 => /nix/store/an6bdv4phxsz14q2sk57iscl2dc7bnj1-glibc-2.30/lib/libdl.so.2 (0x00007f834c1b0000)
	libstdc++.so.6 => not found
	libm.so.6 => /nix/store/an6bdv4phxsz14q2sk57iscl2dc7bnj1-glibc-2.30/lib/libm.so.6 (0x00007f834c070000)
	libgcc_s.so.1 => /nix/store/an6bdv4phxsz14q2sk57iscl2dc7bnj1-glibc-2.30/lib/libgcc_s.so.1 (0x00007f834c056000)
	libc.so.6 => /nix/store/an6bdv4phxsz14q2sk57iscl2dc7bnj1-glibc-2.30/lib/libc.so.6 (0x00007f834be97000)
	/lib64/ld-linux-x86-64.so.2 => /nix/store/an6bdv4phxsz14q2sk57iscl2dc7bnj1-glibc-2.30/lib64/ld-linux-x86-64.so.2 (0x00007f834c1d8000)
undefined symbol: _ZTVN10__cxxabiv116__enum_type_infoE, version CXXABI_1.3	(/home/wmertens/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent)
undefined symbol: _ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE, version GLIBCXX_3.4	(/home/wmertens/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent)
undefined symbol: _ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE, version GLIBCXX_3.4	(/home/wmertens/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent)
undefined symbol: _ZNSt8ios_base4InitD1Ev, version GLIBCXX_3.4	(/home/wmertens/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent)
undefined symbol: _ZNSs4_Rep11_S_terminalE, version GLIBCXX_3.4	(/home/wmertens/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent)
undefined symbol: _ZTTSt13basic_fstreamIcSt11char_traitsIcEE, version GLIBCXX_3.4	(/home/wmertens/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent)
undefined symbol: _ZTVSt15basic_streambufIcSt11char_traitsIcEE, version GLIBCXX_3.4	(/home/wmertens/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent)
undefined symbol: _ZNSs4_Rep20_S_empty_rep_storageE, version GLIBCXX_3.4	(/home/wmertens/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent)

So I try providing it:

$ LD_LIBRARY_PATH=/nix/store/jy89v2q2zv074mvw91jgqcvkmk7yqx69-gcc-9.3.0-lib/lib ldd -d ~/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent 
	linux-vdso.so.1 (0x00007ffe51f2a000)
	libpthread.so.0 => /nix/store/an6bdv4phxsz14q2sk57iscl2dc7bnj1-glibc-2.30/lib/libpthread.so.0 (0x00007fa9e77cd000)
	libdl.so.2 => /nix/store/an6bdv4phxsz14q2sk57iscl2dc7bnj1-glibc-2.30/lib/libdl.so.2 (0x00007fa9e77c8000)
	libstdc++.so.6 => /nix/store/jy89v2q2zv074mvw91jgqcvkmk7yqx69-gcc-9.3.0-lib/lib/libstdc++.so.6 (0x00007fa9e75e7000)
	libm.so.6 => /nix/store/an6bdv4phxsz14q2sk57iscl2dc7bnj1-glibc-2.30/lib/libm.so.6 (0x00007fa9e74a7000)
	libgcc_s.so.1 => /nix/store/jy89v2q2zv074mvw91jgqcvkmk7yqx69-gcc-9.3.0-lib/lib/libgcc_s.so.1 (0x00007fa9e748d000)
	libc.so.6 => /nix/store/an6bdv4phxsz14q2sk57iscl2dc7bnj1-glibc-2.30/lib/libc.so.6 (0x00007fa9e72ce000)
	/lib64/ld-linux-x86-64.so.2 => /nix/store/an6bdv4phxsz14q2sk57iscl2dc7bnj1-glibc-2.30/lib64/ld-linux-x86-64.so.2 (0x00007fa9e77f0000)

Seems ok! But:

$ LD_LIBRARY_PATH=/nix/store/jy89v2q2zv074mvw91jgqcvkmk7yqx69-gcc-9.3.0-lib/lib ~/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent 
bash: /home/wmertens/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent: No such file or directory

Strace doesn’t help:

$ LD_LIBRARY_PATH=/nix/store/jy89v2q2zv074mvw91jgqcvkmk7yqx69-gcc-9.3.0-lib/lib strace -f ~/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent 
execve("/home/wmertens/.vscode/extensions/ms-vsliveshare.vsliveshare-1.0.2104/dotnet_modules/vsls-agent", ["/home/wmertens/.vscode/extension"...], 0x7ffc9e63d988 /* 93 vars */) = -1 ENOENT (No such file or directory)
strace: exec: No such file or directory
+++ exited with 1 +++

Any idea how this is possible? LD_DEBUG shows nothing, this seems to happen before ld is involved?

I solved it by creating a wrapper that patches the ELF loaders and puts all the required libs in LD_LIBRARY_PATH: No error "Start collaboration session", nothing happens · Issue #3501 · microsoft/live-share · GitHub

#! /usr/bin/env nix-shell
#! nix-shell -i sh -p dotnetCorePackages.netcore_3_1 icu patchelf gcc gcr liburcu openssl krb5 zlib gnome3.gnome-keyring libsecret desktop-file-utils xorg.xprop

# patch ELF loaders where needed
GCCLIB=$(dirname $(gcc -print-file-name=libstdc++.so.6))
LOADER=$(dirname $(gcc -print-file-name=ld-linux-x86-64.so.2))
find ~/.vscode/extensions/ ~/.config/Code -type f -perm -100 -print0 | xargs -0 file \
| grep 'interpreter /lib' | cut -d: -f1 | while read f; do
	echo "Patching $f" >&2
	patchelf --set-interpreter "$LOADER" "$f"
	RPATH=$(patchelf --print-rpath "$f")
	patchelf --set-rpath "${RPATH+RPATH:}$GCCLIB" "$f"
done
# Provide all libraries
export LD_LIBRARY_PATH=$(echo "$NIX_LDFLAGS" | sed -E -e 's/\s*(-rpath|-L)\s*/:/g' -e 's/^://')
# It seems VSLS downloads dotnet itself so this may not be needed
export DOTNET_ROOT=$(dirname $(type -p dotnet))/..
# Don't know how to tell dotnet about ICU
export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
exec code  "$@"
1 Like

I just found out that it is possible to completely avoid using LD_LIBRARY_PATH
when the library is dynamically loaded / isn’t part of the needed set (patchelf --print-needed).

$ patchelf --add-needed "my-lib-to-add-to-the-needed-set.so" "/path/to/my/exe"
$ patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
  --set-rpath "${lib.makeLibraryPath [ my-lib-derivation ]}" "/path/to/my/exe"

Note that the --add-needed needs to be performed separately / before the
--set-interpreter/--set-rpath invocation.

1 Like