Building a testdir for module 'striconveh' on CentOS 7,
with -DCONTINUE_AFTER_ASSERT and with CFLAGS=-O2, I see a compilation error:
gcc -std=gnu99 -std=gnu11 -DHAVE_CONFIG_H -DEXEEXT=\"\" -I. -I../../gltests
-I.. -DGNULIB_STRICT_CHECKING=1 -DIN_GNULIB_TESTS=1 -I. -I../../gltests -I..
-I../../gltests/.. -I../gllib -I../../gltests/../gllib -Wall
-DCONTINUE_AFTER_ASSERT -Wno-error -g -O2 -MT test-pthread-thread.o -MD -MP
-MF $depbase.Tpo -c -o test-pthread-thread.o
../../gltests/test-pthread-thread.c &&\
mv -f $depbase.Tpo $depbase.Po
../../gltests/test-pthread-thread.c: In function ‘main’:
../../gltests/test-pthread-thread.c:54:7: warning: implicit declaration of
function ‘_gl_pre_abort’ [-Wimplicit-function-declaration]
ASSERT (memcmp (&main_thread_before, &main_thread_after,
^
gcc -std=gnu99 -std=gnu11 -Wno-error -g -O2 -o test-pthread-thread
test-pthread-thread.o libtests.a ../gllib/libgnu.a libtests.a ../gllib/libgnu.a
libtests.a -pthread
test-pthread-thread.o: In function `main':
/home/bruno/testdir1/build/gltests/../../gltests/test-pthread-thread.c:61:
undefined reference to `_gl_pre_abort'
/home/bruno/testdir1/build/gltests/../../gltests/test-pthread-thread.c:64:
undefined reference to `_gl_pre_abort'
/home/bruno/testdir1/build/gltests/../../gltests/test-pthread-thread.c:58:
undefined reference to `_gl_pre_abort'
/home/bruno/testdir1/build/gltests/../../gltests/test-pthread-thread.c:54:
undefined reference to `_gl_pre_abort'
collect2: error: ld returned 1 exit status
make[4]: *** [test-pthread-thread] Error 1
But <stdlib.h>, included near the top of macros.h, is supposed to define
#define _gl_pre_abort() /* empty */
if — like here — the module 'abort-debug' is not in use.
The cause is that
1. An earlier include of <string.h> has included <bits/string2.h>.
2. <bits/string2.h> does
#define __need_malloc_and_calloc
#include <stdlib.h>
This include of <stdlib.h> is redirected from gllib/stdlib.h to
/usr/include/stdlib.h, via #include_next.
3. Then comes the #include <stdlib.h> from within macros.h. Since
__need_malloc_and_calloc is still defined, it again merely redirects
to /usr/include/stdlib.h, via #include_next. That is, it bypasses
the tons of definitions of gllib/stdlib.h. In particular, _gl_pre_abort
does not get defined.
4. In the expansion of macro ASSERT, _gl_pre_abort denotes an undefined
function.
This patch fixes it.
The reason we don't see this issue with newer glibc versions is that
<bits/string2.h> has been removed. glibc now relies on the GCC compiler
to do string operations optimizations at -O2.
2024-05-22 Bruno Haible <[email protected]>
stdlib: Handle glibc special invocation conventions correctly.
* lib/stdlib.in.h: Undefine __need_malloc_and_calloc after doing the
#include_next <stdlib.h>.
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index ef9fde30eb..cfc69d0a50 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -26,6 +26,10 @@
#@INCLUDE_NEXT@ @NEXT_STDLIB_H@
+/* Make sure that the macros that indicate the special invocation convention
+ get undefined. This is needed at least on CentOS 7. */
+#undef __need_malloc_and_calloc
+
#else
/* Normal invocation convention. */