lib/dns/tests/tkey_test uses -Wl,--wrap incorrectly
In fact, tkey_test
is currently not using -Wl,--wrap
at all, despite #ifdef LD_WRAP
and the related configure.ac
checks. Here is the culprit:
tkey_test@EXEEXT@: tkey_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
if test "${LD_WRAP_TESTS}" = true; then WRAP="${WRAP_OPTIONS}"; fi; \
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \
${LDFLAGS} ${WRAP} -o $@ tkey_test.@O@ \
${DNSLIBS} ${ISCLIBS} ${LIBS}
Note that ${WRAP}
in the libtool
invocation only contains a single dollar sign, which means make
will try evaluating a make variable (not an environment variable) called WRAP
, which is not defined (and thus evaluates to an empty string).
If lib/dns/tests/Makefile.in
is changed to use $${WRAP}
instead, tkey_test
is still compiled correctly, but the -Wl,--wrap
part of the linker invocation is essentially a noop as the actual C code in lib/dns/tests/tkey_test.c
does not depend on -Wl,--wrap
to work.
The important point here is that -Wl,--wrap
does not work with calls made from inside shared libraries (it is not like LD_PRELOAD
). Thus, since tkey_test
calls e.g. dns_tkeyctx_create()
, which resides inside libdns, and tkey_test
does not call isc__mem_get()
directly, and libdns is not built with -Wl,--wrap
, dns_tkeyctx_create()
still calls the "real" isc__mem_get()
from libisc.
What makes tkey_test
work are its local definitions of isc__mem_*()
functions that call __wrap_isc__mem_*()
functions directly. However, these local versions of isc__mem_*()
do not need -Wl,--wrap
support in the linker in order to work properly.
All in all, I think we need to reconsider our strategy here, i.e. I think:
- we do not need
-Wl,--wrap
support in the linker to achieve what we want intkey_test
, - in the typical case, we cannot use
-Wl,--wrap
with unit tests linked with BIND shared libraries to achieve what we want.
@ondrej, thoughts?