[PATCH v4] string: Add tests for unique strerror and strsignal strings

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Wed Oct 1 11:56:03 GMT 2025



On 23/09/25 09:25, Adhemerval Zanella Netto wrote:
> 
> 
> On 23/09/25 09:11, Arjun Shankar wrote:
>> Hi Florian, Adhemerval,
>>
>>>>> Maybe derive from errlist.h by extending scripts/gen-as-const.py to
>>>>> build a TU similar to stdio-common/errlist-data-gen.c?
>>>>
>>>> Ah, so basically look at
>>>>
>>>>   echo '#include <linux/errno.h>'| gcc -E - -dM | grep '^#define E'
>>>>
>>>> and cross-check against the strerror functions?
>>>
>>> I think it can work, although I was think about using errlist.h to get the
>>> expected list built in libc.so.
>>
>> I know that it sounds kind of implausible that we might make an
>> erroneous change to errlist.h in the future. However, keeping the
>> test's behaviour independent of the list can help guard against the
>> test silently passing when the list is somehow updated incorrectly.
>> Does this sound reasonable? I'm going to think about how I can make
>> the test better here, instead of this hardcoded 160.
> 
> Right, but my understanding was this testcase aims to check uniqueness
> of errors strings and that it should at least check for the number of
> different error string glibc can return.
> 
> Testing more should be ok, since invalid inputs would return empty/NULL 
> string; but checking a number lower than string list makes the test invalid.
> 
> Can't you do something like:
> 
> const char *const _sys_errlist_internal[] __attribute_maybe_unused__ =
>   {
> #define _S(n, str)         [ERR_MAP(n)] = str,
> #include <errlist.h>
> #undef _S
>   };
> const size_t _sys_errlist_internal_len = array_length (_sys_errlist_internal);
> 
> And use _sys_errlist_internal_len? 

The following patch works to get the current internal errlist size, although
it ties the test to internal glibc machinery (it is an glibc test so it
is ok). 

Ideally I think we will need to more the errlist generation to the string
folder, so the test should not rely on including stdio-common.


iff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 973dcc3822..5dd122387c 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -729,4 +729,6 @@ tests += \
   tst-xsi-strerror_r-strings \
   # tests
 $(objpfx)tst-xsi-strerror_r-strings: $(objpfx)tst-xsi-strerror_r-mod.so
+
+CFLAGS-tst-strerror-strings.c += -I../stdio-common
 endif
diff --git a/sysdeps/unix/sysv/linux/tst-strerror-strings.c b/sysdeps/unix/sysv/linux/tst-strerror-strings.c
index 4bd0e4b0a8..377cbbe45e 100644
--- a/sysdeps/unix/sysv/linux/tst-strerror-strings.c
+++ b/sysdeps/unix/sysv/linux/tst-strerror-strings.c
@@ -17,6 +17,7 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */

+#include <array_length.h>
 #include <string.h>
 #include <stdlib.h>

@@ -25,20 +26,31 @@

 #include "tst-verify-unique-strings.c"

-#define NSTRINGS 2049
+#include <stdio.h>
+
+/* As defined by stdio-common/errlist-data-gen.c */
+#include <errno.h>
+#include <err_map.h>
+#define N_(msgid)      msgid
+const char *const errlist_internal[] __attribute_maybe_unused__ =
+  {
+#define _S(n, str)         [ERR_MAP(n)] = str,
+#include <errlist.h>
+#undef _S
+      };
+const int errlist_internal_len = array_length (errlist_internal);

 static int
 do_test (void)
 {
-  char *string[NSTRINGS];
-  /* Convenient indexing for error strings from -1024 to 1024.  */
-  char **err_str = string + 1024;
+  char *string[errlist_internal_len * 2];
+  char **err_str = string + errlist_internal_len;

   unsetenv ("LANGUAGE");

   xsetlocale (LC_ALL, "C");

-  for (int i = -1024; i <= 1024; i++)
+  for (int i = -errlist_internal_len; i <= errlist_internal_len; i++)
     {

 #ifdef TEST_STRERROR_VARIANT
@@ -48,17 +60,16 @@ do_test (void)
       err_str[i] = xstrdup (strerror (i));
 #endif

-      /* Negative as well as large positive errnums are unused.  160 allows
-         us to define more errors without needing to update this test.  */
       int is_unknown_error
         = (strstr (err_str[i], "Unknown error ") == err_str[i]);
-      TEST_VERIFY_EXIT ((i >= 0 && i < 160) || is_unknown_error);
+      TEST_VERIFY_EXIT ((i >= 0 && i < errlist_internal_len)
+                       || is_unknown_error);
     }

   /* We check for and fail on duplicate strings.  */
-  VERIFY_UNIQUE_STRINGS (string, NSTRINGS);
+  VERIFY_UNIQUE_STRINGS (string, errlist_internal_len);

-  for (int i = -1024; i <= 1024; i++)
+  for (int i = -errlist_internal_len; i <= errlist_internal_len; i++)
     free (err_str[i]);

   return 0;


More information about the Libc-alpha mailing list