[Vm-dev] The squeak.sh wrapper an LD_LIBRARY_PATH

Eliot Miranda eliot.miranda at gmail.com
Fri Jan 19 22:17:17 UTC 2018


Hi Tobias,

On Fri, Jan 19, 2018 at 11:40 AM, Tobias Pape <Das.Linux at gmx.de> wrote:

>
> Hi Eliot,
>
> Long story short at the end
>
>
> > On 19.01.2018, at 18:48, Eliot Miranda <eliot.miranda at gmail.com> wrote:
> >
> >
> > Hi Tobias,
> >
> >
> >> On Jan 19, 2018, at 7:57 AM, Tobias Pape <Das.Linux at gmx.de> wrote:
> >>
> >>
> >> Hi all,
> >>
> >> So I've seen this LD_LIBRARY_PATH dance in the squeak.sh wrapper.
> >> I would like to see an example where leaving it out fails.
> >> My assumption is, that we can rather do something about it on the
> dlopen-side of the problem and make this script simpler (or even completely
> unnecessary).
> >
> > It is vital in cases where one is using external  dynamic link libraries
> which themselves use other dynamic link libraries.  Also vital in cares
> where there are variants of e.g. lunch.so for different implementations of
> features such as thread-local storage.
> >
> >>
> >> I have played around with dlopen on linux (https://github.com/krono/
> dltest) and my bet is that if we catch all strange names of libc on the
> dlopen side, change them to "libc.so.6" and just go with it, we might end
> up just fine.
> >
> > We might.  But in my hard experience at Cadence using external libraries
> for license verification, xml parsing and much more, we don't.  It may seem
> complex but it's there for a reason, and If It Ain't Broke, Don't Fix It.
> Further, debugging some application because, due to it not having the right
> LD_LIBRARY_PATH, the VM is using a different errno to that the library ends
> up using (for a complete because the VM is using a thread-specific
> implementation but the library ends up using a static one) is really hard,
> and results in one implementing the LD_LIBRARY_PATH dance you see in the
> script.
> >
> > I hope the dance makes more sense now.  Perhaps we should put more
> commentary in the script.  One /really/ doesn't want these kinds of things
> to break unless one loves migraines.
>
> I think I know why the thing is there, but it still bother me. More
> commentary does imho not help.
>
> I'd just say using LD_LIBRARY_PATH for non-debug/non-intercept purposes
> seems extremely uncommon to me:
>
> So, on my linux, there are 2375 common binaries [1], and of these 15 only
> ever mention LD_LIBRARY_PATH [2]
> Lets break them down:
>  - Programs that are used to execute other programs to alter their
> behavior:
>    - eatmydata (changes the way the system fsync works)
>    - fakeroot-{tcp,zsh} (well, fake that we are root)
>   (I thinks LD_LIBRARY_PATH was made exactly for those purposes)
>
> - Collect env vars for reporting/investigation (ie, LD_LIBRARY_PATH is
> just read and not used)
>   - perlthanks
>   - perlbug
>   - rkhunter
> - Shells (Well, they might have to work with LD_LIBRARY_PATH, right? they
> are shells )
>   - busybox
>   - zsh
> - Perl : nonfunctional reference in a documentation string (both variants)
> - Loaders (Well, they make LD_LIBRARY_PATH work, they must use it....)
>   - x86_64-linux-gnu-ld.bfd
>   - ldconfig
> - icu-config: usage not unlike to squeak.sh but sole purpose is to provide
> Compilation flags.
>
> -----------------
>
> Although this is not _very_ representative, I don't think that squeak fits
> any those categories.
> And neither Ruby, Python, nor Nodejs, perl, or php, who all have FFI, seem
> to need any of such loader dances.
>
> I'm not denying that there are reasons that the LD_LIBRARY_PATH was put in.
> Certainly there was a need. But I would really like to see a concrete
> example.
>

OK.  So you can find the issue by googling for lib/tls/libc.  Some lines
have both /lib/libc.so.6 and /lib/tls/libc.so.6.  In fact there are lots of
variations on these naming schemes and I think there may be even more
variants that simply between /lib and /lib/tls (for thread-local storage).
In any case, one's VM may be linked against either one, and one's libraries
need to use the same one, otherwise one has two different, incompatible
libc.so.6 libraries loaded and chaos can ensue.  So the solution is, on
start-up, to find out which libc the Vm is binding to, and to install a
LD_LIBRARY_PATH in the environment that will ensure that loaded libraries
will pick up the same one.  Of course the same goes for any library that is
in more than one place and in use by the Vm and libraries; libc.so is
simply the most likely library.



> To be frank, I'd really love it if we could get rid of the shell script
> altogether (especially since we actually have two virtually identical ones).
>

We only need one.  But historically there are two.  I didn't make that
decision.  I merely maintained the situation.  Sorry.


> It is prone to paths with spaces, very linux-centric, and depends on the
> concrete output of ldd.
>

Indeed.  It is in fact a hack around a bug in linux.  Why linux allows this
situation to occur in the first place is beyond me; it seems insane.  But
my employer needed a solution and so the initial case statement was
developed and extended until some kind soul replaced it with the one liner
that's there now ok, two lines, (one line to extract it, another to install
it).

(Again, I don't say that there was no reason to it to have it , in the
> first place).
>
> ----------------
>
> Long story short: I'd love to see an actual problem-generating config
> (libs, deps of libs or so), so I can understand that stuff better :)
>

Find a linux that has both /lib/libc.so.N and /lib/tls/libc.so.N and you'll
have your sandbox :-)


> Best regards
>         -Tobias
>
>
>
>
>
> [1]: $ find /usr/bin /bin /sbin /usr/sbin /usr/local/bin -type f | wc -l
> [2]: $ find /usr/bin /bin /sbin /usr/sbin /usr/local/bin -type f -exec
> grep LD_LIBRARY_PATH {} \+
> /usr/bin/icu-config:LDLIBRARYPATH_ENVVAR="LD_LIBRARY_PATH"
> Binary file /usr/bin/perl5.24.1 matches
> Binary file /usr/bin/x86_64-linux-gnu-ld.bfd matches
> /usr/bin/eatmydata:   LD_LIBRARY_PATH=${LD_LIBRARY_
> PATH:+"$LD_LIBRARY_PATH:"}/usr/lib/libeatmydata
> /usr/bin/eatmydata:   export LD_LIBRARY_PATH LD_PRELOAD
> /usr/bin/perlthanks:        qw(PATH LD_LIBRARY_PATH LANG PERL_BADLANG
> SHELL HOME LOGDIR LANGUAGE);
> /usr/bin/perlbug:        qw(PATH LD_LIBRARY_PATH LANG PERL_BADLANG SHELL
> HOME LOGDIR LANGUAGE);
> Binary file /usr/bin/perl matches
> /usr/bin/fakeroot-tcp:  trap 'FAKEROOTKEY=$FAKEROOTKEY
> LD_LIBRARY_PATH="$PATHS" LD_PRELOAD="$LIB" /bin/ls -l / >/dev/null 2>&1;
> while kill -s HUP $PID 2>/dev/null; do sleep 0.1; done' EXIT INT
> /usr/bin/fakeroot-tcp:if test -n "$LD_LIBRARY_PATH"; then
> /usr/bin/fakeroot-tcp:  PATHS="$PATHS:$LD_LIBRARY_PATH"
> /usr/bin/fakeroot-tcp:  FAKEROOTKEY=$FAKEROOTKEY LD_LIBRARY_PATH="$PATHS"
> LD_PRELOAD="$LIB" ${SHELL:-/bin/sh}
> /usr/bin/fakeroot-tcp:  FAKEROOTKEY=$FAKEROOTKEY LD_LIBRARY_PATH="$PATHS"
> LD_PRELOAD="$LIB" "$@"
> Binary file /usr/bin/zgz matches
> /usr/bin/rkhunter:      # Finally we check the LD_LIBRARY_PATH. This check
> may be
> /usr/bin/rkhunter:                      if [ -n "${LD_LIBRARY_PATH}" ];
> then
> /usr/bin/rkhunter:
> LD_LIBRARY_PATH_SAVED="${LD_LIBRARY_PATH}"
> /usr/bin/rkhunter:
> LD_LIBRARY_PATH="${LD_LIBRARY_PATH_SAVED}"
> /usr/bin/rkhunter:                                      export
> LD_LIBRARY_PATH
> /usr/bin/rkhunter:                                      unset
> LD_LIBRARY_PATH
> /usr/bin/rkhunter:
> LD_LIBRARY_PATH="${LD_LIBRARY_PATH_SAVED}"
> /usr/bin/rkhunter:                              export LD_LIBRARY_PATH
> /usr/bin/rkhunter:                                      display --to LOG
> --type WARNING SHARED_LIBS_PATH_BAD "${LD_LIBRARY_PATH}"
> /usr/bin/fakeroot-sysv:  trap 'FAKEROOTKEY=$FAKEROOTKEY
> LD_LIBRARY_PATH="$PATHS" LD_PRELOAD="$LIB" /bin/ls -l / >/dev/null 2>&1;
> while kill -s TERM $PID 2>/dev/null; do sleep 0.1; done' EXIT INT
> /usr/bin/fakeroot-sysv:if test -n "$LD_LIBRARY_PATH"; then
> /usr/bin/fakeroot-sysv:  PATHS="$PATHS:$LD_LIBRARY_PATH"
> /usr/bin/fakeroot-sysv:  FAKEROOTKEY=$FAKEROOTKEY
> LD_LIBRARY_PATH="$PATHS"  LD_PRELOAD="$LIB" ${SHELL:-/bin/sh}
> /usr/bin/fakeroot-sysv:  FAKEROOTKEY=$FAKEROOTKEY
> LD_LIBRARY_PATH="$PATHS"  LD_PRELOAD="$LIB" "$@"
> Binary file /bin/zsh matches
> Binary file /bin/busybox matches
> Binary file /sbin/ldconfig matches


_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20180119/08acb579/attachment.html>


More information about the Vm-dev mailing list