Hi,

I have a copy of Inkscape compiled with GCC 3.3, running on a GCC 3.4
based system. All of the C++ libraries it links directly against, like
GTKmm, are statically linked. In other words, it dynamically links
against no C++ libraries.

Inkscape dlopens libgtkspell, which in turn dlopens libaspell (to add
a spelling checker). libgtkspell is written in C, but libaspell is written
in C++ and exposes a C interface.

This causes a crash, even though the GCC documentation explicitly says
this should work because the C++ standard library has symbol versioning
applied so the usual ELF cross-wiring mess is (theoretically) avoided.

But this isn't what happens. Here is an LD_DEBUG=binding trace at the
point of the crash:

     17179:     binding file /usr/lib/libaspell.so.15 to 
/usr/lib/libstdc++.so.6: normal symbol `_ZNKSs5rfindEcj' [GLIBCXX_3.4]
     17179:     binding file /usr/lib/libaspell.so.15 to 
/usr/lib/libaspell.so.15: normal symbol 
`_ZN8aspeller9find_fileERN7acommon6StringERKS1_S4_S4_PKc'
     17179:     binding file /usr/lib/libaspell.so.15 to 
/usr/lib/libstdc++.so.5: normal symbol 
`_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_'
     17179:     binding file /usr/lib/libstdc++.so.5 to 
/usr/lib/libstdc++.so.5: normal symbol `_ZNSsC1ERKSs' [GLIBCPP_3.2]
     17179:     binding file /usr/lib/libstdc++.so.5 to 
/usr/lib/libstdc++.so.5: normal symbol `_ZNSs6appendERKSs' [GLIBCPP_3.2]
     17179:     binding file /usr/lib/libaspell.so.15 to 
/usr/lib/libstdc++.so.6: normal symbol `_ZNSsC1ERKSs' [GLIBCXX_3.4]
     17179:     binding file ./inkscape.stripped to /lib/tls/libc.so.6: normal 
symbol `fprintf' [GLIBC_2.0]
Emergency save activated!

Just before the last line, the std::string destructor calls free on an
invalid pointer, which glibc detects and triggers an abort (which in turn
triggers an emergency save).

Note that on the first line libaspell is being bound to libstdc++.so.6,
which is what I'd expect as libaspell is compiled using gcc 3.4 - and
indeed up until this point it's been linked only against libstdc++.so.6.
Then for some reason it's linked against libstdc++.so.5, for the following
symbol:

_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_

or

std::basic_string<char, std::char_traits<char>, std::allocator<char> >
std::operator+<char, std::char_traits<char>, std::allocator<char>
>(std::basic_string<char, std::char_traits<char>, std::allocator<char> >
const&, std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&)

This symbol does exist in v6 of the library:

  2471: 009ac084   145 FUNC    WEAK   DEFAULT   11 
_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_@@GLIBCXX_3.4

but it's also defined in v5:

  2492: 0311d2a0    98 FUNC    WEAK   DEFAULT   11 
_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_@@GLIBCPP_3.2.1

and for some reason (first in the link order I guess) it takes precedence. 

I don't know exactly what revisions of the C++ ABI spec gcc 3.3 and 3.4 
implement 
(does anybody know? It'd be nice to be able to see exactly what changed) but I 
guess these two symbols aren't compatible. I'm not sure why the symbol 
versioning 
is being ignored.

Can anybody help me?

thanks -mike

Reply via email to