skalibs: issue with strnlen() when statically linking with uclibc-ng

From: Eric Le Bihan <>
Date: Sat, 13 Jan 2018 19:12:13 +0100


The autobuilder system of the Buildroot project (which rebuilds packages
for multiple architectures and toolchains) reported an issue when
building s6-rc for ARM using uclibc-ng statically [1]. The build
ends as follows:

In function `strnlen':
strnlen.c:(.text+0x0): multiple definition of `strnlen'
first defined here

It means that skalibs v2.6.3.0 has been compiled with its internal variant of
strnlen(), as the configuration script failed to detect the one provided by

When trying to recreate the build issue, using a tweaked version of
skalibs/configure gives us more information:

/home/eric/build/test-s6-rc- -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -Isrc/include -Werror=implicit-function-declaration -Werror=implicit-int -Werror=pointer-sign -Werror=pointer-arith -Wno-unused-value -Wno-parentheses -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -pipe -Wall -std=c99 -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -Wa,--noexecstack -ffunction-sections -fdata-sections -O2 -fomit-frame-pointer -fno-stack-protector -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os -static -o trystrnlen.o -c src/sysdeps/trystrnlen.c
src/sysdeps/trystrnlen.c: In function 'main':
src/sysdeps/trystrnlen.c:10:10: error: implicit declaration of function 'strnlen' [-Werror=implicit-function-declaration]
   return strnlen("/", 1) ;
cc1: some warnings being treated as errors

The MAN page for strnlen() from glibc states that _POSIX_C_SOURCE should be
defined and uclibc-ng seems to behave the same. The _POSIX_C_SOURCE is indeed
passed by Buildroot to the cross-compiler when build the program.

But since v2.6.3.0, skalibs/src/sysdeps/trystrnlen.c clears the definition of
_POSIX_C_SOURCE. Allowing it again solves the issue: the uclibc-ng version of
strnlen() is detected, skalibs internal variant is disabled and s6-rc-update
statically links with uclibc-ng like a charm.

I tried to statically link with musl and surprisingly, there is no linking error
even though the skalibs variant of strnlen() is enabled and musl provides it

$ grep STRNLEN ~/build/demo-s6/qemu/x86/musl/static/staging/usr/include/skalibs/sysdeps.h
$ grep STRNLEN ~/build/demo-s6/qemu/x86/uclibc/static/staging/usr/include/skalibs/sysdeps.h

One of the differences between uclibc-ng and musl is that uclibc-ng, as glibc,
defines strnlen() using libc_hidden_def(strnlen), which results in the following
when inspecting symbols:

$ objdump -t ~/build/demo-s6/qemu/x86/musl/static/staging/lib/libc.a | grep strnlen
00000000 *UND* 00000000 strnlen
00000000 *UND* 00000000 strnlen
strnlen.o: format de fichier elf32-i386
00000000 l df *ABS* 00000000 strnlen.c
00000000 l d .text.strnlen 00000000 .text.strnlen
00000000 g F .text.strnlen 00000033 strnlen
00000000 *UND* 00000000 strnlen
$ objdump -t ~/build/demo-s6/qemu/x86/uclibc/static/staging/usr/lib/libc.a | grep strnlen
00000000 *UND* 00000000 __GI_strnlen
00000000 *UND* 00000000 __GI_strnlen
strnlen.os: format de fichier elf32-i386
00000000 l df *ABS* 00000000 strnlen.c
00000000 l d .text.__GI_strnlen 00000000 .text.__GI_strnlen
00000000 g F .text.__GI_strnlen 00000034 .hidden __GI_strnlen
00000000 g F .text.__GI_strnlen 00000034 strnlen
00000000 *UND* 00000000 __GI_strnlen

Would this difference explains why there is no redefinition linking error with
musl, or am I missing something?

What is the reason for clearing _POSIX_C_SOURCE from trystrnlen.c?



Received on Sat Jan 13 2018 - 18:12:13 UTC

This archive was generated by hypermail 2.3.0 : Sun May 09 2021 - 19:38:49 UTC