This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch, pasky/fixes, created. glibc-2.12-225-g8bddf3f
- From: pasky at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 16 Nov 2010 03:19:13 -0000
- Subject: GNU C Library master sources branch, pasky/fixes, created. glibc-2.12-225-g8bddf3f
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".
The branch, pasky/fixes has been created
at 8bddf3f453ce1b6f6591825846437d6cb55f7b4c (commit)
- Log -----------------------------------------------------------------
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=8bddf3f453ce1b6f6591825846437d6cb55f7b4c
commit 8bddf3f453ce1b6f6591825846437d6cb55f7b4c
Author: Petr Baudis <pasky@ucw.cz>
Date: Tue Nov 16 03:26:19 2010 +0100
Fix fstat() not trying to call fxstat64() on sparc64
sparc64 fxstat implementation should follow the same code path as on
i386, first trying fxstat64() and falling back to fxstat() only when
it is not available. Otherwise, nanosecond times resolution will not
be available.
sparc64 is unlike other 64-bit architectures in that fxstat64() has
not been historically always available in the kernel.
Solution by hideaki@sogetthis.com.
diff --git a/ChangeLog b/ChangeLog
index 1bbbceb..2f25a86 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2010-11-16 Petr Baudis <pasky@suse.cz>
+
+ [BZ #11155]
+ * sysdeps/unis/sysv/linux/sparc/sparc64/fxstat.c: Use i386 fxstat
+ with support for fxstat64 instead of generic fxstat version.
+ Solution by hideaki@sogetthis.com.
+
2010-08-18 Mike Frysinger <vapier@gentoo.org>
[BZ #11929]
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/fxstat.c b/sysdeps/unix/sysv/linux/sparc/sparc64/fxstat.c
index 6b37477..4f219f0 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/fxstat.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/fxstat.c
@@ -1 +1 @@
-#include "../../fxstat.c"
+#include <sysdeps/unix/sysv/linux/i386/fxstat.c>
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=fd5ba40413efc0c95c0754341a76ada944aa1d5f
commit fd5ba40413efc0c95c0754341a76ada944aa1d5f
Author: Mike Frysinger <vapier@gentoo.org>
Date: Sun Aug 22 17:32:46 2010 +0200
Make sure GLRO(dl_pagesize) is initialized properly on all archs
After a recent change to __getpagesize(), GLRO(dl_pagesize) is required
to be set. But that is only done at app init, and shared libraries
dlopened at runtime by static apps dont have their GLRO() state
initialized from the linux auxvec.
ia64/mips have long had similar behavior with their __getpagesize(), but
they have a DL_STATIC_INIT hook to sync some of the static GLRO() fields
to the dynamic GLRO() fields. Now that common linux code requires
GLRO(dl_pagesize) to be set, common linux code now needs that
DL_STATIC_INIT hook.
This patch takes the ia64 logic and promotes it to common code.
diff --git a/ChangeLog b/ChangeLog
index 9f0a7a9..1bbbceb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2010-08-18 Mike Frysinger <vapier@gentoo.org>
+
+ [BZ #11929]
+ * sysdeps/unix/sysv/linux/ia64/Makefile: Move dl-static addition to
+ sysdep vars for subdir==elf to ...
+ * sysdeps/unix/sysv/linux/Makefile: ... here.
+ * sysdeps/unix/sysv/linux/ia64/dl-static.c: Move file to ...
+ * sysdeps/unix/sysv/linux/dl-static.c: ... here.
+ * sysdeps/unix/sysv/linux/ia64/ldsodefs.h: Delete, and move the
+ DL_STATIC_INIT defines to ...
+ * sysdeps/unix/sysv/linux/ldsodefs.h: ... here.
+ * sysdeps/unix/sysv/linux/ia64/getpagesize.c: Delete.
+
2006-11-30 Jan Kratochvil <jan.kratochvil@redhat.com>
[BZ #6693]
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 4302bd3..37c56a3 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -147,7 +147,9 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \
endif
ifeq ($(subdir),elf)
-sysdep-rtld-routines += dl-brk dl-sbrk
+sysdep-dl-routines += dl-static
+sysdep_routines += dl-static
+sysdep-rtld-routines += dl-brk dl-sbrk dl-static
CPPFLAGS-lddlibc4 += -DNOT_IN_libc
endif
diff --git a/sysdeps/unix/sysv/linux/ia64/dl-static.c b/sysdeps/unix/sysv/linux/dl-static.c
similarity index 93%
rename from sysdeps/unix/sysv/linux/ia64/dl-static.c
rename to sysdeps/unix/sysv/linux/dl-static.c
index 4efc077..fa70811 100644
--- a/sysdeps/unix/sysv/linux/ia64/dl-static.c
+++ b/sysdeps/unix/sysv/linux/dl-static.c
@@ -1,5 +1,5 @@
-/* Variable initialization. IA-64 version.
- Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Variable initialization.
+ Copyright (C) 2001, 2002, 2003, 2004, 2010 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
diff --git a/sysdeps/unix/sysv/linux/ia64/Makefile b/sysdeps/unix/sysv/linux/ia64/Makefile
index d9a35a7..3bb1ce0 100644
--- a/sysdeps/unix/sysv/linux/ia64/Makefile
+++ b/sysdeps/unix/sysv/linux/ia64/Makefile
@@ -12,12 +12,6 @@ sysdep_headers += sys/io.h
sysdep_routines += ioperm clone2
endif
-ifeq ($(subdir),elf)
-sysdep-dl-routines += dl-static
-sysdep_routines += $(sysdep-dl-routines)
-sysdep-rtld-routines += $(sysdep-dl-routines)
-endif
-
ifeq ($(subdir),rt)
librt-routines += rt-sysdep
endif
diff --git a/sysdeps/unix/sysv/linux/ia64/getpagesize.c b/sysdeps/unix/sysv/linux/ia64/getpagesize.c
deleted file mode 100644
index 1155dfd..0000000
--- a/sysdeps/unix/sysv/linux/ia64/getpagesize.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (C) 1999, 2000, 2001, 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
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#include <assert.h>
-#include <unistd.h>
-#include <sys/param.h>
-
-#include <ldsodefs.h>
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* Return the system page size. The return value will depend on how
- the kernel is configured. A program must use this call to
- determine the page size to ensure proper alignment for calls such
- as mmap and friends. --davidm 99/11/30 */
-
-int
-__getpagesize ()
-{
- assert (GLRO(dl_pagesize) != 0);
- return GLRO(dl_pagesize);
-}
-libc_hidden_def (__getpagesize)
-weak_alias (__getpagesize, getpagesize)
diff --git a/sysdeps/unix/sysv/linux/ia64/ldsodefs.h b/sysdeps/unix/sysv/linux/ia64/ldsodefs.h
deleted file mode 100644
index 31af624..0000000
--- a/sysdeps/unix/sysv/linux/ia64/ldsodefs.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Run-time dynamic linker data structures for loaded ELF shared objects. IA64.
- Copyright (C) 2001 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
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#ifndef _LDSODEFS_H
-
-/* Get the real definitions. */
-#include_next <ldsodefs.h>
-
-/* Now define our stuff. */
-
-/* We need special support to initialize DSO loaded for statically linked
- binaries. */
-extern void _dl_static_init (struct link_map *map);
-#undef DL_STATIC_INIT
-#define DL_STATIC_INIT(map) _dl_static_init (map)
-
-#endif /* ldsodefs.h */
diff --git a/sysdeps/unix/sysv/linux/ldsodefs.h b/sysdeps/unix/sysv/linux/ldsodefs.h
index 5d5b1b4..ecb5d4f 100644
--- a/sysdeps/unix/sysv/linux/ldsodefs.h
+++ b/sysdeps/unix/sysv/linux/ldsodefs.h
@@ -36,6 +36,12 @@ extern void _dl_aux_init (ElfW(auxv_t) *av) internal_function;
/* Initialization which is normally done by the dynamic linker. */
extern void _dl_non_dynamic_init (void) internal_function;
+/* We need special support to initialize DSO loaded for statically linked
+ binaries. */
+extern void _dl_static_init (struct link_map *map);
+#undef DL_STATIC_INIT
+#define DL_STATIC_INIT(map) _dl_static_init (map)
+
/* We can assume that the kernel always provides the AT_UID, AT_EUID,
AT_GID, and AT_EGID values in the auxiliary vector from 2.4.0 or so on. */
#if __ASSUME_AT_XID
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=fb8fb8464c2b5a44b69e62bcc3211b9c769416da
commit fb8fb8464c2b5a44b69e62bcc3211b9c769416da
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date: Tue Nov 16 03:47:22 2010 +0100
Fix incorrect backtrace unwinding through thread_start() on x86_64
Provide CFI for the outermost clone() to ensure proper unwinding stop
of gdb.
diff --git a/ChangeLog b/ChangeLog
index c7174be..9f0a7a9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2006-11-30 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ [BZ #6693]
+ * sysdeps/unix/sysv/linux/x86_64/clone.S: Provide CFI for the outermost
+ `clone' function to ensure proper unwinding stop of gdb.
+
2010-05-31 Petr Baudis <pasky@suse.cz>
[BZ #11149]
diff --git a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S
index db42f20..8a12b09 100644
--- a/sysdeps/unix/sysv/linux/x86_64/clone.S
+++ b/sysdeps/unix/sysv/linux/x86_64/clone.S
@@ -89,9 +89,6 @@ L(pseudo_end):
ret
L(thread_start):
- cfi_startproc;
- /* Clearing frame pointer is insufficient, use CFI. */
- cfi_undefined (rip);
/* Clear the frame pointer. The ABI suggests this be done, to mark
the outermost frame obviously. */
xorl %ebp, %ebp
@@ -116,7 +113,6 @@ L(thread_start):
/* Call exit with return value from function call. */
movq %rax, %rdi
call HIDDEN_JUMPTARGET (_exit)
- cfi_endproc;
cfi_startproc;
PSEUDO_END (BP_SYM (__clone))
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c8e6e9e783bc5018525e881f021333c3daa4b0f6
commit c8e6e9e783bc5018525e881f021333c3daa4b0f6
Author: Petr Baudis <pasky@suse.cz>
Date: Tue Nov 16 03:35:47 2010 +0100
Allow aux_cache_file open()ing to fail silently even in the chroot mode.
The aux_cache fix of bug 11149 introduced a new bug - normally,
ldconfig -r never cares if the auxiliary cache is not available and
that is not a fatal problem, however this is not the case in case
of ldconfig -r when executed as non-root. In that case, ldconfig -r
fails hard unless var/cache/ldconfig/ exists within the chroot. This
patch fixes that.
diff --git a/ChangeLog b/ChangeLog
index 8f7372b..c7174be 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2010-05-31 Petr Baudis <pasky@suse.cz>
+
+ [BZ #11149]
+ * elf/ldconfig.c (main): Allow aux_cache_file open()ing to fail
+ silently even in the chroot mode.
+
2010-08-19 Petr Baudis <pasky@suse.cz>
[BZ #11928]
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index b4af31e..b82ca8e 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -1359,14 +1359,9 @@ main (int argc, char **argv)
const char *aux_cache_file = _PATH_LDCONFIG_AUX_CACHE;
if (opt_chroot)
- {
- aux_cache_file = chroot_canon (opt_chroot, aux_cache_file);
- if (aux_cache_file == NULL)
- error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"),
- _PATH_LDCONFIG_AUX_CACHE);
- }
+ aux_cache_file = chroot_canon (opt_chroot, aux_cache_file);
- if (! opt_ignore_aux_cache)
+ if (! opt_ignore_aux_cache && aux_cache_file)
load_aux_cache (aux_cache_file);
else
init_aux_cache ();
@@ -1376,7 +1371,8 @@ main (int argc, char **argv)
if (opt_build_cache)
{
save_cache (cache_file);
- save_aux_cache (aux_cache_file);
+ if (aux_cache_file)
+ save_aux_cache (aux_cache_file);
}
return 0;
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b321e863ac162595250446a3b107384dc7aecd89
commit b321e863ac162595250446a3b107384dc7aecd89
Author: Petr Baudis <pasky@ucw.cz>
Date: Sun Aug 22 16:15:17 2010 +0200
Make nscd load /etc/host.conf options in aicache
This patch makes sure _res_hconf is initialized before resolving is being done.
However, this would not be enough since nscd has its own _res_hconf due to
nscd/res_hconf.c; _res_hconf_init() would work on different _res_hconf instance
than the NSS routines. We just need to make sure nscd and glibc share the same
_res_hconf instance - this should not be a problem since users should run
matching versions of glibc and nscd anyway.
diff --git a/ChangeLog b/ChangeLog
index 3d87811..8f7372b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2010-08-19 Petr Baudis <pasky@suse.cz>
+
+ [BZ #11928]
+ * nscd/aicache.c (addhstaiX): Ensure _res_hconf has been initialized.
+ * resolv/res_hconf.c (_res_hconf): Do not redefine outside of libc.
+
2010-05-31 Petr Baudis <pasky@suse.cz>
[BZ #10085]
diff --git a/nscd/aicache.c b/nscd/aicache.c
index 3cb2208..2e92929 100644
--- a/nscd/aicache.c
+++ b/nscd/aicache.c
@@ -26,6 +26,7 @@
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>
+#include <resolv/res_hconf.h>
#include "dbg_log.h"
#include "nscd.h"
@@ -103,6 +104,8 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
if (__res_maybe_init (&_res, 0) == -1)
no_more = 1;
+ if (!_res_hconf.initialized)
+ _res_hconf_init ();
/* If we are looking for both IPv4 and IPv6 address we don't want
the lookup functions to automatically promote IPv4 addresses to
diff --git a/resolv/res_hconf.c b/resolv/res_hconf.c
index ed55bec..c79b85a 100644
--- a/resolv/res_hconf.c
+++ b/resolv/res_hconf.c
@@ -84,7 +84,9 @@ static const struct cmd
};
/* Structure containing the state. */
+#ifndef NOT_IN_libc
struct hconf _res_hconf;
+#endif
/* Skip white space. */
static const char *
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b9be604a7bcffd1fa5fc0141c0dfd2ddcbf09451
commit b9be604a7bcffd1fa5fc0141c0dfd2ddcbf09451
Author: Petr Baudis <pasky@ucw.cz>
Date: Sun Aug 22 16:37:10 2010 +0200
Fix multiple nss_compat initgroups() bugs
Compat initgroups() is completely broken; the code will always set
skip_initgroups_dyn to true, so initgroups() will never be actually
called, but due to the nature of the code, setgrent() won't be called
either - thus, subsequent invocations of initgroups() will not return
the NIS group list anymore.
This is a simple patch that makes sure skip_initgroups_dyn is set only
in case initgroups is not available; it also attempts to handle the
unavailability of other NSS interfaces better.
diff --git a/ChangeLog b/ChangeLog
index d253fde..3d87811 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2010-05-31 Petr Baudis <pasky@suse.cz>
+
+ [BZ #10085]
+ * nis/nss_compat/compat-initgroups.c (internal_getgrent_r): Fix
+ initialization of skip_initgroups_dyn.
+
2010-05-17 Michael Matz <matz@suse.de>
[BZ #11610]
diff --git a/nis/nss_compat/compat-initgroups.c b/nis/nss_compat/compat-initgroups.c
index 07a3b92..de8d95c 100644
--- a/nis/nss_compat/compat-initgroups.c
+++ b/nis/nss_compat/compat-initgroups.c
@@ -474,18 +474,21 @@ internal_getgrent_r (ent_t *ent, char *buffer, size_t buflen, const char *user,
/* If the selected module does not support getgrent_r or
initgroups_dyn, abort. We cannot find the needed group
entries. */
- if (nss_getgrent_r == NULL && nss_initgroups_dyn == NULL)
+ if (nss_initgroups_dyn == NULL || nss_getgrgid_r == NULL)
+ {
+ if (nss_setgrent != NULL)
+ {
+ nss_setgrent (1);
+ ent->need_endgrent = true;
+ }
+ ent->skip_initgroups_dyn = true;
+ }
+
+ if (ent->skip_initgroups_dyn && nss_getgrent_r == NULL)
return NSS_STATUS_UNAVAIL;
ent->files = false;
- if (nss_initgroups_dyn == NULL && nss_setgrent != NULL)
- {
- nss_setgrent (1);
- ent->need_endgrent = true;
- }
- ent->skip_initgroups_dyn = true;
-
return getgrent_next_nss (ent, buffer, buflen, user, group,
start, size, groupsp, limit, errnop);
}
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=31eb5a4c4986367538ccb154dfce0c84276ba151
commit 31eb5a4c4986367538ccb154dfce0c84276ba151
Author: Michael Matz <matz@suse.de>
Date: Sun Aug 22 16:53:24 2010 +0200
Add proper unwind information for x86_64 _fini
It is impossible to reliably unwind the stack above _fini() on x86_64 since no
unwind information is provided for it and it modifies a stack register. This
matters for gdb backtracing - if a process crashes within a destructor, it can
frequently be essential to look at why the program began terminating in the
first place.
diff --git a/ChangeLog b/ChangeLog
index 122a2b8..d253fde 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2010-05-17 Michael Matz <matz@suse.de>
+
+ [BZ #11610]
+ * sysdeps/x86_64/elf/initfini.c (_fini): Add unwind information.
+
2010-05-12 Petr Baudis <pasky@suse.cz>
[BZ #11589]
diff --git a/sysdeps/x86_64/elf/initfini.c b/sysdeps/x86_64/elf/initfini.c
index 30161d5..dd1a4ce 100644
--- a/sysdeps/x86_64/elf/initfini.c
+++ b/sysdeps/x86_64/elf/initfini.c
@@ -44,6 +44,25 @@
* crtn.s puts the corresponding function epilogues
in the .init and .fini sections. */
+/* The unwind annotation for _fini is peculiar for good reasons:
+ (a) We need a real function that isn't constructed separately
+ (i.e. one which has a .size directive) in order to attach unwind
+ info to it. Hence _fini is a wrapper around _real_fini, the
+ former being a normal function, the latter being the first
+ instruction of the traditional _fini.
+ (b) We must not fiddle with the stack pointer in _real_fini,
+ as we wouldn't be able to describe the effects in unwind info
+ (c) some versions of GCC have no correct unwind info for
+ __do_global_dtors_aux, meaning they can't properly restore %rbp
+ (unwinding through it is possible but later up when we next
+ need %rbp we can't access it anymore)
+ Therefore we save/restore it in _fini for uses later up the call chain.
+ But we don't make the CFA use that register (that would lead to
+ the above problem)
+ (d) We want an 16-aligned stack pointer at _real_fini. Because of (a)
+ we can't align it in _real_fini, hence we do it in the caller by
+ subtracting 8, making in 8mod16 which the call then make 0mod16
+ again. */
__asm__ ("\n\
#include \"defs.h\"\n\
\n\
@@ -88,16 +107,28 @@ _init:\n\
.globl _fini\n\
.type _fini,@function\n\
_fini:\n\
+ .cfi_startproc\n\
+ push %rbp\n\
+ .cfi_def_cfa_offset 16\n\
+ .cfi_offset 6,-16\n\
subq $8, %rsp\n\
+ .cfi_def_cfa_offset 24\n\
+ call _real_fini\n\
+ addq $8, %rsp\n\
+ .cfi_def_cfa_offset 16\n\
+ pop %rbp\n\
+ ret\n\
+ .cfi_endproc\n\
ALIGN\n\
END_FINI\n\
+.size _fini, .-_fini\n\
+_real_fini:\n\
\n\
/*@_fini_PROLOG_ENDS*/\n\
call i_am_not_a_leaf@PLT\n\
\n\
/*@_fini_EPILOG_BEGINS*/\n\
.section .fini\n\
- addq $8, %rsp\n\
ret\n\
END_FINI\n\
\n\
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=9fcff7a79b60cd9202fdacafdbd5fb369933c64b
commit 9fcff7a79b60cd9202fdacafdbd5fb369933c64b
Author: Petr Baudis <pasky@ucw.cz>
Date: Sun Aug 22 16:44:15 2010 +0200
Fix jn() precision problems around zero points of j0()
There appears to be a really nasty bug in jn() from fdlibm, which is
the foundation for most libm implementations (including glibc libm).
The zeroth-order j0() and first-order j1() cylindrical Bessel functions
are used to recursively generate the jn() value, but only the zeroth-order
Bessel function is used to normalize it; however, each of the functions
gets highly imprecise (approaching "bogus") near its zero point, making
the jn() value itself bogus.
But in fact, the zero points of j0() and j1() never coincide, thus j1()
should be used in case it is more precise than j0(). (That is, simply
when its value is further from zero.)
As an example, 2.4048255576957729_8 is the first zero of j0().
The proper value as calculated by Mathematica is 0.19899990535769...
However, jn() returns -inf on 64-bit arch, or 0.185007 on 32-bit arch.
With the proposed patch below, the returned value is 0.199000.
The fix is based on work by Steve Kargl and Tobias Burnus.
diff --git a/ChangeLog b/ChangeLog
index 601f6f0..122a2b8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2010-05-12 Petr Baudis <pasky@suse.cz>
+
+ [BZ #11589]
+ * sysdeps/ieee754/dbl-64/e_jn.c: Compensate major precision loss
+ around j0() zero points by switching to j1().
+ * sysdeps/ieee754/flt-32/e_jnf.c: Likewise.
+ * sysdeps/ieee754/ldbl-128/e_jnl.c: Likewise.
+ * sysdeps/ieee754/ldbl-128ibm/e_jnl.c: Likewise.
+ * sysdeps/ieee754/ldbl-96/e_jnl.c: Likewise.
+
2010-06-01 Jan Sembera <jsembera@suse.cz>
[BZ #6812]
diff --git a/sysdeps/ieee754/dbl-64/e_jn.c b/sysdeps/ieee754/dbl-64/e_jn.c
index bf4a13d..d9d6f91 100644
--- a/sysdeps/ieee754/dbl-64/e_jn.c
+++ b/sysdeps/ieee754/dbl-64/e_jn.c
@@ -215,7 +215,16 @@ static double zero = 0.00000000000000000000e+00;
}
}
}
- b = (t*__ieee754_j0(x)/b);
+ /* j0() and j1() suffer enormous loss of precision at and
+ * near zero; however, we know that their zero points never
+ * coincide, so just choose the one further away from zero.
+ */
+ z = __ieee754_j0 (x);
+ w = __ieee754_j1 (x);
+ if (fabs (z) >= fabs (w))
+ b = (t * z / b);
+ else
+ b = (t * w / a);
}
}
if(sgn==1) return -b; else return b;
diff --git a/sysdeps/ieee754/flt-32/e_jnf.c b/sysdeps/ieee754/flt-32/e_jnf.c
index de2e53d..dd3d551 100644
--- a/sysdeps/ieee754/flt-32/e_jnf.c
+++ b/sysdeps/ieee754/flt-32/e_jnf.c
@@ -165,7 +165,16 @@ static float zero = 0.0000000000e+00;
}
}
}
- b = (t*__ieee754_j0f(x)/b);
+ /* j0() and j1() suffer enormous loss of precision at and
+ * near zero; however, we know that their zero points never
+ * coincide, so just choose the one further away from zero.
+ */
+ z = __ieee754_j0f (x);
+ w = __ieee754_j1f (x);
+ if (fabsf (z) >= fabsf (w))
+ b = (t * z / b);
+ else
+ b = (t * w / a);
}
}
if(sgn==1) return -b; else return b;
diff --git a/sysdeps/ieee754/ldbl-128/e_jnl.c b/sysdeps/ieee754/ldbl-128/e_jnl.c
index a4a4e24..a7f6772 100644
--- a/sysdeps/ieee754/ldbl-128/e_jnl.c
+++ b/sysdeps/ieee754/ldbl-128/e_jnl.c
@@ -285,7 +285,16 @@ __ieee754_jnl (n, x)
}
}
}
- b = (t * __ieee754_j0l (x) / b);
+ /* j0() and j1() suffer enormous loss of precision at and
+ * near zero; however, we know that their zero points never
+ * coincide, so just choose the one further away from zero.
+ */
+ z = __ieee754_j0l (x);
+ w = __ieee754_j1l (x);
+ if (fabsl (z) >= fabsl (w))
+ b = (t * z / b);
+ else
+ b = (t * w / a);
}
}
if (sgn == 1)
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_jnl.c b/sysdeps/ieee754/ldbl-128ibm/e_jnl.c
index 0eea745..372f942 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_jnl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_jnl.c
@@ -286,7 +286,16 @@ __ieee754_jnl (n, x)
}
}
}
- b = (t * __ieee754_j0l (x) / b);
+ /* j0() and j1() suffer enormous loss of precision at and
+ * near zero; however, we know that their zero points never
+ * coincide, so just choose the one further away from zero.
+ */
+ z = __ieee754_j0l (x);
+ w = __ieee754_j1l (x);
+ if (fabsl (z) >= fabsl (w))
+ b = (t * z / b);
+ else
+ b = (t * w / a);
}
}
if (sgn == 1)
diff --git a/sysdeps/ieee754/ldbl-96/e_jnl.c b/sysdeps/ieee754/ldbl-96/e_jnl.c
index 3d715d3..bedff7d 100644
--- a/sysdeps/ieee754/ldbl-96/e_jnl.c
+++ b/sysdeps/ieee754/ldbl-96/e_jnl.c
@@ -281,7 +281,16 @@ __ieee754_jnl (n, x)
}
}
}
- b = (t * __ieee754_j0l (x) / b);
+ /* j0() and j1() suffer enormous loss of precision at and
+ * near zero; however, we know that their zero points never
+ * coincide, so just choose the one further away from zero.
+ */
+ z = __ieee754_j0l (x);
+ w = __ieee754_j1l (x);
+ if (fabsl (z) >= fabsl (w))
+ b = (t * z / b);
+ else
+ b = (t * w / a);
}
}
if (sgn == 1)
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=75134e46476263ab116be341531cadb1e6ab87d6
commit 75134e46476263ab116be341531cadb1e6ab87d6
Author: Jan Sembera <jsembera@suse.cz>
Date: Sun Aug 22 15:43:46 2010 +0200
nscd/hstcache.c: Propagate TRY_AGAIN properly to the clients.
When nscd host cache gets temporary error from nss, it should return
temporary error instead of permanent error to the application.
diff --git a/ChangeLog b/ChangeLog
index 7fc8af2..601f6f0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2010-06-01 Jan Sembera <jsembera@suse.cz>
+
+ [BZ #6812]
+ * nscd/hstcache.c: Propagate TRY_AGAIN properly to the clients.
+
2010-11-11 Andreas Schwab <schwab@redhat.com>
* posix/fnmatch_loop.c (NEW_PATTERN): Fix use of alloca.
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
index 228f6fd..5d3fbe2 100644
--- a/nscd/hstcache.c
+++ b/nscd/hstcache.c
@@ -77,6 +77,20 @@ static const hst_response_header notfound =
};
+/* This is the standard reply in case of temporary error */
+static const hst_response_header tryagain =
+{
+ .version = NSCD_VERSION,
+ .found = 0,
+ .h_name_len = 0,
+ .h_aliases_cnt = 0,
+ .h_addrtype = -1,
+ .h_length = -1,
+ .h_addr_list_cnt = 0,
+ .error = TRY_AGAIN
+};
+
+
static void
cache_addhst (struct database_dyn *db, int fd, request_header *req,
const void *key, struct hostent *hst, uid_t owner,
@@ -85,6 +99,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
{
bool all_written = true;
time_t t = time (NULL);
+ hst_response_header *errhdr;
/* We allocate all data in one memory block: the iov vector,
the response header and the dataset itself. */
@@ -112,15 +127,20 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
{
/* We have no data. This means we send the standard reply for this
case. */
- ssize_t total = sizeof (notfound);
+ ssize_t total = sizeof (hst_response_header);
+ errhdr = (errval == EAGAIN) ? &tryagain : ¬found;
if (fd != -1 &&
- TEMP_FAILURE_RETRY (send (fd, ¬found, total,
+ TEMP_FAILURE_RETRY (send (fd, errhdr, total,
MSG_NOSIGNAL)) != total)
all_written = false;
- dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
- 1);
+ if (errval == EAGAIN)
+ /* Don't store temporary resolver errors at all */
+ dataset = NULL;
+ else
+ dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
+ IDX_result_data);
/* If we cannot permanently store the result, so be it. */
if (dataset != NULL)
{
@@ -490,7 +510,7 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
/* We set the error to indicate this is (possibly) a
temporary error and that it does not mean the entry
is not available at all. */
- errval = EAGAIN;
+ h_errno = TRY_AGAIN;
break;
}
use_malloc = true;
@@ -502,7 +522,7 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
}
cache_addhst (db, fd, req, key, hst, uid, he, dh,
- h_errno == TRY_AGAIN ? errval : 0, ttl);
+ h_errno == TRY_AGAIN ? EAGAIN : 0, ttl);
if (use_malloc)
free (buffer);
-----------------------------------------------------------------------
hooks/post-receive
--
GNU C Library master sources