Apache OpenOffice (AOO) Bugzilla – Issue 34676
gcc 3.4.2 locks static locals with __cxa_guard_acquire/__cxa_guard_release
Last modified: 2005-03-07 12:26:12 UTC
This would be fine, a minor issue is that we already double lock our local statics (at least in theory), so we now have extra locking. The major issue is that __cxa_guard... are in libstdc++ so libsal which has some local statics now has link requirements when compiled with gcc 3.4.2 against these symbols which are in libstdc++, which libsal doesn't link against for its own abi reasons. If we wish to continue refraining from linking against libstdc++ perhaps a hack like the attached patch would be sufficient. Or maybe there is a different way to approach the issue
Created attachment 17949 [details] example patch
The error log is... ../unxlngi4.pro/slo/uuid.o(.text+0x1a2): In function `getInt16RandomValue(unsigned long long)': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/uuid.o(.text+0x1b9): In function `getInt16RandomValue(unsigned long long)': : undefined reference to `__cxa_guard_release' ../unxlngi4.pro/slo/bootstrap.o(.text+0x34): In function `getFromCommandLineArgs(_rtl_uString**, _rtl_uString*)': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/bootstrap.o(.text+0x5d): In function `getFromCommandLineArgs(_rtl_uString**, _rtl_uString*)': : undefined reference to `__cxa_guard_release' ../unxlngi4.pro/slo/bootstrap.o(.text+0x737): In function `getIniFileNameImpl()': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/bootstrap.o(.text+0x75b): In function `getIniFileNameImpl()': : undefined reference to `__cxa_guard_release' ../unxlngi4.pro/slo/bootstrap.o(.gnu.linkonce.t._ZN3rtl14StaticInstanceIN4_STL4listI23rtl_bootstrap_NameValueN3sal9AllocatorIS3_EEEEN85_GLOBAL__N__home_cmc_ooocvs_SRC680_m54_sal_rtl_source_bootstrap.cxx_CF4CBC2E_BD6C99D922rtl_bootstrap_set_listEEclEv+0x26): In function `rtl::StaticInstance<_STL::list<rtl_bootstrap_NameValue, sal::Allocator<rtl_bootstrap_NameValue> >, (anonymous namespace)::rtl_bootstrap_set_list>::operator()()': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/bootstrap.o(.gnu.linkonce.t._ZN3rtl14StaticInstanceIN4_STL4listI23rtl_bootstrap_NameValueN3sal9AllocatorIS3_EEEEN85_GLOBAL__N__home_cmc_ooocvs_SRC680_m54_sal_rtl_source_bootstrap.cxx_CF4CBC2E_BD6C99D922rtl_bootstrap_set_listEEclEv+0x47): In function `rtl::StaticInstance<_STL::list<rtl_bootstrap_NameValue, sal::Allocator<rtl_bootstrap_NameValue> >, (anonymous namespace)::rtl_bootstrap_set_list>::operator()()': : undefined reference to `__cxa_guard_release' ../unxlngi4.pro/slo/bootstrap.o(.gnu.linkonce.t._ZN3rtl14StaticInstanceIN4_STL8hash_mapINS_8OUStringEP14Bootstrap_ImplNS_12OUStringHashENS1_8equal_toIS3_EEN3sal9AllocatorIS3_EEEEN85_GLOBAL__N__home_cmc_ooocvs_SRC680_m54_sal_rtl_source_bootstrap.cxx_CF4CBC2E_BD6C99D913bootstrap_mapEEclEv+0x26): In function `rtl::StaticInstance<_STL::hash_map<rtl::OUString, Bootstrap_Impl*, rtl::OUStringHash, _STL::equal_to<rtl::OUString>, sal::Allocator<rtl::OUString> >, (anonymous namespace)::bootstrap_map>::operator()()': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/bootstrap.o(.gnu.linkonce.t._ZN3rtl14StaticInstanceIN4_STL8hash_mapINS_8OUStringEP14Bootstrap_ImplNS_12OUStringHashENS1_8equal_toIS3_EEN3sal9AllocatorIS3_EEEEN85_GLOBAL__N__home_cmc_ooocvs_SRC680_m54_sal_rtl_source_bootstrap.cxx_CF4CBC2E_BD6C99D913bootstrap_mapEEclEv+0x40): In function `rtl::StaticInstance<_STL::hash_map<rtl::OUString, Bootstrap_Impl*, rtl::OUStringHash, _STL::equal_to<rtl::OUString>, sal::Allocator<rtl::OUString> >, (anonymous namespace)::bootstrap_map>::operator()()': : undefined reference to `__cxa_guard_release' ../unxlngi4.pro/slo/cmdargs.o(.text+0xfb): In function `impl_rtl_initCommandArgs()': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/cmdargs.o(.text+0x107): In function `impl_rtl_initCommandArgs()': : undefined reference to `__cxa_guard_release' ../unxlngi4.pro/slo/macro.o(.gnu.linkonce.t._ZN3rtl14StaticInstanceIN4_STL8hash_setINS_8OUStringENS_12OUStringHashENS1_8equal_toIS3_EEN3sal9AllocatorIS3_EEEEN81_GLOBAL__N__home_cmc_ooocvs_SRC680_m54_sal_rtl_source_macro.cxx_CF4CBC2E_5C013EE77lookupsEEclEv+0x26): In function `rtl::StaticInstance<_STL::hash_set<rtl::OUString, rtl::OUStringHash, _STL::equal_to<rtl::OUString>, sal::Allocator<rtl::OUString> >, (anonymous namespace)::lookups>::operator()()': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/macro.o(.gnu.linkonce.t._ZN3rtl14StaticInstanceIN4_STL8hash_setINS_8OUStringENS_12OUStringHashENS1_8equal_toIS3_EEN3sal9AllocatorIS3_EEEEN81_GLOBAL__N__home_cmc_ooocvs_SRC680_m54_sal_rtl_source_macro.cxx_CF4CBC2E_5C013EE77lookupsEEclEv+0x40): In function `rtl::StaticInstance<_STL::hash_set<rtl::OUString, rtl::OUStringHash, _STL::equal_to<rtl::OUString>, sal::Allocator<rtl::OUString> >, (anonymous namespace)::lookups>::operator()()': : undefined reference to `__cxa_guard_release' ../unxlngi4.pro/slo/unload.o(.text+0x1b2): In function `getUnloadingMutex()': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/unload.o(.text+0x1c9): In function `getUnloadingMutex()': : undefined reference to `__cxa_guard_release' ../unxlngi4.pro/slo/unload.o(.text+0x326): In function `getModuleMap()': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/unload.o(.text+0x340): In function `getModuleMap()': : undefined reference to `__cxa_guard_release' ../unxlngi4.pro/slo/unload.o(.text+0x89a): In function `getListenerMap()': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/unload.o(.text+0x8b4): In function `getListenerMap()': : undefined reference to `__cxa_guard_release' ../unxlngi4.pro/slo/unload.o(.text+0x97d): In function `getCookieQueue()': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/unload.o(.text+0x9a6): In function `getCookieQueue()': : undefined reference to `__cxa_guard_release' ../unxlngi4.pro/slo/logfile.o(.text+0x1c4): In function `getLogMutex()': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/logfile.o(.text+0x1db): In function `getLogMutex()': : undefined reference to `__cxa_guard_release' ../unxlngi4.pro/slo/logfile.o(.text+0x56e): In function `rtl_logfile_trace': : undefined reference to `__cxa_guard_acquire' ../unxlngi4.pro/slo/logfile.o(.text+0x57a): In function `rtl_logfile_trace': : undefined reference to `__cxa_guard_release' collect2: ld returned 1 exit status dmake: Error code 1, while making '../unxlngi4.pro/lib/libsal.so.3.1.0' '---* tg_merge.mk *---'
The other solution is to simply add -fno-threadsafe-statics to the gcc options. Seems a pity to lose the builtin new useful auto-lock behaviour of gcc though :-( cmc->sb: You've expressed interest in c++ thread-safe local static variables in the past
sb->cmc: A few things confuse me here: 1 For the Sun StarOffice/OpenOffice.org builds, it appears that for SRC680 (i.e., OOo 2.x) libsal is linked against libstdc++, while for SRX645 (i.e., OOo 1.x) it is not. Strange that for non-Sun SRC680 builds libsal is not linked against libstdc++. 2 Do you use a modified gcc 3.4.2? When I compile a simple test program with gcc 3.4.2, the generated code does not call __cxa_guard_acquire/release. Also, the online manual for gcc 3.4.2 does not mention -f[no-]threadsafe-statics. And, looking at the source of gcc 3.4.2 libstdc++ guard.cc, it is doubtful whether these functions are indeed used to implement thread-safe initialization of statics (I cannot check it, as I cannot bring gcc to emit code that uses the functions). (I checked the recent Sun SRC680 builds that use gcc 3.4.1: no calls to __cxa_guard_acquire/release there, either.)
1 re: it appears that for SRC680 (i.e., OOo 2.x) libsal is linked against libstdc++ With my 1.9.54 build the link line is gcc -z combreloc -z defs -Wl,-rpath,'$ORIGIN' "-Wl,-hlibsal.so.3" -shared -Wl,-O1 -Wl,--version-script ../unxlngi4.pro/misc/sal_sal.map -L../unxlngi4.pro/lib -L../lib -L/usr/home/cmc/ooocvs/SRC680_m54/solenv/unxlngi4/lib -L/usr/home/cmc/ooocvs/SRC680_m54/solver/680/unxlngi4.pro/lib -L/usr/home/cmc/ooocvs/SRC680_m54/solenv/unxlngi4/lib -L/opt/blackdown-jdk-1.4.2_rc1/lib -L/opt/blackdown-jdk-1.4.2_rc1/jre/lib/i386 -L/opt/blackdown-jdk-1.4.2_rc1/jre/lib/i386/client -L/opt/blackdown-jdk-1.4.2_rc1/jre/lib/i386/native_threads -L/usr/X11R6/lib ../unxlngi4.pro/slo/sal_version.o ../unxlngi4.pro/slo/sal_description.o -o ../unxlngi4.pro/lib/libsal.so.3.1.0 ../unxlngi4.pro/slo/utility.o ../unxlngi4.pro/slo/readline.o ../unxlngi4.pro/slo/filepath.o ../unxlngi4.pro/slo/conditn.o ../unxlngi4.pro/slo/diagnose.o ../unxlngi4.pro/slo/semaphor.o ../unxlngi4.pro/slo/socket.o ../unxlngi4.pro/slo/interlck.o ../unxlngi4.pro/slo/mutex.o ../unxlngi4.pro/slo/nlsupport.o ../unxlngi4.pro/slo/thread.o ../unxlngi4.pro/slo/module.o ../unxlngi4.pro/slo/process.o ../unxlngi4.pro/slo/security.o ../unxlngi4.pro/slo/profile.o ../unxlngi4.pro/slo/time.o ../unxlngi4.pro/slo/file.o ../unxlngi4.pro/slo/signal.o ../unxlngi4.pro/slo/pipe.o ../unxlngi4.pro/slo/system.o ../unxlngi4.pro/slo/util.o ../unxlngi4.pro/slo/tempfile.o ../unxlngi4.pro/slo/file_url.o ../unxlngi4.pro/slo/file_error_transl.o ../unxlngi4.pro/slo/file_path_helper.o ../unxlngi4.pro/slo/uunxapi.o ../unxlngi4.pro/slo/process_impl.o ../unxlngi4.pro/slo/file_stat.o ../unxlngi4.pro/slo/alloc.o ../unxlngi4.pro/slo/memory.o ../unxlngi4.pro/slo/cipher.o ../unxlngi4.pro/slo/crc.o ../unxlngi4.pro/slo/digest.o ../unxlngi4.pro/slo/random.o ../unxlngi4.pro/slo/locale.o ../unxlngi4.pro/slo/strimp.o ../unxlngi4.pro/slo/string.o ../unxlngi4.pro/slo/ustring.o ../unxlngi4.pro/slo/strbuf.o ../unxlngi4.pro/slo/ustrbuf.o ../unxlngi4.pro/slo/uuid.o ../unxlngi4.pro/slo/rtl_process.o ../unxlngi4.pro/slo/byteseq.o ../unxlngi4.pro/slo/uri.o ../unxlngi4.pro/slo/bootstrap.o ../unxlngi4.pro/slo/cmdargs.o ../unxlngi4.pro/slo/macro.o ../unxlngi4.pro/slo/unload.o ../unxlngi4.pro/slo/logfile.o ../unxlngi4.pro/slo/tres.o ../unxlngi4.pro/slo/math.o ../unxlngi4.pro/slo/context.o ../unxlngi4.pro/slo/convertbig5hkscs.o ../unxlngi4.pro/slo/converter.o ../unxlngi4.pro/slo/converteuctw.o ../unxlngi4.pro/slo/convertgb18030.o ../unxlngi4.pro/slo/convertiso2022cn.o ../unxlngi4.pro/slo/convertiso2022jp.o ../unxlngi4.pro/slo/convertiso2022kr.o ../unxlngi4.pro/slo/convertsinglebytetobmpunicode.o ../unxlngi4.pro/slo/tcvtbyte.o ../unxlngi4.pro/slo/tcvtmb.o ../unxlngi4.pro/slo/tcvtutf7.o ../unxlngi4.pro/slo/tcvtutf8.o ../unxlngi4.pro/slo/tenchelp.o ../unxlngi4.pro/slo/tencinfo.o ../unxlngi4.pro/slo/textcvt.o ../unxlngi4.pro/slo/textenc.o ../unxlngi4.pro/slo/unichars.o -ldl -lpthread -lm i.e. no link against libstdc++. And when we discussed using the system stl I thought the showstopper against that was that it would force linking against libstdc++ which would compromise the ABI? So I'm surprised to hear that libsal would link against libstdc++. 2. re: Do you use a modified gcc 3.4.2? hmm, well as it seems to turn out "sort of". http://gcc.gnu.org/ml/gcc-patches/2004-08/msg01598.html, apparently the code to do this is committed to the mainline stable 3.4 branch which is what is used on redhat's fedora, though not seperately released yet outside of a cvs snapshot. This should be on the way in a formal release-for-everyone-else like 3.4.3. So perhaps its a little early to worry about it if it only affects fedora users right now, but it will on the next stable gcc release.
1 re:re: it appears that for SRC680 (i.e., OOo 2.x) libsal is linked against libstdc++ I think the magic difference is that Sun uses unxlngi5/6, where on SRC680 g++ is always used instead of gcc for linking (see thread "[Fwd: [ucb-dev] Problems on Linux with GCC-3.3--built components]" on openoffice.udk.dev, starting Sept 2, 2003), whereas non-Sun uses unxlngi4, where on SRC680 gcc is still used. For unxlngi5/6 this means that ld always records a NEEDS libstdc++, even if a library does not need any symbols from it (as is the case for libsal). That unnecessary dependency is rather harmless (we should see to remove it, though). The problem with STL was different: Some UDK libraries use STL types in their exported interfaces, and if two STL versions have different type layouts, that would break compatibility.
Ah right, now I get you on the ABI thing. This reminds me that there is also an issue with rtti being disabled in unxlngi4.mk which causes vcl to crash as it now depends on it. So with that in mind, and the difference in linking between unxlngi4.mk and later .mk it looks to me that unxlngi4.mk (which is the default for the OOo builds created through the ./configure etc route) is suffering some bitrot. So if the community config_office/set_soenv.in is updated to use a later unxlngi?.mk, or unxlngi4.mk updated with the LINK (and rtti) change. then this problem would go away on its own for us now, and for you later on when a gcc release includes this new feature.
I think Ause is working with Ken Foskey on aligning the Sun/non-Sun build envs, so the problem of undefined symbol references should indeed go away (until we decide for some reason to link C-only libraries like sal with gcc instead of g++ again...). Once the threadsafe-statics gcc patch appears in a released gcc version, we should revisit how we use it: - Either we use -fno-threadsafe-statics and stay with our cross-platform rtl_Instance/rtl::Static approach unmodified. - Or we place #ifdefs into rtl_Instance/rtl::Static to either do its current single instantiation stuff, or rely on the compiler to already get that right where available. The advantage would be that this also fixes (for GCC platforms, at least) code that inadvertantly lacks use of rtl_Instance/rtl::Static but can suffer from multiple threads initializing a static object more than once. Note that I think the proposed gcc patch has an (obscure) problem that might make it necessary to check whether this approach is indeed applicable for OOo, see http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02845.html
"#ifdefs into rtl_Instance/rtl::Static to either do its current single instantiation stuff, or rely on the compiler to already get that right where available." sounds nicest to me, as you say we get the advantage of fixed currently unprotected local static, and it would seem unfortunate to penalise gcc for introducing a threadsafe feature by then quadruple locking the variables. cmc->mh: so how about just right now changing unxlngi4.mk to link like unxlngi5/6.mk with g++ instead of gcc ?
mh->cmc: it would be more consistent to change configure scripts to use unxlngi6 instead of unxlngi4 ?!
sure, but probably should mention it on dev@ in that case. Perhaps there are accumulated porting hacks and so on in unxlngi4.mk which I'm unaware of which aren't reflected in unxlngi6.mk.
it's not clear to me, what is now expected to be done ?
Martin, We either need to implement these symbols ourselves (bad), or link against libsupc++.a which is where these are defined. --- sal/util/makefile.mk.foo 2004-12-21 14:38:37.314521336 -0500 +++ sal/util/makefile.mk 2004-12-21 14:46:52.495159848 -0500 @@ -146,6 +146,10 @@ SHL1STDLIBS+=-init InitLibrary -term ExitLibrary .ENDIF # MAC +.IF "$(OS)"=="LINUX" +SHL1STDLIBS+= -Wl,-Bstatic -lsupc++ -Wl,-Bdynamic -lgcc_s +.ENDIF + .IF "$(GUI)"=="UNX" .IF "$(OS)"=="SOLARIS" # libposix4.so (SunOS 5.6) <-> librt.so (SunOS >= 5.7)
Obviously, we should only link to libsupc++.a if we are using gcc >= 3.4, but I don't see a way to do that offhand. CVER=300 isn't good enough, do we even have an environment variable set up with actual compiler version rather than just "this is gcc3" like CVER seems to be?
cmc->mh: This is only a matter for fedora people and unxlngi4.pro at the moment because our gcc guys backported some stuff from the gcc4. With unxlngi6.pro the linker is CXX and the problem isn't there. So I'd forget about this subissue and just consider its resolution a happy outcome of moving to unxlngi6.pro for gcc > 3.4 from configure. I can take care of rounding up the unxlngi4->unxlngi6 configure.in alternatives and do this under #i41026# if you want to close this out.
doesn't matter anymore with LINK as g++ under unxlngi6 when compiler version is >= 3.4.1
close