gcc (GCC) 4.0.2 20050901 (prerelease) (SUSE Linux) SUSE Linux 10.0 i686 I don'know, if this is a gcc or elf bug. I use the following construct:
Slib1 => Dlib1 Slib1 + Dlib1 => Dlib2 Test => dlopen/dlclose (Dlib2) Slib1 is a static lib. Dlib1 is a shared lib containing Slib1. Dlib2 is a shared lib containing Dlib1 and Slib1. After building the libraries with hidden visibility: tmp/demo/lib/linuxrelease> readelf -s -W -D libdlib1.so | c++filt ... 14 15: 00001a80 4 OBJECT GLOBAL DEFAULT 23 SLibC1::m_str ... tmp/demo/lib/linuxrelease> readelf -s -W -D libdlib2.so | c++filt ... 14 15: 00001ad8 4 OBJECT GLOBAL DEFAULT 23 SLibC1::m_str ... Both Dso-s will have the static member SLibC1::m_str with DEFAULT visibility. If you try to load / read symbol / close / load the Dso libdlib2.so, it will crash with the following error message: *** glibc detected *** double free or corruption (fasttop): 0x0804b888 *** If you set: export MALLOC_CHECK_=3 you can see in the debugger, that calling the global dtor in libdlib2.so at ~SLibC1::m_str() causes the crash. If you change hash_map to map in the example below (comment the line #define BUG 1), the test is OK. In this case the visibility of SLibC1::m_str is hidden. If this problem already known, does a workaround exist? I will supply the automake files. Without them I could not reproduce bug(?). I try to upload the whole configuration, but here are source files in the following tree: (how can I upload an attachment?) . |-- AUTHORS <= dummy |-- COPYING <= dummy |-- ChangeLog <= dummy |-- INSTALL <= dummy |-- NEWS <= dummy |-- README <= dummy |-- configure.ac |-- dlib1 | |-- dlib1_m1.cpp | `-- makefile.am |-- dlib2 | |-- dlib2_m1.cpp | `-- makefile.am |-- lib |-- makefile.am `-- stlib1 |-- makefile.am `-- stlib1_m1.cpp >>>>>>> stlib1_m1.cpp #include <string> #define BUG 1 #ifdef BUG #include <ext/hash_map> class SLibC1 : public __gnu_cxx::hash_map<int, int > #else #include <map> class SLibC1 : public std::map<int, int > #endif { public: static const std::string m_str; }; const std::string SLibC1::m_str = "SLibC1 1.0"; <<<<EOF>>>> >>>>>>> dlib1_m1.cpp struct __attribute__ ((visibility("default"))) Dlib1C1 { void Dlib1Func1() {} }; <<<<EOF>>>> >>>>>>> dlib2_m1.cpp struct __attribute__ ((visibility("default"))) Dlib2C1 { void Dlib2Func1() {}; }; <<<<EOF>>>> >>>>>>> configure.ac _dnl Process this file with autoconf to produce a configure script. AC_INIT([PSP],[pre]) AM_INIT_AUTOMAKE dnl Checks for programs. AC_PROG_LIBTOOL #AC_PROG_RANLIB AC_PROG_CXX AC_PROG_CPP AC_PROG_CC AC_LANG(C++) abs_top_srcdir=`pwd` VERSION_INFO="-avoid-version" AC_CONFIG_FILES([dlib1/makefile]) AC_CONFIG_FILES([dlib2/makefile]) AC_CONFIG_FILES([stlib1/makefile]) PRODNAME="linuxrelease" CXXFLAGS=" -fvisibility=hidden -fvisibility-inlines-hidden -D_Linux " CFLAGS=$CFLAGS" -fvisibility=hidden -D_Linux " ALD_FLAGS=" -no-undefined" SYSLIBS="-ldl" AM_CONFIG_HEADER([config.h]) AC_CONFIG_FILES([makefile]) dnl Checks for libraries. dnl Checks for header files. dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_C_BIGENDIAN AC_TYPE_SIZE_T dnl Checks for library functions. AC_SUBST(abs_top_srcdir) AC_SUBST(PRODNAME) AC_SUBST(AINC_PATH) AC_SUBST(ALD_FLAGS) AC_SUBST(SYSLIBS) AC_SUBST(VERSION_INFO) AC_OUTPUT([]) <<<<EOF>>>> >>>>>>> ./makefile.am SUBDIRS = stlib1 dlib1 dlib2 exe <<<<EOF>>>> >>>>>>> stlib1/makefile.am libdir = ${abs_top_srcdir}/lib/@PRODNAME@ lib_LTLIBRARIES = libstlib1.la libstlib1_la_LDFLAGS = -all-static libstlib1_la_LIBADD = libstlib1_la_SOURCES = stlib1_m1.cpp libstlib1_la_CPPFLAGS = -D_LIB -I${top_srcdir}/inc @AINC_PATH@ install-exec-local: mkdir -p $(libdir)/.libs && \ sed -e "1s/libstlib1.la/libstlib1_noi.la/;s/^old_library=.*/old_library='..\/libstlib1.a'/;s/^installed=.*/installed=no/;s/^libdir=.*/libdir=''/" libstlib1.la >$(libdir)/libstlib1_noi.la <<<<EOF>>>> >>>>>>> dlib1/makefile.am libdir = ${abs_top_srcdir}/lib/@PRODNAME@ lib_LTLIBRARIES = libdlib1.la libdlib1_la_LDFLAGS = @VERSION_INFO@ @ALD_FLAGS@ -L${abs_top_srcdir}/lib/@PRODNAME@ libdlib1_la_SOURCES = dlib1_m1.cpp libdlib1_la_LIBADD = -lstlib1 @SYSLIBS@ libdlib1_la_CPPFLAGS = -D_USRDLL -DDLIB1_EXPORTS -I${top_srcdir}/stlib1 -I${top_srcdir}/inc @AINC_PATH@ install-exec-local: rm -f $(libdir)/libdlib1.a && \ touch $(libdir)/_x.o && \ ar cru $(libdir)/libdlib1.a $(libdir)/_x.o && \ ranlib $(libdir)/libdlib1.a && \ cp $(libdir)/libdlib1.a .libs/ && \ rm -f $(libdir)/_x.o <<<<EOF>>>> >>>>>>> dlib2/makefile.am libdir = ${abs_top_srcdir}/lib/@PRODNAME@ lib_LTLIBRARIES = libdlib2.la libdlib2_la_LDFLAGS = @VERSION_INFO@ @ALD_FLAGS@ -L${abs_top_srcdir}/lib/@PRODNAME@ libdlib2_la_SOURCES = dlib2_m1.cpp libdlib2_la_LIBADD = -ldlib1 -lstlib1 @SYSLIBS@ libdlib2_la_CPPFLAGS = -D_USRDLL -DDLIB2_EXPORTS -I${top_srcdir}/stlib1 -I${top_srcdir}/dlib1 -I${top_srcdir}/inc @AINC_PATH@ install-exec-local: rm -f $(libdir)/libdlib2.a && \ touch $(libdir)/_x.o && \ ar cru $(libdir)/libdlib2.a $(libdir)/_x.o && \ ranlib $(libdir)/libdlib2.a && \ cp $(libdir)/libdlib2.a .libs/ && \ rm -f $(libdir)/_x.o <<<<EOF>>>> Installation: go to the installation dir, and issue: libtoolize --force aclocal autoheader autoconf automake --add-missing --warning=portability --warning=obsolete ./configure make install cd lib/linuxrelease readelf -s -W -D libdlib1.so | c++filt -- Summary: hidden visibility of static member in class derived from hash_map changes to default visibility Product: gcc Version: 4.0.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: laszlo dot szakony at philips dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26846