Beginning in GCC 4.6.0 we started seeing various package failures at runtime with the message: symbol lookup error: /usr/lib/gcc/x86_64-pc-linux-gnu/4.6.0/libstdc++.so.6: undefined symbol: _ZNSt14error_categoryD2Ev, version GLIBCXX_3.4.15 It appears to be triggered when you have a program written in C that dlopens C++ shared objects. I've seen this bug reported in several distro's bug trackers for various packages. There are several real-world examples at [1]. Harald van Dijk did some investigating and came up with a minimal testcase, and explains the bug better than I can, so I will include his mail below. My question is whether this is a bug in libstdc++ or in glibc and what we can do about it. It appears the change that led to this behaviour was http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00745.html (r171051). [1] https://bugs.gentoo.org/364077 Begin forwarded message: Date: Fri, 08 Jul 2011 18:33:58 +0200 From: Harald van Dijk <harald@xxxxxxxxxxx> To: dirtyepic@xxxxxxxxxx Subject: Gentoo bug #364077: undefined symbol: _ZNSt14error_categoryD2Ev Hi, I've had the same problem as mentioned in that bug, with gcc 4.6.1. Searching, I found that others suffers from the same problem, and Gentoo and Arch seem to take it seriously, but I see no solution or proper workaround. So I looked into it and thought I'd let you know what I found so far. Firstly, here's a minimal testcase to expose the problem: $ cat test.c #include <dlfcn.h> #include <assert.h> int main(void) { void *so1, *so2; so1 = dlopen("./test1.so", RTLD_LAZY); assert(so1); so2 = dlopen("./test2.so", RTLD_LAZY); assert(so2); dlclose(so1); dlclose(so2); return 0; } $ gcc test.c -o test -ldl $ gcc -fPIC -shared -xc /dev/null -o test1.so $ g++ -fPIC -shared -xc++ /dev/null -o test2.so $ ./test Reordering the dlclose calls alters the behaviour. With RTLD_NOW, it works with either dlclose ordering. Secondly, the reason this works with gcc 4.5 is because error_category's destructor was implicitly inline. Its definition has moved, and it is no longer inline in 4.6, but that change exposed this bug, so until the underlying bug is fixed I will hide the problem like this on my system: --- gcc-4.6.1/libstdc++-v3/include/std/system_error +++ gcc-4.6.1/libstdc++-v3/include/std/system_error @@ -102,6 +102,10 @@ { return this != &__other; } }; + inline error_category::error_category() = default; + + inline error_category::~error_category() = default; + // DR 890. _GLIBCXX_CONST const error_category& system_category() throw(); _GLIBCXX_CONST const error_category& generic_category() throw(); --- gcc-4.6.1/libstdc++-v3/src/system_error.cc +++ gcc-4.6.1/libstdc++-v3/src/system_error.cc @@ -74,10 +74,6 @@ { _GLIBCXX_BEGIN_NAMESPACE_VERSION - error_category::error_category() = default; - - error_category::~error_category() = default; - const error_category& system_category() throw() { return system_category_instance; } With this change, my minimal test runs, and nss builds and shlibsign is functional when not setting LD_BIND_NOW. Note that this is an ABI change, as reported by the newly added FAIL: libstdc++-abi/abi_check when running tests. This looks to me like a glibc bug, but perhaps libstdc++ is really doing something that is not supported by glibc. Cheers, Harald -- fonts, gcc-porting, it makes no sense how it makes no sense toolchain, wxwidgets but i'll take it free anytime @ gentoo.org EFFD 380E 047A 4B51 D2BD C64F 8AA8 8346 F9A4 0662
Attachment:
signature.asc
Description: PGP signature