C++ runtime version patch for testing
Hi All, Here is a patch that, I believe, should fix the symbol version mismatches between the runtime and the STL implementation. I have run the exception tests from libcxxrt with this patch applied and: - libsupc++ libstdc++ - libcxxrt libstdc++ - libcxxrt libc++ All tests pass for me now. Please let me know if there are any problems with this, otherwise I'll aim to commit it today or tomorrow with a 1-week MFC. David Index: gnu/lib/libsupc++/Version.map === --- gnu/lib/libsupc++/Version.map (revision 245840) +++ gnu/lib/libsupc++/Version.map (working copy) @@ -142,6 +142,28 @@ _ZdaPvRKSt9nothrow_t; _ZdlPv; _ZdlPvRKSt9nothrow_t; +extern C++ { + std::set_new_handler*; + std::set_terminate*; + std::set_unexpected*; + std::bad_alloc*; + + std::bad_alloc*; + std::bad_cast*; + std::exception*; + + typeinfo for std::bad_alloc; + typeinfo for std::bad_cast; + typeinfo for std::exception; + + typeinfo name for std::bad_alloc; + typeinfo name for std::bad_cast; + typeinfo name for std::exception; + + vtable for std::bad_alloc; + vtable for std::bad_cast; + vtable for std::exception; +}; }; CXXABI_1.3.1 { Index: lib/libcxxrt/Version.map === --- lib/libcxxrt/Version.map(revision 245840) +++ lib/libcxxrt/Version.map(working copy) @@ -209,18 +209,7 @@ std::type_info::type_info(std::type_info const); std::type_info::type_info(std::type_info const); -std::type_info::~type_info(); -std::type_info::~type_info(); -std::type_info::~type_info(); std::type_info::operator=(std::type_info const); -std::unexpected(); -std::get_terminate(); -std::set_terminate(void (*)()); -std::get_unexpected(); -std::set_unexpected(void (*)()); -std::set_new_handler(void (*)()); -std::uncaught_exception(); -std::terminate(); # Extensions @@ -243,70 +232,25 @@ CXXRT_1.0 { extern C++ { -std::bad_cast::what() const; -std::bad_typeid::what() const; -std::bad_alloc::what() const; -std::exception::what() const; std::type_info::name() const; std::type_info::before(std::type_info const) const; std::type_info::operator==(std::type_info const) const; std::type_info::operator!=(std::type_info const) const; -std::bad_typeid::bad_typeid(std::bad_typeid const); -std::bad_typeid::bad_typeid(); -std::bad_typeid::bad_typeid(std::bad_typeid const); -std::bad_typeid::bad_typeid(); -std::bad_typeid::~bad_typeid(); -std::bad_typeid::~bad_typeid(); -std::bad_typeid::~bad_typeid(); -std::bad_typeid::operator=(std::bad_typeid const); std::bad_cast::bad_cast(std::bad_cast const); std::bad_cast::bad_cast(); std::bad_cast::bad_cast(std::bad_cast const); std::bad_cast::bad_cast(); -std::bad_cast::~bad_cast(); -std::bad_cast::~bad_cast(); -std::bad_cast::~bad_cast(); std::bad_cast::operator=(std::bad_cast const); -std::bad_alloc::bad_alloc(std::bad_alloc const); -std::bad_alloc::bad_alloc(); -std::bad_alloc::bad_alloc(std::bad_alloc const); -std::bad_alloc::bad_alloc(); -std::bad_alloc::~bad_alloc(); -std::bad_alloc::~bad_alloc(); -std::bad_alloc::~bad_alloc(); -std::bad_alloc::operator=(std::bad_alloc const); std::exception::exception(std::exception const); std::exception::exception(); std::exception::exception(std::exception const); std::exception::exception(); -std::exception::~exception(); -std::exception::~exception(); -std::exception::~exception(); std::exception::operator=(std::exception const); -vtable for std::bad_typeid; -vtable for std::bad_cast; -vtable for std::bad_alloc; -vtable for std::exception; -vtable for std::type_info; -typeinfo for std::bad_typeid; -typeinfo for std::bad_cast; -typeinfo for std::bad_alloc; -typeinfo for std::exception; -typeinfo for std::type_info; -typeinfo name for std::bad_typeid; -typeinfo name for std::bad_cast; -typeinfo name for std::bad_alloc; -typeinfo name for std::exception; -typeinfo name for std::type_info; -std::type_info::__is_function_p() const; -std::type_info::__do_upcast(__cxxabiv1::__class_type_info const*, void**) const; -std::type_info::__is_pointer_p() const; - }; __cxa_allocate_dependent_exception; __cxa_current_primary_exception; @@ -317,6 +261,15 @@ } CXXABI_1.3.1; + +GLIBCXX_3.4.9 { +extern C++ { +
Re: C++ runtime version patch for testing
On 27 Jan 2013, at 15:03, Konstantin Belousov wrote: On Sun, Jan 27, 2013 at 01:28:44PM +, David Chisnall wrote: + std::set_new_handler*; What are the symbols you assigning the version there ? I cannot find anything in the libstdc++.so export list which would match the line. std::set_new_handler(void (*)()) # objdump -T /usr/lib/libsupc++.so | c++filt | grep new_h 9010 __float128DF .text 000e GLIBCXX_3.4 std::set_new_handler(void (*)()) + std::set_terminate*; + std::set_unexpected*; + std::bad_alloc*; + + std::bad_alloc*; std::bad_alloc seems to be duplicated. Thanks, removed. Besides that, pristine libstdc++.so exports 'std::bad_alloc::what() const' at the GLIBCXX_3.4.9 namespace. You did this for the *::what()' from libcxxrt but not for the libsupc++. Ooops. I wrote a script that checked for version mismatches, but for some reason I missed this one. Running it again, it shows two mismatches, both fixed in the new version of the diff. + std::bad_cast*; + std::exception*; + + typeinfo for std::bad_alloc; + typeinfo for std::bad_cast; + typeinfo for std::exception; + + typeinfo name for std::bad_alloc; + typeinfo name for std::bad_cast; + typeinfo name for std::exception; + + vtable for std::bad_alloc; + vtable for std::bad_cast; + vtable for std::exception; +}; }; CXXABI_1.3.1 { Index: lib/libcxxrt/Version.map === --- lib/libcxxrt/Version.map (revision 245840) +++ lib/libcxxrt/Version.map (working copy) @@ -209,18 +209,7 @@ std::type_info::type_info(std::type_info const); std::type_info::type_info(std::type_info const); -std::type_info::~type_info(); -std::type_info::~type_info(); -std::type_info::~type_info(); std::type_info::operator=(std::type_info const); [omitted] Do applications record the dependency on the libcxxrt directly, using the DT_NEEDED tag ? I don't believe so, they get it indirectly via libc++ or libstdc++. How can I check? David Index: gnu/lib/libsupc++/Version.map === --- gnu/lib/libsupc++/Version.map (revision 245840) +++ gnu/lib/libsupc++/Version.map (working copy) @@ -130,6 +130,13 @@ *; }; +GLIBCXX_3.4.9 { +extern C++ { +std::bad_alloc::what() const; +std::bad_cast::what() const; +}; +}; + GLIBCXX_3.4 { # operator new and new[] _Znai[jm]; @@ -142,6 +149,27 @@ _ZdaPvRKSt9nothrow_t; _ZdlPv; _ZdlPvRKSt9nothrow_t; +extern C++ { + std::set_new_handler*; + std::set_terminate*; + std::set_unexpected*; + + std::bad_alloc*; + std::bad_cast*; + std::exception*; + + typeinfo for std::bad_alloc; + typeinfo for std::bad_cast; + typeinfo for std::exception; + + typeinfo name for std::bad_alloc; + typeinfo name for std::bad_cast; + typeinfo name for std::exception; + + vtable for std::bad_alloc; + vtable for std::bad_cast; + vtable for std::exception; +}; }; CXXABI_1.3.1 { Index: lib/libcxxrt/Version.map === --- lib/libcxxrt/Version.map(revision 245840) +++ lib/libcxxrt/Version.map(working copy) @@ -209,18 +209,7 @@ std::type_info::type_info(std::type_info const); std::type_info::type_info(std::type_info const); -std::type_info::~type_info(); -std::type_info::~type_info(); -std::type_info::~type_info(); std::type_info::operator=(std::type_info const); -std::unexpected(); -std::get_terminate(); -std::set_terminate(void (*)()); -std::get_unexpected(); -std::set_unexpected(void (*)()); -std::set_new_handler(void (*)()); -std::uncaught_exception(); -std::terminate(); # Extensions @@ -243,70 +232,25 @@ CXXRT_1.0 { extern C++ { -std::bad_cast::what() const; -std::bad_typeid::what() const; -std::bad_alloc::what() const; -std::exception::what() const; std::type_info::name() const; std::type_info::before(std::type_info const) const; std::type_info::operator==(std::type_info const) const; std::type_info::operator!=(std::type_info const) const; -std::bad_typeid::bad_typeid(std::bad_typeid const); -std::bad_typeid::bad_typeid(); -std::bad_typeid::bad_typeid(std::bad_typeid const); -std::bad_typeid::bad_typeid(); -std::bad_typeid::~bad_typeid(); -std::bad_typeid::~bad_typeid(); -std::bad_typeid::~bad_typeid(); -std::bad_typeid::operator=(std::bad_typeid const); std::bad_cast::bad_cast(std::bad_cast const); std::bad_cast::bad_cast();
Re: C++ runtime version patch for testing
On Sun, Jan 27, 2013 at 06:15:51PM +0200, Konstantin Belousov wrote: On Sun, Jan 27, 2013 at 04:01:48PM +, David Chisnall wrote: On 27 Jan 2013, at 15:52, Konstantin Belousov wrote: On Sun, Jan 27, 2013 at 03:17:51PM +, David Chisnall wrote: Apparently c++filt from 2.23.1 binutils has bug, c++filt is not able to demangle the set_new_handler. I'm using the one from head, which may be the elftoolchain project one? It seems to be missing a man page... In head, the c++ demangler is coming from either binutils or gcc copy of libiberty. I did not looked which one is selected. You need to add 'std::bad_typeid::what() const' to 3.4.9 as well, it seems. Added Do readelf -d some binary and look for the needed tags. If libcxxrt is not passed on the linker command line and not recorded as needed in the libc++/libstdc++, it should be fine. 0x0001 (NEEDED) Shared library: [libcxxrt.so.1] This is with something compiled with -stdlib=libc++. It seems the (NEEDED) is there even if I compile with clang -lc++, instead of clang++, so the linker is adding it via the indirect dependency? Or does it show up because libc++ has that line too? Until recently, the default behaviour of the ELF linker was to record all second order needed libraries (i.e. libraries needed by a library specified on the linker command line) in the final link result. This is controllable with --copy-dt-needed-entries linker flag and recently the default were flipped to --no-copy. Your changes to libcxxrt obviously break the ABI, removing the symbols from the version namespace, but my hope is that namespace for libcxxrt is actually not part of the _system_ ABI. Thus the question. I'm okay with breaking the libcxxrt ABI at this point. libc++ is not part of the standard install, and is there for testing in 9.1. libcxxrt isn't linked against anything unless you use libc++ (or libstdc++ and a line in libmap.conf) so nothing non-experimental should use it. For 9.2, I'd like to have an ABI that we can support long term. You might be okay with ABI breakage, but the project is not. Having ABI breakage on the stable branch is very unfortunate both from the technical and PR points of view. You should consider using .gnu.warning. section or some other mechanism to explicitely warn about using libcxxrt begin unsupported, or better, remove it from the stable branch. I noted one more thing to verify. Shouldn't the GLIBCXX_3.4.9 version inherit from the GLIBCXX_3.4, both for libsupc++ and libcxxrt ? I cannot verify the stock libstdc++ right now, but I suspect that namespace is inherited, and this must be fixed before the commit, if true. pgpKQhR7iEfFy.pgp Description: PGP signature