[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