[libvirt] Build failed in Jenkins: libvirt-build #472

See <http://honk.sigxcpu.org:8001/job/libvirt-build/472/changes> Changes: [eblake] maint: update to latest gnulib ------------------------------------------ [...truncated 5806 lines...] GEN wchar.h GEN wctype.h make all-am make[3]: Entering directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/gnulib/lib'> CC allocator.lo CC areadlink.lo CC base64.lo CC binary-io.lo CC bitrotate.lo CC c-ctype.lo CC c-strcasecmp.lo CC c-strncasecmp.lo CC c-strcasestr.lo CC careadlinkat.lo CC cloexec.lo CC count-one-bits.lo CC md5.lo CC sha256.lo CC dirname-lgpl.lo CC basename-lgpl.lo CC stripslash.lo CC fd-hook.lo CC freading.lo CC localcharset.lo CC lock.lo CC malloca.lo CC nonblocking.lo CC passfd.lo CC physmem.lo CC pipe2.lo CC sig-handler.lo CC sockets.lo CC stat-time.lo CC stdio.lo CC strnlen1.lo CC sys_socket.lo CC tempname.lo CC threadlib.lo CC unistd.lo CC wctype-h.lo CC xsize.lo CC asnprintf.lo CC fclose.lo CC fcntl.lo CC fflush.lo CC fpurge.lo CC fseek.lo CC fseeko.lo CC ioctl.lo CC mktime.lo CC perror.lo CC printf-args.lo CC printf-parse.lo CC strerror.lo CC strerror_r.lo CC vasnprintf.lo CCLD libgnu.la GEN charset.alias GEN ref-add.sed GEN ref-del.sed make[3]: Leaving directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/gnulib/lib'> make[2]: Leaving directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/gnulib/lib'> Making all in include make[2]: Entering directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/include'> Making all in libvirt make[3]: Entering directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/include/libvirt'> make[3]: Nothing to be done for `all'. make[3]: Leaving directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/include/libvirt'> make[3]: Entering directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/include'> make[3]: Nothing to be done for `all-am'. make[3]: Leaving directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/include'> make[2]: Leaving directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/include'> Making all in src make[2]: Entering directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src'> GEN libvirt.syms GEN libvirt.def make all-am make[3]: Entering directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src'> CC libvirt_util_la-viralloc.lo CC libvirt_util_la-virarch.lo CC libvirt_util_la-viratomic.lo CC libvirt_util_la-viraudit.lo CC libvirt_util_la-virauth.lo CC libvirt_util_la-virauthconfig.lo CC libvirt_util_la-virbitmap.lo CC libvirt_util_la-virbuffer.lo CC libvirt_util_la-vircgroup.lo CC libvirt_util_la-vircommand.lo CC libvirt_util_la-virconf.lo CC libvirt_util_la-virdbus.lo CC libvirt_util_la-virdnsmasq.lo CC libvirt_util_la-virebtables.lo CC libvirt_util_la-virerror.lo CC libvirt_util_la-virevent.lo CC libvirt_util_la-vireventpoll.lo CC libvirt_util_la-virfile.lo CC libvirt_util_la-virhash.lo CC libvirt_util_la-virhashcode.lo CC libvirt_util_la-virhook.lo CC libvirt_util_la-virinitctl.lo CC libvirt_util_la-viriptables.lo CC libvirt_util_la-virjson.lo CC libvirt_util_la-virkeycode.lo CC libvirt_util_la-virkeyfile.lo CC libvirt_util_la-virlockspace.lo CC libvirt_util_la-virlog.lo CC libvirt_util_la-virmacaddr.lo CC libvirt_util_la-virnetdev.lo CC libvirt_util_la-virnetdevbandwidth.lo CC libvirt_util_la-virnetdevbridge.lo CC libvirt_util_la-virnetdevmacvlan.lo CC libvirt_util_la-virnetdevopenvswitch.lo CC libvirt_util_la-virnetdevtap.lo CC libvirt_util_la-virnetdevveth.lo CC libvirt_util_la-virnetdevvlan.lo CC libvirt_util_la-virnetdevvportprofile.lo CC libvirt_util_la-virnetlink.lo CC libvirt_util_la-virnodesuspend.lo CC libvirt_util_la-virobject.lo CC libvirt_util_la-virpci.lo CC libvirt_util_la-virpidfile.lo CC libvirt_util_la-virprocess.lo CC libvirt_util_la-virrandom.lo CC libvirt_util_la-virsexpr.lo CC libvirt_util_la-virsocketaddr.lo CC libvirt_util_la-virstatslinux.lo CC libvirt_util_la-virstoragefile.lo CC libvirt_util_la-virstring.lo CC libvirt_util_la-virsysinfo.lo CC libvirt_util_la-virthread.lo CC libvirt_util_la-virthreadpool.lo CC libvirt_util_la-virtime.lo CC libvirt_util_la-virtypedparam.lo CC libvirt_util_la-virusb.lo CC libvirt_util_la-viruri.lo CC libvirt_util_la-virutil.lo CC libvirt_util_la-viruuid.lo CC libvirt_util_la-virxml.lo CCLD libvirt_util.la CC libvirt_conf_la-netdev_bandwidth_conf.lo CC libvirt_conf_la-netdev_vport_profile_conf.lo CC libvirt_conf_la-netdev_vlan_conf.lo CC libvirt_conf_la-capabilities.lo CC libvirt_conf_la-domain_conf.lo CC libvirt_conf_la-domain_audit.lo CC libvirt_conf_la-domain_nwfilter.lo CC libvirt_conf_la-snapshot_conf.lo CC libvirt_conf_la-domain_event.lo CC libvirt_conf_la-network_conf.lo CC libvirt_conf_la-nwfilter_params.lo CC libvirt_conf_la-nwfilter_ipaddrmap.lo CC libvirt_conf_la-nwfilter_conf.lo CC libvirt_conf_la-node_device_conf.lo CC libvirt_conf_la-storage_conf.lo CC libvirt_conf_la-storage_encryption_conf.lo CC libvirt_conf_la-interface_conf.lo CC libvirt_conf_la-secret_conf.lo CC libvirt_conf_la-cpu_conf.lo CC libvirt_conf_la-virconsole.lo CC libvirt_conf_la-device_conf.lo CCLD libvirt_conf.la CC libvirt_cpu_la-cpu.lo CC libvirt_cpu_la-cpu_generic.lo CC libvirt_cpu_la-cpu_x86.lo CC libvirt_cpu_la-cpu_s390.lo CC libvirt_cpu_la-cpu_arm.lo CC libvirt_cpu_la-cpu_map.lo CC libvirt_cpu_la-cpu_powerpc.lo CCLD libvirt_cpu.la CC libvirt_vmx_la-vmx.lo CCLD libvirt_vmx.la CC libvirt_xenxs_la-xen_sxpr.lo CC libvirt_xenxs_la-xen_xm.lo CCLD libvirt_xenxs.la CC libvirt_driver_la-driver.lo CC libvirt_driver_la-datatypes.lo CC libvirt_driver_la-fdstream.lo CC libvirt_driver_la-nodeinfo.lo CC libvirt_driver_la-libvirt.lo CC libvirt_driver_la-lock_manager.lo CC libvirt_driver_la-lock_driver_nop.lo CC libvirt_driver_la-domain_lock.lo CCLD libvirt_driver.la CC libvirt_driver_test_la-test_driver.lo CCLD libvirt_driver_test.la CC libvirt_driver_remote_la-remote_driver.lo CC libvirt_driver_remote_la-remote_protocol.lo CC libvirt_driver_remote_la-qemu_protocol.lo CC libvirt_net_rpc_client_la-virnetclientprogram.lo CC libvirt_net_rpc_client_la-virnetclientstream.lo CC libvirt_net_rpc_client_la-virnetclient.lo CCLD libvirt-net-rpc-client.la CC libvirt_net_rpc_server_la-virnetserverprogram.lo CC libvirt_net_rpc_server_la-virnetserverservice.lo CC libvirt_net_rpc_server_la-virnetserverclient.lo CC libvirt_net_rpc_server_la-virnetservermdns.lo CC libvirt_net_rpc_server_la-virnetserver.lo CCLD libvirt-net-rpc-server.la CC libvirt_net_rpc_la-virnetmessage.lo CC libvirt_net_rpc_la-virnetprotocol.lo CC libvirt_net_rpc_la-virnetsocket.lo CC libvirt_net_rpc_la-virnettlscontext.lo CC libvirt_net_rpc_la-virkeepaliveprotocol.lo CC libvirt_net_rpc_la-virkeepalive.lo CC libvirt_net_rpc_la-virnetsaslcontext.lo CCLD libvirt-net-rpc.la CCLD libvirt_driver_remote.la CC libvirt_driver_openvz_la-openvz_conf.lo CC libvirt_driver_openvz_la-openvz_driver.lo CC libvirt_driver_openvz_la-openvz_util.lo CCLD libvirt_driver_openvz.la CC libvirt_driver_vmware_la-vmware_driver.lo CC libvirt_driver_vmware_la-vmware_conf.lo CCLD libvirt_driver_vmware.la CC libvirt_driver_vbox_la-vbox_glue.lo CC libvirt_driver_vbox_la-vbox_driver.lo CC libvirt_driver_vbox_la-vbox_V2_2.lo CC libvirt_driver_vbox_la-vbox_V3_0.lo CC libvirt_driver_vbox_la-vbox_V3_1.lo CC libvirt_driver_vbox_la-vbox_V3_2.lo CC libvirt_driver_vbox_la-vbox_V4_0.lo CC libvirt_driver_vbox_la-vbox_V4_1.lo CCLD libvirt_driver_vbox.la CC libvirt_security_manager_la-security_driver.lo CC libvirt_security_manager_la-security_nop.lo CC libvirt_security_manager_la-security_stack.lo CC libvirt_security_manager_la-security_dac.lo CC libvirt_security_manager_la-security_manager.lo CC libvirt_security_manager_la-security_selinux.lo CCLD libvirt_security_manager.la CCLD libvirt.la ./.libs/libvirt_util.a(libvirt_util_la-virnetdevtap.o): In function `rpl_fwrite': <http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src/../gnulib/lib/stdio.h>:903: multiple definition of `rpl_fwrite' ./.libs/libvirt_util.a(libvirt_util_la-virnetdev.o):<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src/../gnulib/lib/stdio.h>:903: first defined here ./.libs/libvirt_util.a(libvirt_util_la-virnetlink.o): In function `rpl_fwrite': <http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src/../gnulib/lib/stdio.h>:903: multiple definition of `rpl_fwrite' ./.libs/libvirt_util.a(libvirt_util_la-virnetdev.o):<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src/../gnulib/lib/stdio.h>:903: first defined here ../gnulib/lib/.libs/libgnu.a(stdio.o): In function `rpl_fwrite': <http://honk.sigxcpu.org:8001/job/libvirt-build/ws/gnulib/lib/stdio.h>:903: multiple definition of `rpl_fwrite' ./.libs/libvirt_util.a(libvirt_util_la-virnetdev.o):<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src/../gnulib/lib/stdio.h>:903: first defined here collect2: error: ld returned 1 exit status make[3]: *** [libvirt.la] Error 1 make[3]: Leaving directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src'> make[2]: *** [all] Error 2 make[2]: Leaving directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src'> make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/'> make: *** [all] Error 2 Build step 'Execute shell' marked build as failure

On 01/02/2013 10:29 AM, Jenkins CI wrote:
See <http://honk.sigxcpu.org:8001/job/libvirt-build/472/changes>
Changes:
[eblake] maint: update to latest gnulib
CCLD libvirt_security_manager.la CCLD libvirt.la ./.libs/libvirt_util.a(libvirt_util_la-virnetdevtap.o): In function `rpl_fwrite': <http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src/../gnulib/lib/stdio.h>:903: multiple definition of `rpl_fwrite' ./.libs/libvirt_util.a(libvirt_util_la-virnetdev.o):<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src/../gnulib/lb/stdio.h>:903: first defined here
Yuck. This sounds like an issue in upstream gnulib inline handling. I see this from your logs: checking build system type... i686-pc-linux-gnu but that doesn't tell me what version of glibc and gcc you are using, in case the problem is an interaction between those (as is, I recently reported[1] a case where a mismatch of old glibc and new gcc causes build failures, but that was on a modified RHEL 5 box, so probably doesn't match your setup). [1] https://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00176.html I haven't been able to reproduce the failure locally on any of my Fedora or RHEL boxes, using incremental builds; I am also in the middle of trying a fresh clone build, to see if that is any different. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Hi, On Wed, Jan 02, 2013 at 11:20:08AM -0700, Eric Blake wrote:
On 01/02/2013 10:29 AM, Jenkins CI wrote:
See <http://honk.sigxcpu.org:8001/job/libvirt-build/472/changes>
Changes:
[eblake] maint: update to latest gnulib
CCLD libvirt_security_manager.la CCLD libvirt.la ./.libs/libvirt_util.a(libvirt_util_la-virnetdevtap.o): In function `rpl_fwrite': <http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src/../gnulib/lib/stdio.h>:903: multiple definition of `rpl_fwrite' ./.libs/libvirt_util.a(libvirt_util_la-virnetdev.o):<http://honk.sigxcpu.org:8001/job/libvirt-build/ws/src/../gnulib/lb/stdio.h>:903: first defined here
Yuck. This sounds like an issue in upstream gnulib inline handling. I see this from your logs: checking build system type... i686-pc-linux-gnu but that doesn't tell me what version of glibc and gcc you are using, in case the problem is an interaction between those (as is, I recently reported[1] a case where a mismatch of old glibc and new gcc causes build failures, but that was on a modified RHEL 5 box, so probably doesn't match your setup). [1] https://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00176.html
This is gcc 4.7.1 and eglibc 2.13. I upgraded to Debian Wheezy's current gcc 4.7.2 without any changes. I'm not able to reproduce it locally on a Debian sid system either. I also tried a clean bootstrap http://honk.sigxcpu.org:8001/job/libvirt-build/474/ but the problem persists: $ nm src/.libs/libvirt_util.a | grep rpl_fwrite 00000760 T rpl_fwrite 00000000 T rpl_fwrite 00000300 T rpl_fwrite Any information I can provide to diagnose this further? -- Guido P.S.: I've removed the mailing list from the build reports temporarily to not spam the list with new build failures until this is fixed.
I haven't been able to reproduce the failure locally on any of my Fedora or RHEL boxes, using incremental builds; I am also in the middle of trying a fresh clone build, to see if that is any different.
-- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 01/02/2013 01:14 PM, Guido Günther wrote:
This is gcc 4.7.1 and eglibc 2.13. I upgraded to Debian Wheezy's current gcc 4.7.2 without any changes. I'm not able to reproduce it locally on a Debian sid system either. I also tried a clean bootstrap
http://honk.sigxcpu.org:8001/job/libvirt-build/474/
but the problem persists:
$ nm src/.libs/libvirt_util.a | grep rpl_fwrite 00000760 T rpl_fwrite 00000000 T rpl_fwrite 00000300 T rpl_fwrite
Any information I can provide to diagnose this further?
Sure - can you paste the portion of libvirt/gnulib/lib/stdio.h that shows why rpl_fwrite was enabled in the first place? The original template file stdio.in.h looks like: #if @GNULIB_FWRITE@ # if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef fwrite # define fwrite rpl_fwrite # endif _GL_FUNCDECL_RPL (fwrite, size_t, On my F18 box, I see: #if 1 # if 0 && (1 || 1) # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef fwrite # define fwrite rpl_fwrite # endif _GL_FUNCDECL_RPL (fwrite, size_t, which means that there is no replacement of stdio write functions on glibc; reading the source code of .gnulib/m4/stdio_h.m4, REPLACE_STDIO_WRITE_FUNCS is only set to 1 if gl_SIGNAL_SIGPIPE detects an unusual situation. So something in eglibc is tripping up gl_SIGNAL_SIGPIPE; maybe finding that portion of config.log will help understand root cause. Then again, your configure output shows: checking for SIGPIPE... yes which says gl_SIGNAL_SIGPIPE didn't find anything unusual. Oh, maybe the next culprit - I was compiling at -O0, which disables fortification (since that only works at -O1 or higher); in the gnulib stdio.h I see: /* Work around glibc bug 11959 <http://sources.redhat.com/bugzilla/show_bug.cgi?id=11959>, which sometimes causes an unwanted diagnostic for fwrite calls. This affects only function declaration attributes, so it's not needed for C++. */ # if !defined __cplusplus && 0 < __USE_FORTIFY_LEVEL _GL_STDIO_INLINE size_t _GL_ARG_NONNULL ((1, 4)) rpl_fwrite (const void *ptr, size_t s, size_t n, FILE *stream) { size_t r = fwrite (ptr, s, n, stream); (void) r; return r; } # undef fwrite # define fwrite rpl_fwrite # endif It could be that while this works for glibc, it causes grief on eglibc, especially depending on what _GL_STDIO_INLINE expands to at the time. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

[adding gnulib in cc] On 01/02/2013 03:03 PM, Eric Blake wrote:
On 01/02/2013 01:14 PM, Guido Günther wrote:
This is gcc 4.7.1 and eglibc 2.13. I upgraded to Debian Wheezy's current gcc 4.7.2 without any changes. I'm not able to reproduce it locally on a Debian sid system either. I also tried a clean bootstrap
http://honk.sigxcpu.org:8001/job/libvirt-build/474/
but the problem persists:
$ nm src/.libs/libvirt_util.a | grep rpl_fwrite 00000760 T rpl_fwrite 00000000 T rpl_fwrite 00000300 T rpl_fwrite
Any information I can provide to diagnose this further?
Sure - can you paste the portion of libvirt/gnulib/lib/stdio.h that shows why rpl_fwrite was enabled in the first place? The original template file stdio.in.h looks like:
#if @GNULIB_FWRITE@ # if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef fwrite # define fwrite rpl_fwrite # endif _GL_FUNCDECL_RPL (fwrite, size_t,
On my F18 box, I see:
#if 1 # if 0 && (1 || 1) # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef fwrite # define fwrite rpl_fwrite # endif _GL_FUNCDECL_RPL (fwrite, size_t,
which means that there is no replacement of stdio write functions on glibc; reading the source code of .gnulib/m4/stdio_h.m4, REPLACE_STDIO_WRITE_FUNCS is only set to 1 if gl_SIGNAL_SIGPIPE detects an unusual situation. So something in eglibc is tripping up gl_SIGNAL_SIGPIPE; maybe finding that portion of config.log will help understand root cause.
Then again, your configure output shows: checking for SIGPIPE... yes
which says gl_SIGNAL_SIGPIPE didn't find anything unusual.
Oh, maybe the next culprit - I was compiling at -O0, which disables fortification (since that only works at -O1 or higher); in the gnulib stdio.h I see:
/* Work around glibc bug 11959 <http://sources.redhat.com/bugzilla/show_bug.cgi?id=11959>, which sometimes causes an unwanted diagnostic for fwrite calls. This affects only function declaration attributes, so it's not needed for C++. */ # if !defined __cplusplus && 0 < __USE_FORTIFY_LEVEL _GL_STDIO_INLINE size_t _GL_ARG_NONNULL ((1, 4)) rpl_fwrite (const void *ptr, size_t s, size_t n, FILE *stream) { size_t r = fwrite (ptr, s, n, stream); (void) r; return r; } # undef fwrite # define fwrite rpl_fwrite # endif
It could be that while this works for glibc, it causes grief on eglibc, especially depending on what _GL_STDIO_INLINE expands to at the time.
Aha, I reproduced the problem on glibc while using RHEL 6.3 and default CFLAGS (instead of my more typical CFLAGS=-g devel override). Definitely a problem in Paul's recent work on inline magic, where _GL_STDIO_INLINE is not doing the intended actions. Paul, any thoughts on what we need to do to fix this? Also, since that glibc bug (of a bogus __wur attribute on fwrite) has since been fixed, is the unconditional override to rpl_fwrite something that is still useful to keep around? -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

The libvirt folks reported[1] a link error of multiple rpl_fwrite definitions that hits only when optimization and FORTIFY_SOURCE are both enabled, due to improper use of inline. But since that particular use of rpl_fwrite exists only to work around a spurious gcc warning on some versions of glibc, we can use gcc extensions to acheive the same effect without using inline. This approach copies the method used in ignore-value.h. [1] https://lists.gnu.org/archive/html/bug-gnulib/2013-01/msg00014.html * lib/stdio.in.h (fwrite): Limit warn_unused_result workaround to just gcc, and in a way that avoids inline issues. * modules/stdio (Depends-on): Drop extern-inline. Signed-off-by: Eric Blake <eblake@redhat.com> --- ChangeLog | 7 +++++++ lib/stdio.in.h | 23 +++++------------------ modules/stdio | 1 - 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 73c186d..0bae990 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-01-03 Eric Blake <eblake@redhat.com> + + fwrite: silence __wur without using inline + * lib/stdio.in.h (fwrite): Limit warn_unused_result workaround to + just gcc, and in a way that avoids inline issues. + * modules/stdio (Depends-on): Drop extern-inline. + 2013-01-03 Jim Meyering <jim@meyering.net> update-copyright: avoid copyright notice date corruption diff --git a/lib/stdio.in.h b/lib/stdio.in.h index ec39c7d..0f20171 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -46,11 +46,6 @@ #ifndef _@GUARD_PREFIX@_STDIO_H #define _@GUARD_PREFIX@_STDIO_H -_GL_INLINE_HEADER_BEGIN -#ifndef _GL_STDIO_INLINE -# define _GL_STDIO_INLINE _GL_INLINE -#endif - /* Get va_list. Needed on many systems, including glibc 2.8. */ #include <stdarg.h> @@ -583,18 +578,12 @@ _GL_CXXALIAS_SYS (fwrite, size_t, /* Work around glibc bug 11959 <http://sources.redhat.com/bugzilla/show_bug.cgi?id=11959>, which sometimes causes an unwanted diagnostic for fwrite calls. - This affects only function declaration attributes, so it's not - needed for C++. */ -# if !defined __cplusplus && 0 < __USE_FORTIFY_LEVEL -_GL_STDIO_INLINE size_t _GL_ARG_NONNULL ((1, 4)) -rpl_fwrite (const void *ptr, size_t s, size_t n, FILE *stream) -{ - size_t r = fwrite (ptr, s, n, stream); - (void) r; - return r; -} + This affects only function declaration attributes under certain + versions of gcc, and is not needed for C++. */ +# if !defined __cplusplus && 0 < __USE_FORTIFY_LEVEL \ + && 3 < (__GNUC__ + (4 <= __GNUC_MINOR__)) # undef fwrite -# define fwrite rpl_fwrite +# define fwrite(a, b, c, d) ({size_t __r = fwrite (a, b, c, d); __r; }) # endif # endif _GL_CXXALIASWARN (fwrite); @@ -1338,8 +1327,6 @@ _GL_WARN_ON_USE (vsprintf, "vsprintf is not always POSIX compliant - " "POSIX compliance"); #endif -_GL_INLINE_HEADER_END - #endif /* _@GUARD_PREFIX@_STDIO_H */ #endif /* _@GUARD_PREFIX@_STDIO_H */ #endif diff --git a/modules/stdio b/modules/stdio index c33ad31..54189dc 100644 --- a/modules/stdio +++ b/modules/stdio @@ -7,7 +7,6 @@ lib/stdio.in.h m4/stdio_h.m4 Depends-on: -extern-inline include_next snippet/arg-nonnull snippet/c++defs -- 1.8.0.2

Thanks for fixing that. I'm still puzzled about why the problem happened with libvirt. It's better now that stdio doesn't depend on extern-inline, but I worry that whatever bug the libvirt folks were having with stdio and extern inline might crop up when extern inline is used in other include files. One minor improvement is that we can limit the workaround to glibc versions that have the problem, so I pushed this further change. --- ChangeLog | 6 ++++++ lib/stdio.in.h | 8 +++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0bae990..714ee4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-01-03 Paul Eggert <eggert@cs.ucla.edu> + + fwrite: silence __wur only for older glibc versions + * lib/stdio.in.h (fwrite): Limit workaround to glibc 2.4 through 2.15. + This will help us remove this workaround some time in the far future. + 2013-01-03 Eric Blake <eblake@redhat.com> fwrite: silence __wur without using inline diff --git a/lib/stdio.in.h b/lib/stdio.in.h index f9765d1..c345499 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -575,13 +575,15 @@ _GL_CXXALIAS_RPL (fwrite, size_t, _GL_CXXALIAS_SYS (fwrite, size_t, (const void *ptr, size_t s, size_t n, FILE *stream)); -/* Work around glibc bug 11959 +/* Work around bug 11959 when fortifying glibc 2.4 through 2.15 <http://sources.redhat.com/bugzilla/show_bug.cgi?id=11959>, which sometimes causes an unwanted diagnostic for fwrite calls. This affects only function declaration attributes under certain versions of gcc, and is not needed for C++. */ -# if !defined __cplusplus && 0 < __USE_FORTIFY_LEVEL \ - && 3 < (__GNUC__ + (4 <= __GNUC_MINOR__)) +# if (0 < __USE_FORTIFY_LEVEL \ + && __GLIBC__ == 2 && 4 <= __GLIBC_MINOR__ && __GLIBC_MINOR__ <= 15 \ + && 3 < __GNUC__ + (4 <= __GNUC_MINOR__) \ + && !defined __cplusplus) # undef fwrite # define fwrite(a, b, c, d) ({size_t __r = fwrite (a, b, c, d); __r; }) # endif -- 1.7.11.7

On 01/03/2013 11:16 AM, Paul Eggert wrote:
Thanks for fixing that. I'm still puzzled about why the problem happened with libvirt.
Why libvirt, and not detected elsewhere? Probably because libvirt does this at configure time: AH_VERBATIM([FORTIFY_SOURCE], [/* Enable compile-time and run-time bounds-checking, and some warnings, without upsetting newer glibc. */ #if !defined _FORTIFY_SOURCE && defined __OPTIMIZE__ && __OPTIMIZE__ # define _FORTIFY_SOURCE 2 #endif and the inline in question is only turned on when _FORTIFY_SOURCE is enabled. Packages where no one uses _FORTIFY_SOURCE by default would never hit the issue.
It's better now that stdio doesn't depend on extern-inline, but I worry that whatever bug the libvirt folks were having with stdio and extern inline might crop up when extern inline is used in other include files.
The elided code was not using _GL_EXTERN_INLINE, but _GL_INLINE. They have different semantics, but I'm hard-pressed to say _which_ semantics are right from just those names. If I understand correctly, we _want_ the semantics where the inline function is _always_ inlined and never emitted as a linkable entry point, but I'd have to refer back to C99 and the gcc manual to see which use of inline and possible __attribute__ combinations guarantees that point. I've seen code that uses the name ELIDABLE_INLINE for the specific combination we want used in header files; maybe it's worth adding a name _GL_ELIDABLE_INLINE into m4/extern-inline.m4 to make it easier to use the results.
One minor improvement is that we can limit the workaround to glibc versions that have the problem, so I pushed this further change.
Thanks for that improvement. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 01/03/13 12:23, Eric Blake wrote:
The elided code was not using _GL_EXTERN_INLINE, but _GL_INLINE. They have different semantics, but I'm hard-pressed to say _which_ semantics are right from just those names.
Standard C semantics. _GL_EXTERN_INLINE is C99/C11 extern inline. _GL_INILNE is C99/C11 inline.
If I understand correctly, we _want_ the semantics where the inline function is _always_ inlined and never emitted as a linkable entry point, but I'd have to refer back to C99 and the gcc manual to see which use of inline and possible __attribute__ combinations guarantees that point.
Can't be done in Standard C, as far as I know. With GNU C it can be done with __attribute__((__always_inline__)). Why is it important that it not be a linkable entry point?
maybe it's worth adding a name _GL_ELIDABLE_INLINE into m4/extern-inline.m4 to make it easier to use the results.
Sorry, I guess I don't see how this would work. That is, I can see how _GL_ELIDABLE_INLINE would expand to 'inline __attribute__((__always_inline__))' in GNU C, but what would it expand to in Standard C? It can't be expanded to nothing, since you don't want a linkable entry point, and it can't be expanded to 'static', at least not in a header, because the resulting function couldn't be called from an extern inline function.

On 01/03/2013 01:48 PM, Paul Eggert wrote:
Can't be done in Standard C, as far as I know.
Oh well, not worth it then.
With GNU C it can be done with __attribute__((__always_inline__)).
Why is it important that it not be a linkable entry point?
At least in the case libvirt was hitting, multiple files used fwrite, which in turn meant multiple linkable entries for rpl_fwrite were emitted when linking things together; but because they weren't marked 'static', the linker didn't like us. If we are going to have a wrapper inline function in a header, then we want to ensure that the wrapper does not cause duplicate links.
maybe it's worth adding a name _GL_ELIDABLE_INLINE into m4/extern-inline.m4 to make it easier to use the results.
Sorry, I guess I don't see how this would work. That is, I can see how _GL_ELIDABLE_INLINE would expand to 'inline __attribute__((__always_inline__))' in GNU C, but what would it expand to in Standard C? It can't be expanded to nothing, since you don't want a linkable entry point, and it can't be expanded to 'static', at least not in a header, because the resulting function couldn't be called from an extern inline function.
Indeed, that's an annoying limitation. Which goes to show that what we did for fwrite (avoid inline altogether, and instead use GNU C instead of Standard C, to get the workaround we wanted) is really all the best we can do - we have to use a case-by-case analysis of WHY a wrapper is in the header, and either pull the wrapper out of a header and into a real function, or rely on compiler extensions for the cases where the wrapper only makes sense for that compiler. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 01/03/2013 01:00 PM, Eric Blake wrote:
in the case libvirt was hitting, multiple files used fwrite, which in turn meant multiple linkable entries for rpl_fwrite were emitted when linking things together; but because they weren't marked 'static', the linker didn't like us.
OK, but surely this problem would happen with any extern symbol that gnulib defines. I.e., it's not a problem specific to extern inline functions; it's a problem with externs in general. Isn't the "right" way to handle this, from the gnulib point of view, the lib-symbol-visibility module? Shouldn't libvirt be using that? If libvirt was compiled with -fvisibility=hidden then any miscellanous extern functions that it defined would be local to the libvirt .so, and wouldn't clash with similarly-named functions in other shared objects.
what we did for fwrite (avoid inline altogether, and instead use GNU C instead of Standard C, to get the workaround we wanted) is really all the best we can do
I hope that's not the case, because it pretty much means that there's no portable way to use inline functions in gnulib headers that contribute to shared objects.

Build failure detected by Jenkins autobuilder: http://honk.sigxcpu.org:8001/job/libvirt-build/472/changes * .gnulib: Update to latest, for stdio.h rpl_fwrite fix. --- Pushing under the build-breaker rule. I managed to reproduce the link failure on a RHEL 6 box with CFLAGS='-g -O2', and also that this gnulib update made it go away. * .gnulib 964bbc2...61c7b1e (2):
fwrite: silence __wur without using inline update-copyright: avoid copyright notice date corruption
.gnulib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gnulib b/.gnulib index 964bbc2..61c7b1e 160000 --- a/.gnulib +++ b/.gnulib @@ -1 +1 @@ -Subproject commit 964bbc2d419584e93fe629ddbc40595612f62083 +Subproject commit 61c7b1e32e11e9e40b4d59ab888a807620befcd3 -- 1.8.0.2

On Thu, Jan 03, 2013 at 10:15:06AM -0700, Eric Blake wrote:
Build failure detected by Jenkins autobuilder: http://honk.sigxcpu.org:8001/job/libvirt-build/472/changes
* .gnulib: Update to latest, for stdio.h rpl_fwrite fix.
That fixed it. Thanks a lot! As of the latest update I'm seeing spurious SIGSEGV on make invocations. I'll diagnose these first until I turn the list mails back on. Cheers, -- Guido
---
Pushing under the build-breaker rule. I managed to reproduce the link failure on a RHEL 6 box with CFLAGS='-g -O2', and also that this gnulib update made it go away.
* .gnulib 964bbc2...61c7b1e (2):
fwrite: silence __wur without using inline update-copyright: avoid copyright notice date corruption
.gnulib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.gnulib b/.gnulib index 964bbc2..61c7b1e 160000 --- a/.gnulib +++ b/.gnulib @@ -1 +1 @@ -Subproject commit 964bbc2d419584e93fe629ddbc40595612f62083 +Subproject commit 61c7b1e32e11e9e40b4d59ab888a807620befcd3 -- 1.8.0.2
participants (4)
-
Eric Blake
-
Guido Günther
-
Jenkins CI
-
Paul Eggert