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

Reply via email to