diff options
author | Jakub Jelinek <jakub@redhat.com> | 2004-11-15 09:47:23 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2004-11-15 09:47:23 +0000 |
commit | b3c20a361d75caf75f670b2fcd64ab8668c16ca5 (patch) | |
tree | cac006e13628dcbf5a48cb618417ae708906db89 | |
parent | 87ffc9aca119436c8530d6605483a49cfb16668e (diff) | |
download | glibc-b3c20a361d75caf75f670b2fcd64ab8668c16ca5.tar glibc-b3c20a361d75caf75f670b2fcd64ab8668c16ca5.tar.gz glibc-b3c20a361d75caf75f670b2fcd64ab8668c16ca5.tar.bz2 glibc-b3c20a361d75caf75f670b2fcd64ab8668c16ca5.zip |
Updated to fedora-glibc-20041115T0915
-rw-r--r-- | ChangeLog | 51 | ||||
-rw-r--r-- | debug/chk_fail.c | 18 | ||||
-rw-r--r-- | debug/test-strcpy_chk.c | 36 | ||||
-rw-r--r-- | debug/tst-chk1.c | 16 | ||||
-rw-r--r-- | elf/elf.h | 7 | ||||
-rw-r--r-- | elf/rtld.c | 20 | ||||
-rw-r--r-- | fedora/branch.mk | 4 | ||||
-rw-r--r-- | fedora/glibc.spec.in | 7 | ||||
-rw-r--r-- | include/stdio.h | 2 | ||||
-rw-r--r-- | malloc/malloc.c | 354 | ||||
-rw-r--r-- | nis/ypclnt.c | 2 | ||||
-rw-r--r-- | posix/Makefile | 1 | ||||
-rw-r--r-- | sysdeps/posix/libc_fatal.c | 125 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/libc_fatal.c | 144 |
14 files changed, 501 insertions, 286 deletions
@@ -1,3 +1,43 @@ +2004-11-13 Ulrich Drepper <drepper@redhat.com> + + * malloc/malloc.c (malloc_state): stat_lock_* elements need only + be defined if THREAD_STATS is defined. Remove pad0_ since it does + not align with cache line sizes in general anyway. + +2004-11-13 Jakub Jelinek <jakub@redhat.com> + + * elf/rtld.c (print_statistics): Avoid segfaults if not all namespaces + are used. Fix computation of num_relative_relocations on RELA + architectures other than IA-64 and Alpha. + +2004-11-13 Ulrich Drepper <drepper@redhat.com> + + * malloc/malloc.c (_int_free): Use munmap_chunk for handling + mmaped memory. + +2004-11-12 Ulrich Drepper <drepper@redhat.com> + + * malloc/malloc.c (_int_free): Remove test for NULL parameter. + (_int_realloc): Call _int_free only if memory parameter is not NULL. + + * sysdeps/unix/sysv/linux/libc_fatal.c: Add new function __libc_message + which performs the printing and simple format string handling. The + string is written to tty, stderr, syslog in this order, stopping after + the first successful output. + (__libc_fatal): Call __libc_message. + * include/stdio.h: Declare __libc_message. + * malloc/malloc.c (malloc_printerr): Use __libc_message. + * debug/chk_fail.c: Also print message with __libc_message. + * debug/test-strcpy_chk.c: Ensure that debug messages are not printed + to the terminal or stderr. + * debug/tst-chk1.c: Likewise. + + * posix/Makefile: Remove gpl2lgpl variable. + +2004-11-12 Martin Schwidefsky <schwidefsky@de.ibm.com> + + * elf/elf.h: Add 20 bit relocations R_390_*20. + 2004-11-12 Jakub Jelinek <jakub@redhat.com> * sysdeps/unix/sysv/linux/i386/setuid.c: Include linux/posix_types.h. @@ -7,16 +47,9 @@ * sysdeps/unix/sysv/linux/i386/setresuid.c: Likewise. * sysdeps/unix/sysv/linux/i386/setresgid.c: Likewise. -2004-11-11 Jakub Jelinek <jakub@redhat.com> +2004-11-12 Andreas Schwab <schwab@suse.de> - * debug/chk_fail.c: Include errno.h and string.h. - (__chk_fail): Write a short message to stderr. - * debug/tst-chk1.c: Include fcntl.h. - (do_test): Redirect stderr to /dev/null. - * debug/test-strcpy_chk.c: Include fcntl.h. - (test_main): Redirect stderr to /dev/null. - (do_one_test, do_random_tests): Use printf instead of - error. + * nis/ypclnt.c (ypprot_err): Fix "minor optimizations". 2004-11-12 Ulrich Drepper <drepper@redhat.com> diff --git a/debug/chk_fail.c b/debug/chk_fail.c index 70ffa9e40f..dc1c3d70b6 100644 --- a/debug/chk_fail.c +++ b/debug/chk_fail.c @@ -1,3 +1,4 @@ + /* Copyright (C) 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -16,27 +17,14 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <errno.h> +#include <stdio.h> #include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <abort-instr.h> void __attribute__ ((noreturn)) __chk_fail (void) { - while (1) - { - const char *text = "*** buffer overflow detected ***\n"; - TEMP_FAILURE_RETRY (write (STDERR_FILENO, text, strlen (text))); - /* This will leave a nice backtrace. */ - abort (); -#ifdef ABORT_INSTRUCTION - ABORT_INSTRUCTION; -#endif - _exit (127); - } + __libc_fatal ("*** buffer overflow detected ***\n"); } libc_hidden_def (__chk_fail) diff --git a/debug/test-strcpy_chk.c b/debug/test-strcpy_chk.c index 8430ca4704..ac9f9448cf 100644 --- a/debug/test-strcpy_chk.c +++ b/debug/test-strcpy_chk.c @@ -46,9 +46,10 @@ simple_strcpy_chk (char *dst, const char *src, size_t len) } #endif +#include <fcntl.h> +#include <paths.h> #include <setjmp.h> #include <signal.h> -#include <fcntl.h> volatile int chk_fail_ok; jmp_buf chk_fail_buf; @@ -81,8 +82,8 @@ do_one_test (impl_t *impl, char *dst, const char *src, if (setjmp (chk_fail_buf) == 0) { res = CALL (impl, dst, src, dlen); - printf ("*** Function %s (%zd; %zd) did not __chk_fail", - impl->name, len, dlen); + printf ("*** Function %s (%zd; %zd) did not __chk_fail\n", + impl->name, len, dlen); chk_fail_ok = 0; ret = 1; } @@ -93,7 +94,7 @@ do_one_test (impl_t *impl, char *dst, const char *src, if (res != STRCPY_RESULT (dst, len)) { - printf ("*** Wrong result in function %s %p %p", impl->name, + printf ("Wrong result in function %s %p %p\n", impl->name, res, STRCPY_RESULT (dst, len)); ret = 1; return; @@ -101,7 +102,7 @@ do_one_test (impl_t *impl, char *dst, const char *src, if (strcmp (dst, src) != 0) { - printf ("*** Wrong result in function %s dst \"%s\" src \"%s\"", + printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n", impl->name, dst, src); ret = 1; return; @@ -233,7 +234,7 @@ do_random_tests (void) if (setjmp (chk_fail_buf) == 0) { res = CALL (impl, p2 + align2, p1 + align1, dlen); - printf ("*** Iteration %zd - did not __chk_fail", n); + printf ("Iteration %zd - did not __chk_fail\n", n); chk_fail_ok = 0; ret = 1; } @@ -244,7 +245,8 @@ do_random_tests (void) res = CALL (impl, p2 + align2, p1 + align1, dlen); if (res != STRCPY_RESULT (p2 + align2, len)) { - printf ("*** Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p", + printf ("\ +Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p\n", n, impl->name, align1, align2, len, res, STRCPY_RESULT (p2 + align2, len)); ret = 1; @@ -253,7 +255,8 @@ do_random_tests (void) { if (p2[j - 64] != '\1') { - printf ("*** Iteration %zd - garbage before, %s (%zd, %zd, %zd)", + printf ("\ +Iteration %zd - garbage before, %s (%zd, %zd, %zd)\n", n, impl->name, align1, align2, len); ret = 1; break; @@ -263,7 +266,8 @@ do_random_tests (void) { if (p2[j] != '\1') { - printf ("*** Iteration %zd - garbage after, %s (%zd, %zd, %zd)", + printf ("\ +Iteration %zd - garbage after, %s (%zd, %zd, %zd)\n", n, impl->name, align1, align2, len); ret = 1; break; @@ -271,7 +275,8 @@ do_random_tests (void) } if (memcmp (p1 + align1, p2 + align2, len + 1)) { - printf ("*** Iteration %zd - different strings, %s (%zd, %zd, %zd)", + printf ("\ +Iteration %zd - different strings, %s (%zd, %zd, %zd)\n", n, impl->name, align1, align2, len); ret = 1; } @@ -292,8 +297,15 @@ test_main (void) sigaction (SIGABRT, &sa, NULL); /* Avoid all the buffer overflow messages on stderr. */ - close (STDERR_FILENO); - open ("/dev/null", O_WRONLY); + int fd = open (_PATH_DEVNULL, O_WRONLY); + if (fd == -1) + close (STDERR_FILENO); + else + { + dup2 (fd, STDERR_FILENO); + close (fd); + } + setenv ("LIBC_FATAL_STDERR_", "1", 1); test_init (); diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c index e01284ae53..37320c3514 100644 --- a/debug/tst-chk1.c +++ b/debug/tst-chk1.c @@ -18,6 +18,7 @@ 02111-1307 USA. */ #include <fcntl.h> +#include <paths.h> #include <setjmp.h> #include <signal.h> #include <stdio.h> @@ -108,8 +109,15 @@ do_test (void) sigaction (SIGABRT, &sa, NULL); /* Avoid all the buffer overflow messages on stderr. */ - close (STDERR_FILENO); - open ("/dev/null", O_WRONLY); + int fd = open (_PATH_DEVNULL, O_WRONLY); + if (fd == -1) + close (STDERR_FILENO); + else + { + dup2 (fd, STDERR_FILENO); + close (fd); + } + setenv ("LIBC_FATAL_STDERR_", "1", 1); struct A { char buf1[9]; char buf2[1]; } a; @@ -205,7 +213,7 @@ do_test (void) if (memcmp (a.buf1, "aabcdabcjj", 10)) FAIL (); -#if __USE_FORTIFY_LEVEL < 2 || !__GNUC_PREREQ (4, 0) +#if __USE_FORTIFY_LEVEL < 2 /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2 and sufficient GCC support, as the string operations overflow from a.buf1 into a.buf2. */ @@ -304,7 +312,7 @@ do_test (void) memset (a.buf1 + 9, 'j', l0 + 2); CHK_FAIL_END -#if __USE_FORTIFY_LEVEL >= 2 && __GNUC_PREREQ (4, 0) +#if __USE_FORTIFY_LEVEL >= 2 # define O 0 #else # define O 1 @@ -2402,8 +2402,13 @@ typedef Elf32_Addr Elf32_Conflict; #define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ #define R_390_TLS_TPOFF 56 /* Negated offset in static TLS block. */ +#define R_390_20 57 /* Direct 20 bit. */ +#define R_390_GOT20 58 /* 20 bit GOT offset. */ +#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ +#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS + block offset. */ /* Keep this the last entry. */ -#define R_390_NUM 57 +#define R_390_NUM 61 /* CRIS relocations. */ diff --git a/elf/rtld.c b/elf/rtld.c index e53273c2bb..e442aa257f 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -2444,19 +2444,29 @@ print_statistics (hp_timing_t *rtld_total_timep) unsigned long int num_relative_relocations = 0; for (Lmid_t ns = 0; ns < DL_NNS; ++ns) { + if (GL(dl_ns)[ns]._ns_loaded == NULL) + continue; + struct r_scope_elem *scope = &GL(dl_ns)[ns]._ns_loaded->l_searchlist; for (unsigned int i = 0; i < scope->r_nlist; i++) { struct link_map *l = scope->r_list [i]; - if (!l->l_addr) - continue; - - if (l->l_info[VERSYMIDX (DT_RELCOUNT)]) + if (l->l_addr != 0 && l->l_info[VERSYMIDX (DT_RELCOUNT)]) num_relative_relocations += l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val; - if (l->l_info[VERSYMIDX (DT_RELACOUNT)]) +#ifndef ELF_MACHINE_REL_RELATIVE + /* Relative relocations are processed on these architectures if + library is loaded to different address than p_vaddr or + if not prelinked. */ + if ((l->l_addr != 0 || !l->l_info[VALIDX(DT_GNU_PRELINKED)]) + && l->l_info[VERSYMIDX (DT_RELACOUNT)]) +#else + /* On e.g. IA-64 or Alpha, relative relocations are processed + only if library is loaded to different address than p_vaddr. */ + if (l->l_addr != 0 && l->l_info[VERSYMIDX (DT_RELACOUNT)]) +#endif num_relative_relocations += l->l_info[VERSYMIDX (DT_RELACOUNT)]->d_un.d_val; } diff --git a/fedora/branch.mk b/fedora/branch.mk index 2714ad4822..3add7920d6 100644 --- a/fedora/branch.mk +++ b/fedora/branch.mk @@ -1,5 +1,5 @@ # This file is updated automatically by Makefile. glibc-branch := fedora glibc-base := HEAD -fedora-sync-date := 2004-11-12 16:40 UTC -fedora-sync-tag := fedora-glibc-20041112T1640 +fedora-sync-date := 2004-11-15 09:15 UTC +fedora-sync-tag := fedora-glibc-20041115T0915 diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in index 0d97316b37..1c93fc1e0b 100644 --- a/fedora/glibc.spec.in +++ b/fedora/glibc.spec.in @@ -1,4 +1,4 @@ -%define glibcrelease 77 +%define glibcrelease 78 %define auxarches i586 i686 athlon sparcv9 alphaev6 %define prelinkarches noarch %define nptlarches i386 i686 athlon x86_64 ia64 s390 s390x sparcv9 ppc ppc64 @@ -1256,6 +1256,11 @@ rm -f *.filelist* %endif %changelog +* Mon Nov 15 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-78 +- update from CVS + - issue error message before aborting in __chk_fail () + - some more free () checking + * Fri Nov 12 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-77 - update from CVS - speedup regex on palindromes (BZ #429) diff --git a/include/stdio.h b/include/stdio.h index 05a91b4cb3..ad8f157829 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -62,6 +62,8 @@ extern int __gen_tempname (char *__tmpl, int __kind); /* Print out MESSAGE on the error output and abort. */ extern void __libc_fatal (__const char *__message) __attribute__ ((__noreturn__)); +extern void __libc_message (int do_abort, __const char *__fnt, ...) + __attribute__ ((__noreturn__)); /* Acquire ownership of STREAM. */ extern void __flockfile (FILE *__stream); diff --git a/malloc/malloc.c b/malloc/malloc.c index 6d6294c6e6..57074108f1 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -2192,10 +2192,12 @@ typedef struct malloc_chunk* mfastbinptr; struct malloc_state { /* Serialize access. */ mutex_t mutex; + // Should we have padding to move the mutex to its own cache line? +#if THREAD_STATS /* Statistics for locking. Only used if THREAD_STATS is defined. */ long stat_lock_direct, stat_lock_loop, stat_lock_wait; - long pad0_[1]; /* try to give the mutex its own cacheline */ +#endif /* The maximum chunk size to be eligible for fastbin */ INTERNAL_SIZE_T max_fast; /* low 2 bits used as flags */ @@ -4196,191 +4198,182 @@ _int_free(mstate av, Void_t* mem) mchunkptr fwd; /* misc temp for linking */ - /* free(0) has no effect */ - if (mem != 0) { - const char *errstr = NULL; + const char *errstr = NULL; - p = mem2chunk(mem); - size = chunksize(p); + p = mem2chunk(mem); + size = chunksize(p); - /* Little security check which won't hurt performance: the - allocator never wrapps around at the end of the address space. - Therefore we can exclude some size values which might appear - here by accident or by "design" from some intruder. */ - if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0)) - { - errstr = "free(): invalid pointer"; - errout: - malloc_printerr (check_action, errstr, mem); - return; - } + /* Little security check which won't hurt performance: the + allocator never wrapps around at the end of the address space. + Therefore we can exclude some size values which might appear + here by accident or by "design" from some intruder. */ + if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0)) + { + errstr = "free(): invalid pointer"; + errout: + malloc_printerr (check_action, errstr, mem); + return; + } - check_inuse_chunk(av, p); + check_inuse_chunk(av, p); - /* - If eligible, place chunk on a fastbin so it can be found - and used quickly in malloc. - */ + /* + If eligible, place chunk on a fastbin so it can be found + and used quickly in malloc. + */ - if ((unsigned long)(size) <= (unsigned long)(av->max_fast) + if ((unsigned long)(size) <= (unsigned long)(av->max_fast) #if TRIM_FASTBINS - /* - If TRIM_FASTBINS set, don't place chunks - bordering top into fastbins - */ - && (chunk_at_offset(p, size) != av->top) -#endif - ) { - - set_fastchunks(av); - fb = &(av->fastbins[fastbin_index(size)]); - /* Another simple check: make sure the top of the bin is not the - record we are going to add (i.e., double free). */ - if (__builtin_expect (*fb == p, 0)) - { - errstr = "double free or corruption (fasttop)"; - goto errout; - } - p->fd = *fb; - *fb = p; - } - - /* - Consolidate other non-mmapped chunks as they arrive. - */ + /* + If TRIM_FASTBINS set, don't place chunks + bordering top into fastbins + */ + && (chunk_at_offset(p, size) != av->top) +#endif + ) { - else if (!chunk_is_mmapped(p)) { - nextchunk = chunk_at_offset(p, size); + set_fastchunks(av); + fb = &(av->fastbins[fastbin_index(size)]); + /* Another simple check: make sure the top of the bin is not the + record we are going to add (i.e., double free). */ + if (__builtin_expect (*fb == p, 0)) + { + errstr = "double free or corruption (fasttop)"; + goto errout; + } + p->fd = *fb; + *fb = p; + } - /* Lightweight tests: check whether the block is already the - top block. */ - if (__builtin_expect (p == av->top, 0)) - { - errstr = "double free or corruption (top)"; - goto errout; - } - /* Or whether the next chunk is beyond the boundaries of the arena. */ - if (__builtin_expect (contiguous (av) - && (char *) nextchunk - >= ((char *) av->top + chunksize(av->top)), 0)) - { - errstr = "double free or corruption (out)"; - goto errout; - } - /* Or whether the block is actually not marked used. */ - if (__builtin_expect (!prev_inuse(nextchunk), 0)) - { - errstr = "double free or corruption (!prev)"; - goto errout; - } + /* + Consolidate other non-mmapped chunks as they arrive. + */ - nextsize = chunksize(nextchunk); - assert(nextsize > 0); + else if (!chunk_is_mmapped(p)) { + nextchunk = chunk_at_offset(p, size); - /* consolidate backward */ - if (!prev_inuse(p)) { - prevsize = p->prev_size; - size += prevsize; - p = chunk_at_offset(p, -((long) prevsize)); - unlink(p, bck, fwd); + /* Lightweight tests: check whether the block is already the + top block. */ + if (__builtin_expect (p == av->top, 0)) + { + errstr = "double free or corruption (top)"; + goto errout; + } + /* Or whether the next chunk is beyond the boundaries of the arena. */ + if (__builtin_expect (contiguous (av) + && (char *) nextchunk + >= ((char *) av->top + chunksize(av->top)), 0)) + { + errstr = "double free or corruption (out)"; + goto errout; + } + /* Or whether the block is actually not marked used. */ + if (__builtin_expect (!prev_inuse(nextchunk), 0)) + { + errstr = "double free or corruption (!prev)"; + goto errout; } - if (nextchunk != av->top) { - /* get and clear inuse bit */ - nextinuse = inuse_bit_at_offset(nextchunk, nextsize); - - /* consolidate forward */ - if (!nextinuse) { - unlink(nextchunk, bck, fwd); - size += nextsize; - } else - clear_inuse_bit_at_offset(nextchunk, 0); - - /* - Place the chunk in unsorted chunk list. Chunks are - not placed into regular bins until after they have - been given one chance to be used in malloc. - */ + nextsize = chunksize(nextchunk); + assert(nextsize > 0); - bck = unsorted_chunks(av); - fwd = bck->fd; - p->bk = bck; - p->fd = fwd; - bck->fd = p; - fwd->bk = p; + /* consolidate backward */ + if (!prev_inuse(p)) { + prevsize = p->prev_size; + size += prevsize; + p = chunk_at_offset(p, -((long) prevsize)); + unlink(p, bck, fwd); + } - set_head(p, size | PREV_INUSE); - set_foot(p, size); + if (nextchunk != av->top) { + /* get and clear inuse bit */ + nextinuse = inuse_bit_at_offset(nextchunk, nextsize); - check_free_chunk(av, p); - } + /* consolidate forward */ + if (!nextinuse) { + unlink(nextchunk, bck, fwd); + size += nextsize; + } else + clear_inuse_bit_at_offset(nextchunk, 0); /* - If the chunk borders the current high end of memory, - consolidate into top + Place the chunk in unsorted chunk list. Chunks are + not placed into regular bins until after they have + been given one chance to be used in malloc. */ - else { - size += nextsize; - set_head(p, size | PREV_INUSE); - av->top = p; - check_chunk(av, p); - } + bck = unsorted_chunks(av); + fwd = bck->fd; + p->bk = bck; + p->fd = fwd; + bck->fd = p; + fwd->bk = p; - /* - If freeing a large space, consolidate possibly-surrounding - chunks. Then, if the total unused topmost memory exceeds trim - threshold, ask malloc_trim to reduce top. - - Unless max_fast is 0, we don't know if there are fastbins - bordering top, so we cannot tell for sure whether threshold - has been reached unless fastbins are consolidated. But we - don't want to consolidate on each free. As a compromise, - consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD - is reached. - */ + set_head(p, size | PREV_INUSE); + set_foot(p, size); + + check_free_chunk(av, p); + } + + /* + If the chunk borders the current high end of memory, + consolidate into top + */ - if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) { - if (have_fastchunks(av)) - malloc_consolidate(av); + else { + size += nextsize; + set_head(p, size | PREV_INUSE); + av->top = p; + check_chunk(av, p); + } - if (av == &main_arena) { + /* + If freeing a large space, consolidate possibly-surrounding + chunks. Then, if the total unused topmost memory exceeds trim + threshold, ask malloc_trim to reduce top. + + Unless max_fast is 0, we don't know if there are fastbins + bordering top, so we cannot tell for sure whether threshold + has been reached unless fastbins are consolidated. But we + don't want to consolidate on each free. As a compromise, + consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD + is reached. + */ + + if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) { + if (have_fastchunks(av)) + malloc_consolidate(av); + + if (av == &main_arena) { #ifndef MORECORE_CANNOT_TRIM - if ((unsigned long)(chunksize(av->top)) >= - (unsigned long)(mp_.trim_threshold)) - sYSTRIm(mp_.top_pad, av); + if ((unsigned long)(chunksize(av->top)) >= + (unsigned long)(mp_.trim_threshold)) + sYSTRIm(mp_.top_pad, av); #endif - } else { - /* Always try heap_trim(), even if the top chunk is not - large, because the corresponding heap might go away. */ - heap_info *heap = heap_for_ptr(top(av)); + } else { + /* Always try heap_trim(), even if the top chunk is not + large, because the corresponding heap might go away. */ + heap_info *heap = heap_for_ptr(top(av)); - assert(heap->ar_ptr == av); - heap_trim(heap, mp_.top_pad); - } + assert(heap->ar_ptr == av); + heap_trim(heap, mp_.top_pad); } - } - /* - If the chunk was allocated via mmap, release via munmap(). Note - that if HAVE_MMAP is false but chunk_is_mmapped is true, then - user must have overwritten memory. There's nothing we can do to - catch this error unless MALLOC_DEBUG is set, in which case - check_inuse_chunk (above) will have triggered error. - */ - else { + } + /* + If the chunk was allocated via mmap, release via munmap(). Note + that if HAVE_MMAP is false but chunk_is_mmapped is true, then + user must have overwritten memory. There's nothing we can do to + catch this error unless MALLOC_DEBUG is set, in which case + check_inuse_chunk (above) will have triggered error. + */ + + else { #if HAVE_MMAP - int ret; - INTERNAL_SIZE_T offset = p->prev_size; - mp_.n_mmaps--; - mp_.mmapped_mem -= (size + offset); - ret = munmap((char*)p - offset, size + offset); - /* munmap returns non-zero on failure */ - assert(ret == 0); + munmap_chunk (p); #endif - } } } @@ -4528,7 +4521,8 @@ _int_realloc(mstate av, Void_t* oldmem, size_t bytes) #if REALLOC_ZERO_BYTES_FREES if (bytes == 0) { - _int_free(av, oldmem); + if (oldmem != 0) + _int_free(av, oldmem); return 0; } #endif @@ -5474,45 +5468,19 @@ malloc_printerr(int action, const char *str, void *ptr) { if (action & 1) { - /* output string will be ": ADDR ***\n" */ - static const char suffix[] = " ***\n"; - static const char prefix[] = ": 0x"; - char buf[sizeof (prefix) - 1 + sizeof (void *) * 2 + sizeof (suffix)]; - char *cp; - if (action & 4) - cp = memcpy (&buf[sizeof (buf) - 2], "\n", 2); - else - { - cp = memcpy (&buf[sizeof (buf) - sizeof (suffix)], suffix, - sizeof (suffix)); - cp = _itoa_word ((unsigned long int) ptr, cp, 16, 0); - while (cp > &buf[sizeof (prefix) - 1]) - *--cp = '0'; - cp = memcpy (buf, prefix, sizeof (prefix) - 1); - } + char buf[2 * sizeof (uintptr_t) + 1]; - struct iovec iov[3]; - int n = 0; - if ((action & 4) == 0) - { - iov[0].iov_base = (char *) "*** glibc detected *** "; - iov[0].iov_len = strlen (iov[0].iov_base); - ++n; - } - iov[n].iov_base = (char *) str; - iov[n].iov_len = strlen (str); - ++n; - iov[n].iov_base = cp; - iov[n].iov_len = &buf[sizeof (buf) - 1] - cp; - ++n; - if (TEMP_FAILURE_RETRY (__writev (STDERR_FILENO, iov, n)) == -1 - && errno == EBADF) - /* Standard error is not opened. Try using syslog. */ - syslog (LOG_ERR, "%s%s%s", (char *) iov[0].iov_base, - (char *) iov[1].iov_base, - n == 3 ? (const char *) iov[2].iov_base : ""); + buf[sizeof (buf) - 1] = '\0'; + char *cp = _itoa_word ((uintptr_t) ptr, &buf[sizeof (buf) - 1], 16, 0); + while (cp > buf) + *--cp = '0'; + + __libc_message (action & 2, + action & 4 + ? "%s\n" : "*** glibc detected *** %s: 0x%s ***\n", + str, cp); } - if (action & 2) + else if (action & 2) abort (); } diff --git a/nis/ypclnt.c b/nis/ypclnt.c index 65b9c55467..5ad78eda00 100644 --- a/nis/ypclnt.c +++ b/nis/ypclnt.c @@ -846,7 +846,7 @@ ypprot_err (const int code) { if (code < YP_VERS || code > YP_NOKEY) return YPERR_YPERR; - return yp_2_yperr[code]; + return yp_2_yperr[code - YP_VERS]; } libnsl_hidden_def (ypprot_err) diff --git a/posix/Makefile b/posix/Makefile index 8bc15ad215..744f49f5b3 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -91,7 +91,6 @@ tests += wordexp-test tst-exec tst-spawn endif others := getconf install-bin := getconf -gpl2lgpl := getopt.c getopt1.c getopt.h regex.c regex.h before-compile := testcases.h ptestcases.h diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c index 7e45174708..fac8cbd051 100644 --- a/sysdeps/posix/libc_fatal.c +++ b/sysdeps/posix/libc_fatal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1994, 1995, 1997, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1993,1994,1995,1997,2000,2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,44 +16,131 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <stdarg.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <sysdep.h> #include <string.h> +#include <sysdep.h> +#include <unistd.h> +#include <sys/syslog.h> +#include <not-cancel.h> #ifdef FATAL_PREPARE_INCLUDE #include FATAL_PREPARE_INCLUDE #endif +struct str_list +{ + const char *str; + size_t len; + struct str_list *next; +}; + + /* Abort with an error message. */ void -__libc_fatal (message) - const char *message; +__libc_message (int do_abort, const char *fmt, ...) { - size_t len = strlen (message); + va_list ap; + va_list ap_copy; + int fd = -1; + + va_start (ap, fmt); + va_copy (ap_copy, ap); #ifdef FATAL_PREPARE FATAL_PREPARE; #endif - while (len > 0) + /* Open a descriptor for /dev/tty unless the user explicitly + requests errors on standard error. */ + const char *on_2 = __secure_getenv ("LIBC_FATAL_STDERR_"); + if (on_2 == NULL || *on_2 == '\0') + fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY); + + if (fd == -1) + fd = STDERR_FILENO; + + struct str_list *list = NULL; + int nlist = 0; + + const char *cp = fmt; + while (*cp != '\0') { - register int count = __write (STDERR_FILENO, message, len); - if (count > 0) + /* Find the next "%s" or the end of the string. */ + char *next = cp; + while (next[0] != '%' || next[1] != 's') { - message += count; - len -= count; + next = __strchrnul (next + 1, '%'); + + if (next[0] == '\0') + break; } - else if (count < 0 -#ifdef EINTR - && errno != EINTR -#endif - ) - break; + + /* Determine what to print. */ + const char *str; + size_t len; + if (cp[0] == '%' && cp[1] == 's') + { + str = va_arg (ap, const char *); + len = strlen (str); + cp += 2; + } + else + { + str = cp; + len = next - cp; + cp = next; + } + + struct str_list *newp = alloca (sizeof (struct str_list)); + newp->str = str; + newp->len = len; + newp->next = list; + list = newp; + ++nlist; + } + + bool written = false; + if (nlist > 0) + { + struct iovec *iov = alloca (nlist * sizeof (struct iovec)); + ssize_t total = 0; + + for (int cnt = nlist - 1; cnt >= 0; --cnt) + { + iov[cnt].iov_base = list->str; + iov[cnt].iov_len = list->len; + total += list->len; + list = list->next; + } + + if (TEMP_FAILURE_RETRY (__writev (fd, iov, nlist)) == total) + written = true; } - abort (); + va_end (ap); + + /* If we had no success writing the message, use syslog. */ + if (! written) + vsyslog (LOG_ERR, fmt, ap_copy); + + va_end (ap_copy); + + if (do_abort() + /* Kill the application. */ + abort (); +} + + +void +__libc_fatal (message) + const char *message; +{ + __libc_message (1, "%s", message); } libc_hidden_def (__libc_fatal) diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c index 46347bb20e..c0482d96f3 100644 --- a/sysdeps/unix/sysv/linux/libc_fatal.c +++ b/sysdeps/unix/sysv/linux/libc_fatal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-1995,1997,2000,2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1993-1995,1997,2000,2002-2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,45 +16,143 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <sysdep.h> #include <string.h> -#include <abort-instr.h> +#include <sysdep.h> +#include <unistd.h> +#include <sys/syslog.h> #ifndef ABORT_INSTRUCTION /* No such instruction is available. */ # define ABORT_INSTRUCTION #endif /* Abort with an error message. */ +#include <not-cancel.h> + +#ifdef FATAL_PREPARE_INCLUDE +#include FATAL_PREPARE_INCLUDE +#endif + +struct str_list +{ + const char *str; + size_t len; + struct str_list *next; +}; + + +/* Abort with an error message. */ void -__libc_fatal (message) - const char *message; +__libc_message (int do_abort, const char *fmt, ...) { - size_t len = strlen (message); + va_list ap; + va_list ap_copy; + int fd = -1; + + va_start (ap, fmt); + va_copy (ap_copy, ap); + +#ifdef FATAL_PREPARE + FATAL_PREPARE; +#endif - while (len > 0) + /* Open a descriptor for /dev/tty unless the user explicitly + requests errors on standard error. */ + const char *on_2 = __secure_getenv ("LIBC_FATAL_STDERR_"); + if (on_2 == NULL || *on_2 == '\0') + fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY); + + if (fd == -1) + fd = STDERR_FILENO; + + struct str_list *list = NULL; + int nlist = 0; + + const char *cp = fmt; + while (*cp != '\0') { - INTERNAL_SYSCALL_DECL (err); - ssize_t count = INTERNAL_SYSCALL (write, err, 3, STDERR_FILENO, - message, len); - if (! INTERNAL_SYSCALL_ERROR_P (count, err)) + /* Find the next "%s" or the end of the string. */ + const char *next = cp; + while (next[0] != '%' || next[1] != 's') { - message += count; - len -= count; + next = __strchrnul (next + 1, '%'); + + if (next[0] == '\0') + break; } - else if (INTERNAL_SYSCALL_ERRNO (count, err) != EINTR) - break; + + /* Determine what to print. */ + const char *str; + size_t len; + if (cp[0] == '%' && cp[1] == 's') + { + str = va_arg (ap, const char *); + len = strlen (str); + cp += 2; + } + else + { + str = cp; + len = next - cp; + cp = next; + } + + struct str_list *newp = alloca (sizeof (struct str_list)); + newp->str = str; + newp->len = len; + newp->next = list; + list = newp; + ++nlist; } - /* Terminate the process. */ - _exit (127); + bool written = false; + if (nlist > 0) + { + struct iovec *iov = alloca (nlist * sizeof (struct iovec)); + ssize_t total = 0; + + for (int cnt = nlist - 1; cnt >= 0; --cnt) + { + iov[cnt].iov_base = (void *) list->str; + iov[cnt].iov_len = list->len; + total += list->len; + list = list->next; + } + + INTERNAL_SYSCALL_DECL (err); + ssize_t cnt; + do + cnt = INTERNAL_SYSCALL (writev, err, 3, fd, iov, nlist); + while (INTERNAL_SYSCALL_ERROR_P (cnt, err) + && INTERNAL_SYSCALL_ERRNO (cnt, err) == EINTR); - /* The previous call should never have returned. */ - while (1) - /* Try for ever and ever. */ - ABORT_INSTRUCTION; + if (cnt == total) + written = true; + } + + va_end (ap); + + /* If we had no success writing the message, use syslog. */ + if (! written) + vsyslog (LOG_ERR, fmt, ap_copy); + + va_end (ap_copy); + + if (do_abort) + /* Terminate the process. */ + abort (); +} + + +void +__libc_fatal (message) + const char *message; +{ + __libc_message (1, "%s", message); } libc_hidden_def (__libc_fatal) |