diff options
author | Roland McGrath <roland@gnu.org> | 2005-07-29 23:26:18 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2005-07-29 23:26:18 +0000 |
commit | d89f44d0b3c8cef1c0a19f09c26640b0f4fbb47e (patch) | |
tree | b281eeca737ee0b7ec3351ce55d6931ce86eb943 | |
parent | 999a76bfdb718e2e84106094d4ef8d0cba2653d4 (diff) | |
download | glibc-d89f44d0b3c8cef1c0a19f09c26640b0f4fbb47e.tar.gz glibc-d89f44d0b3c8cef1c0a19f09c26640b0f4fbb47e.tar.xz glibc-d89f44d0b3c8cef1c0a19f09c26640b0f4fbb47e.zip |
2005-07-19 Ulrich Drepper <drepper@redhat.com>
[BZ #1137] * misc/Makefile: Add rules to build and run tst-error1. * misc/tst-error1.c: New file. * misc/error.c: Fix memory leak and possibly endless loop.
-rw-r--r-- | misc/Makefile | 13 | ||||
-rw-r--r-- | misc/error.c | 34 | ||||
-rw-r--r-- | misc/tst-error1.c | 26 |
3 files changed, 66 insertions, 7 deletions
diff --git a/misc/Makefile b/misc/Makefile index 862eb1b800..b4c106c0cb 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -65,6 +65,8 @@ routines := brk sbrk sstk ioctl \ distribute := device-nrs.h +generated := tst-error1.mtrace tst-error1-mem + include ../Makeconfig aux := init-misc @@ -73,7 +75,11 @@ install-lib := libbsd-compat.a libg.a endif gpl2lgpl := error.c error.h -tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch +tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \ + tst-error1 +ifeq (no,$(cross-compiling)) +tests: $(objpfx)tst-error1-mem +endif CFLAGS-tsearch.c = $(uses-callbacks) CFLAGS-lsearch.c = $(uses-callbacks) @@ -106,3 +112,8 @@ endif ifeq ($(build-bounded),yes) $(objpfx)tst-tsearch-bp: $(common-objpfx)math/libm_b.a endif + +tst-error1-ENV = MALLOC_TRACE=$(objpfx)tst-error1.mtrace +tst-error1-ARGS = $(objpfx)tst-error1.out +$(objpfx)tst-error1-mem: $(objpfx)tst-error1.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-error1.mtrace > $@ diff --git a/misc/error.c b/misc/error.c index 2501583366..b608913fae 100644 --- a/misc/error.c +++ b/misc/error.c @@ -74,6 +74,7 @@ unsigned int error_message_count; # define program_name program_invocation_name # include <errno.h> +# include <limits.h> # include <libio/libioP.h> /* In GNU libc we want do not want to use the common name `error' directly. @@ -182,14 +183,15 @@ error_tail (int status, int errnum, const char *message, va_list args) mbstate_t st; size_t res; const char *tmp; + bool use_malloc = false; - do + while (1) { - if (len < ALLOCA_LIMIT) + if (__libc_use_alloca (len * sizeof (wchar_t))) wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); else { - if (wmessage != NULL && len / 2 < ALLOCA_LIMIT) + if (!use_malloc) wmessage = NULL; wchar_t *p = (wchar_t *) realloc (wmessage, @@ -201,18 +203,38 @@ error_tail (int status, int errnum, const char *message, va_list args) return; } wmessage = p; + use_malloc = true; } memset (&st, '\0', sizeof (st)); tmp = message; + + res = mbsrtowcs (wmessage, &tmp, len, &st); + if (res != len) + break; + + if (__builtin_expect (len >= SIZE_MAX / 2, 0)) + { + /* This really should not happen if everything is fine. */ + res = (size_t) -1; + break; + } + + len *= 2; } - while ((res = mbsrtowcs (wmessage, &tmp, len, &st)) == len); if (res == (size_t) -1) - /* The string cannot be converted. */ - wmessage = (wchar_t *) L"???"; + { + /* The string cannot be converted. */ + if (use_malloc) + free (wmessage); + wmessage = (wchar_t *) L"???"; + } __vfwprintf (stderr, wmessage, args); + + if (use_malloc) + free (wmessage); } else # endif diff --git a/misc/tst-error1.c b/misc/tst-error1.c new file mode 100644 index 0000000000..e84843ed2f --- /dev/null +++ b/misc/tst-error1.c @@ -0,0 +1,26 @@ +#include <error.h> +#include <mcheck.h> +#include <stdio.h> +#include <string.h> +#include <wchar.h> + +static int +do_test (int argc, char *argv[]) +{ + mtrace (); + (void) freopen (argc == 1 ? "/dev/stdout" : argv[1], "a", stderr); + /* Orient the stream. */ + fwprintf (stderr, L"hello world\n"); + char buf[20000]; + static const char str[] = "hello world! "; + for (int i = 0; i < 1000; ++i) + memcpy (&buf[i * (sizeof (str) - 1)], str, sizeof (str)); + error (0, 0, str); + error (0, 0, buf); + error (0, 0, buf); + error (0, 0, str); + return 0; +} + +#define TEST_FUNCTION do_test (argc, argv) +#include "../test-skeleton.c" |