[PATCH v2] assert: Refactor assert/assert_perror
Florian Weimer
fweimer@redhat.com
Mon Aug 18 14:01:00 GMT 2025
* Adhemerval Zanella:
> It now calls __libc_assert_message, which contains similar logic. The
> assert now does not require any dynamic memory allocation, so
> test-assert2.c is adapted to handle it.
>
> It also removes the fxprintf from assert/assert_perror; although it
> is not 100% backwards-compatible (write message only if there is a
> file descriptor associated with the stderr) it nows write bytes
> directly to without going through the wide stream state.
>
> Checked on aarch64-linux-gnu.
> --
> Changes from v1:
> * Setup the VMA properly.
> ---
> assert/__libc_assert_fail.c | 4 +-
> assert/assert-perr.c | 22 ++++++-
> assert/assert.c | 112 +++++-------------------------------
> assert/test-assert-2.c | 18 ++----
> include/stdio.h | 51 ++++++++++++----
> sysdeps/posix/libc_fatal.c | 4 +-
> 6 files changed, 82 insertions(+), 129 deletions(-)
>
> diff --git a/assert/__libc_assert_fail.c b/assert/__libc_assert_fail.c
> index b50637a893..2d4654bd41 100644
> --- a/assert/__libc_assert_fail.c
> +++ b/assert/__libc_assert_fail.c
> @@ -28,6 +28,6 @@ __libc_assert_fail (const char *assertion, const char *file, unsigned int line,
> char linebuf[INT_BUFSIZE_BOUND (unsigned int)];
> array_end (linebuf)[-1] = '\0';
> char *linestr = _itoa_word (line, array_end (linebuf) - 1, 10, 0);
> - __libc_message ("Fatal glibc error: %s:%s (%s): assertion failed: %s\n",
> - file, linestr, function, assertion);
> + __libc_assert_message ("Fatal glibc error: %s:%s (%s): assertion failed: %s\n",
> + file, linestr, function, assertion);
> }
I think we are aiming for 79 characters at maximum per line.
> diff --git a/include/stdio.h b/include/stdio.h
> index e48d709919..683b212d14 100644
> --- a/include/stdio.h
> +++ b/include/stdio.h
> @@ -171,33 +171,64 @@ extern void __fortify_fail (const char *msg) __attribute__ ((__noreturn__));
> libc_hidden_proto (__fortify_fail)
>
> /* The maximum number of varargs allowed in a __libc_message format string */
> -#define LIBC_MESSAGE_MAX_ARGS 4
> +#define LIBC_MESSAGE_MAX_ARGS 7
>
> -_Noreturn void __libc_message_impl (const char *__fnt, ...) attribute_hidden
> - __attribute__ ((__format__ (__printf__, 1, 2)));
> +_Noreturn void __libc_message_impl (const char *__vmaname, const char *__fmt,
> + ...) attribute_hidden
> + __attribute__ ((__format__ (__printf__, 2, 3)));
> +
> +#define __libc_fatal_vma_name "glibc: fatal"
> +#define __libc_assert_vma_name "glibc: assert"
>
> #define __libc_message0(fmt) \
> - __libc_message_impl (fmt)
> + __libc_message_impl (__libc_fatal_vma_name, fmt)
> #define __libc_message1(fmt, a1) \
> - __libc_message_impl (fmt, a1)
> + __libc_message_impl (__libc_fatal_vma_name, fmt, a1)
> #define __libc_message2(fmt, a1, a2) \
> - __libc_message_impl (fmt, a1, a2)
> + __libc_message_impl (__libc_fatal_vma_name, fmt, a1, a2)
> #define __libc_message3(fmt, a1, a2, a3) \
> - __libc_message_impl (fmt, a1, a2, a3)
> + __libc_message_impl (__libc_fatal_vma_name, fmt, a1, a2, a3)
> #define __libc_message4(fmt, a1, a2, a3, a4) \
> - __libc_message_impl (fmt, a1, a2, a3, a4)
> + __libc_message_impl (__libc_fatal_vma_name, fmt, a1, a2, a3, a4)
> +#define __libc_message5(fmt, a1, a2, a3, a4, a5) \
> + __libc_message_impl (__libc_fatal_vma_name, fmt, a1, a2, a3, a4, a5)
> +#define __libc_message6(fmt, a1, a2, a3, a4, a5, a6) \
> + __libc_message_impl (__libc_fatal_vma_name, fmt, a1, a2, a3, a4, a5, a6)
> +#define __libc_message7(fmt, a1, a2, a3, a4, a5, a6, a7) \
> + __libc_message_impl (__libc_fatal_vma_name, fmt, a1, a2, a3, a4, a5, a6, a7)
> +
> +#define __libc_assert_message0(fmt) \
> + __libc_message_impl (__libc_assert_vma_name, fmt)
> +#define __libc_assert_message1(fmt, a1) \
> + __libc_message_impl (__libc_assert_vma_name, fmt, a1)
> +#define __libc_assert_message2(fmt, a1, a2) \
> + __libc_message_impl (__libc_assert_vma_name, fmt, a1, a2)
> +#define __libc_assert_message3(fmt, a1, a2, a3) \
> + __libc_message_impl (__libc_assert_vma_name, fmt, a1, a2, a3)
> +#define __libc_assert_message4(fmt, a1, a2, a3, a4) \
> + __libc_message_impl (__libc_assert_vma_name, fmt, a1, a2, a3, a4)
> +#define __libc_assert_message5(fmt, a1, a2, a3, a4, a5) \
> + __libc_message_impl (__libc_assert_vma_name, fmt, a1, a2, a3, a4, a5)
> +#define __libc_assert_message6(fmt, a1, a2, a3, a4, a5, a6) \
> + __libc_message_impl (__libc_assert_vma_name, fmt, a1, a2, a3, a4, a5, a6)
> +#define __libc_assert_message7(fmt, a1, a2, a3, a4, a5, a6, a7) \
> + __libc_message_impl (__libc_assert_vma_name, fmt, a1, a2, a3, a4, a5, a6, a7)
>
> #define __libc_message_concat_x(a,b) a##b
> #define __libc_message_concat(a,b) __libc_message_concat_x (a, b)
>
> -#define __libc_message_nargs_x(a0,a1,a2,a3,a4,a5,a6,...) a6
> +#define __libc_message_nargs_x(a0,a1,a2,a3,a4,a5,a6,a7,...) a7
> #define __libc_message_nargs(b, ...) \
> - __libc_message_nargs_x (__VA_ARGS__,6,5,4,3,2,1,0,)
> + __libc_message_nargs_x (__VA_ARGS__,7,6,5,4,3,2,1,0,)
> #define __libc_message_disp(b, ...) \
> __libc_message_concat (b, __libc_message_nargs (__VA_ARGS__))(__VA_ARGS__)
Why do we need __libc_message_nargs when things go into a varargs
function without an explicit argument count in the end anyway?
The patch no longer applies to the main branch.
Thanks,
Florian
More information about the Libc-alpha
mailing list