[PATCH] test: Fix and stabilize tst-wcsmbs-clone-overflow test

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Tue May 26 12:54:09 GMT 2026



On 26/05/26 08:45, Frédéric Bérat wrote:
> The test tst-wcsmbs-clone-overflow was initially added to tests-static.
> However, this causes the test to be unstable because gconv modules
> dynamically load libc.so. Any discrepancy between the statically linked
> version and the dynamically loaded one can lead to a crash.

It is not clear when this would happen, is it the case that the tests
is loading the system gconv modules instead of the one in the build
directory?

> 
> By removing the test from tests-static, it relies on dynamic linking,
> safely bypassing the dlopen crash. Since the test is now dynamically
> linked, it cannot use the internal thread-local symbol
> _NL_CURRENT_DATA(LC_CTYPE) because _nl_current_LC_CTYPE is hidden in
> libc.so, leading to undefined references. Thus, the test now uses
> newlocale and uselocale, safely extracting the locale data from the
> returned locale_t object.
> 
> Furthermore, using newlocale requires the gconv-modules configuration to
> be built and available so that the ISO8859-1.so module can be
> dynamically loaded. Otherwise, glibc falls back to the built-in C locale
> conversions, leaving __shlib_handle as NULL and silently bypassing the
> reference counter increment.
> A new Makefile fragment, gen-gconv-modules.mk, is introduced to ensure
> the gconv-modules are built before the test runs, and an explicit check
> for __shlib_handle != NULL is added to the test.
> ---
>  gen-gconv-modules.mk               |  6 ++++++
>  localedata/Makefile                |  6 ++----
>  wcsmbs/Makefile                    |  7 ++-----
>  wcsmbs/tst-wcsmbs-clone-overflow.c | 12 +++++++++---
>  4 files changed, 19 insertions(+), 12 deletions(-)
>  create mode 100644 gen-gconv-modules.mk
> 
> diff --git a/gen-gconv-modules.mk b/gen-gconv-modules.mk
> new file mode 100644
> index 0000000000..046721a7a7
> --- /dev/null
> +++ b/gen-gconv-modules.mk
> @@ -0,0 +1,6 @@
> +# defines target $(gen-gconv-modules) that ensures gconv-modules are available
> +
> +gen-gconv-modules := $(common-objpfx)iconvdata/gconv-modules
> +
> +$(gen-gconv-modules):
> +	$(MAKE) -C ../iconvdata subdir=iconvdata $@
> diff --git a/localedata/Makefile b/localedata/Makefile
> index 6c9fe7c5c4..0fb1d78c29 100644
> --- a/localedata/Makefile
> +++ b/localedata/Makefile
> @@ -287,7 +287,7 @@ install-others := $(addprefix $(inst_i18ndir)/, \
>  			      $(locales))
>  endif
>  
> -tests: $(objdir)/iconvdata/gconv-modules
> +tests: $(gen-gconv-modules)
>  
>  tests-static += \
>    tst-langinfo-newlocale-static \
> @@ -412,6 +412,7 @@ LOCALES := \
>    # LOCALES
>  
>  include ../gen-locales.mk
> +include ../gen-gconv-modules.mk
>  
>  $(objpfx)tst-iconv-emojis-trans.out: $(gen-locales)
>  
> @@ -587,6 +588,3 @@ $(objpfx)mtrace-tst-leaks.out: $(objpfx)tst-leaks.out
>  
>  bug-setlocale1-ENV-only = LOCPATH=$(objpfx) LC_CTYPE=de_DE.UTF-8
>  bug-setlocale1-static-ENV-only = $(bug-setlocale1-ENV-only)
> -
> -$(objdir)/iconvdata/gconv-modules:
> -	$(MAKE) -C ../iconvdata subdir=iconvdata $@
> diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
> index ee3638c0e5..f4f89c030f 100644
> --- a/wcsmbs/Makefile
> +++ b/wcsmbs/Makefile
> @@ -213,10 +213,6 @@ xtests += test-wcsncmp-nonarray
>  tests-internal += \
>    tst-wcsmbs-clone-overflow
>  
> -tests-static += \
> -  tst-wcsmbs-clone-overflow
> -
> -
>  include ../Rules
>  
>  ifeq ($(run-built-tests),yes)
> @@ -233,6 +229,7 @@ LOCALES := \
>    zh_TW.EUC-TW \
>    # LOCALES
>  include ../gen-locales.mk
> +include ../gen-gconv-modules.mk
>  
>  $(objpfx)tst-btowc.out: $(gen-locales)
>  $(objpfx)tst-c16c32-1.out: $(gen-locales)
> @@ -247,7 +244,7 @@ $(objpfx)tst-c32-state.out: $(gen-locales)
>  $(objpfx)test-c8rtomb.out: $(gen-locales)
>  $(objpfx)test-mbrtoc8.out: $(gen-locales)
>  $(objpfx)tst-wscanf-to_inpunct.out: $(gen-locales)
> -$(objpfx)tst-wcsmbs-clone-overflow.out: $(gen-locales)
> +$(objpfx)tst-wcsmbs-clone-overflow.out: $(gen-locales) $(gen-gconv-modules)
>  endif
>  
>  $(objpfx)tst-wcstod-round: $(libm)
> diff --git a/wcsmbs/tst-wcsmbs-clone-overflow.c b/wcsmbs/tst-wcsmbs-clone-overflow.c
> index adfd4fa61d..99461ea087 100644
> --- a/wcsmbs/tst-wcsmbs-clone-overflow.c
> +++ b/wcsmbs/tst-wcsmbs-clone-overflow.c
> @@ -30,8 +30,11 @@
>  static int
>  do_test (void)
>  {
> -  if (setlocale (LC_ALL, "de_DE.ISO-8859-1") == NULL)
> -    FAIL_EXIT1 ("setlocale failed, check if de_DE.ISO-8859-1 is generated");
> +  locale_t loc_obj = newlocale (LC_ALL_MASK, "de_DE.ISO-8859-1", NULL);
> +  if (loc_obj == NULL)
> +    FAIL_EXIT1 ("newlocale failed, check if de_DE.ISO-8859-1 is generated");
> +
> +  uselocale (loc_obj);
>  
>    wchar_t buf[32] = L"123";
>    int j;
> @@ -41,7 +44,7 @@ do_test (void)
>      FAIL_EXIT1 ("swscanf failed");
>  
>    /* Retrieve the current gconv_fcts from the LC_CTYPE locale data.  */
> -  struct __locale_data *loc = _NL_CURRENT_DATA (LC_CTYPE);
> +  struct __locale_data *loc = loc_obj->__locales[LC_CTYPE];
>    struct lc_ctype_data *ctype = loc->private;
>    const struct gconv_fcts *fcts = ctype->fcts;
>  
> @@ -51,6 +54,9 @@ do_test (void)
>    /* Capture the reference counter.  */
>    int initial_counter = fcts->towc->__counter;
>  
> +  if (fcts->towc->__shlib_handle == NULL)
> +    FAIL_EXIT1 ("__shlib_handle is NULL!");
> +
>    /* Perform a second iteration of swscanf. If the stack-allocated FILE
>       leaks the gconv reference, the counter will increment.  */
>    if (swscanf (buf, L"%d", &j) < 1)



More information about the Libc-alpha mailing list