Static application with --dynamic-list crashes
Alexey Neyman
stilor@att.net
Thu Mar 16 07:07:00 GMT 2017
On 03/15/2017 02:32 AM, Szabolcs Nagy wrote:
> On 15/03/17 08:08, Alexey Neyman wrote:
>> Hi,
>>
>> I've noticed a strange behavior and I am not sure if it is a bug, and if it is - whether it is in gcc, binutils
>> or glibc.
>>
>> The problem I noticed was that in crosstool-ng, when a gdbserver is linked statically, it requests a strange
>> path as the dynamic linker (/lib/ld64.so.1). This path is the default in ld when it creates a dynamically
>> linked application and there was no --dynamic-linker= option passed in. In this case, the application was
>> linked with "-static -Wl,--dynamic-list=some.file". With these options, GCC does not pass --dynamic-linker
>> (because -static is in effect) - but ld thinks it links a dynamically linked app because of the --dynamic-list.
>>
> oh i thought it only affected gdb, not gdbserver.
> if gdbserver is broken with static linking that's
> a huge bug.
I see this invalid linker in both gdb and gdbserver binaries.
>> So the first question is, does it even make sense to link a binary with these options? I'd say there may be a
>> use case - after all, glibc allows dlopen() from a statically linked binary, and all --dynamic-list does is
>> exports some symbols from the application if one does dlopen(NULL, ...).
>>
>> I also tried to experiment a bit. It turned out that if I create /lib/ld64.so.1 as a symlink to
>> ld-linux-x86-64.so.2, it makes GLIBC crash. It also crashes if I pass
>> --dynamic-linker=/lib/ld-linux-x86-64.so.2, or if I pass --no-dynamic-linker.
>>
>> I then created a small script (attached) that exercised these options on various libcs (by chrooting into an
>> environment with GLIBC, uClibc-ng & musl. Here is the summary:
>>
>> '-static --Wl,--dynamic-list=foo.list'
>> * Resulted in "./foo: No such file or directory" with all three libcs
>>
>> '-static --Wl,--dynamic-list=foo.list -Wl,--no-dynamic-linker'
>> * GLIBC either crashed or hung; stock 2.25 crashed for x86_64/i686/x32; Ubuntu 16.10 glibc also crashed with
>> x86_64/x32 but i686 version instead hung indefinitely
>> * uClibc-ng crashed on i686 and did not crash on x86_64, but dlopen(NULL) returned error
>> * musl did not crash on either x86_64/i686, but dlopen(NULL) returned error on both
>>
>> '-static --Wl,--dynamic-list=foo.list -Wl,--dynamic-linker=LDSO' (where LDSO is the appropriate path for a
>> given architecture/libc
>> * GLIBC crashed on x86_64/i686/x32, both stock 2.25 and Ubuntu's
>> * uClibc-ng and musl did not crash on either x86_64/i686 but again, dlopen(NULL) failed on both.
>>
>> Thoughts?
> this is a nasty regression in binutils:
>
> https://sourceware.org/ml/binutils/2017-01/msg00431.html
>
> musl has no dlopen support with static linking (yet)
> (and it is not trivial to get it to work sensibly,
> the glibc approach is mostly broken: requires a glibc
> installation of the right version on the target which
> defeats the purpose of static linking)
>
> the good news is that none of the dlopened dsos
> should matter for gdb (it can work without threaddb
> etc) so i think gdb should be fixed to have a
> workaround for the binutils bug (but i don't have
> an immediate solution).
I'll just put a reference to these bugs to crosstool-ng help for now.
I also notived that with -rdynamic instead of -Wl,--dynamic-list, static
binaries do not crash - even though the symbols in the binary are not
exported. I haven't checked yet how it affects the gdb/gdbserver,
whether they'll work or not.
Until this is fixed upstream, static linking of gdb/gdbserver in
crosstool-ng will be marked experimental.
Regards,
Alexey.
>
More information about the Libc-alpha
mailing list