Bug 210452
Summary: | valgrind turns up binary compatibility issue with libstdc++ | ||
---|---|---|---|
Product: | [Fedora] Fedora | Reporter: | Stefan Ring <stefanrin> |
Component: | gcc4 | Assignee: | Jakub Jelinek <jakub> |
Status: | CLOSED RAWHIDE | QA Contact: | |
Severity: | medium | Docs Contact: | |
Priority: | medium | ||
Version: | 5 | CC: | bkoz |
Target Milestone: | --- | Keywords: | Reopened |
Target Release: | --- | ||
Hardware: | x86_64 | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | 4.1.1-31 | Doc Type: | Bug Fix |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2006-11-05 13:03:38 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
Stefan Ring
2006-10-12 08:26:21 UTC
You have way too many things built yourself, this is something you should debug on your own, I couldn't reproduce it myself using RHEL4 gcc to compile the testcase. I've found a better way to reproduce it. While the valgrind stacktrace looks a bit different, it seems to be the same problem. To reproduce, you need a RHEL system and a Fedora 5. I used CentOS but it should not matter. I compiled the test program on a freshly installed CentOS 4.3 (RHEL4 Update 3) like before: g++ e.cpp -lboost_regex Interestingly, boost is linked in statically. Now when I use valgrind on it on the CentOS box, nothing shows up. Then I take the executable and transfer it to the Fedora 5 box where valgrind will show this: ==2458== Conditional jump or move depends on uninitialised value(s) ==2458== at 0x40CB97: boost::re_detail::c_traits_base::do_update_collate() (in /osiris32/home/sr/a.out-centos43) ==2458== by 0x40CC76: boost::c_regex_traits<char>::update() (in /osiris32/home/sr/a.out-centos43) ==2458== by 0x407D60: boost::reg_expression<char, boost::regex_traits<char>, std::allocator<char> >::set_expression(char const*, char const*, unsigned) (in /osiris32/home/sr/a.out-centos43) ==2458== by 0x409B19: boost::reg_expression<char, boost::regex_traits<char>, std::allocator<char> >::reg_expression(char const*, unsigned, std::allocator<char> const&) (in /osiris32/home/sr/a.out-centos43) ==2458== by 0x402A6C: boost::basic_regex<char, boost::regex_traits<char>, std::allocator<char> >::basic_regex(char const*, unsigned, std::allocator<char> const&) (in /osiris32/home/sr/a.out-centos43) ==2458== by 0x4029B9: main (in /osiris32/home/sr/a.out-centos43) ==2458== ==2458== Conditional jump or move depends on uninitialised value(s) ==2458== at 0x40CBC7: boost::re_detail::c_traits_base::do_update_collate() (in /osiris32/home/sr/a.out-centos43) ==2458== by 0x40CC76: boost::c_regex_traits<char>::update() (in /osiris32/home/sr/a.out-centos43) ==2458== by 0x407D60: boost::reg_expression<char, boost::regex_traits<char>, std::allocator<char> >::set_expression(char const*, char const*, unsigned) (in /osiris32/home/sr/a.out-centos43) ==2458== by 0x409B19: boost::reg_expression<char, boost::regex_traits<char>, std::allocator<char> >::reg_expression(char const*, unsigned, std::allocator<char> const&) (in /osiris32/home/sr/a.out-centos43) ==2458== by 0x402A6C: boost::basic_regex<char, boost::regex_traits<char>, std::allocator<char> >::basic_regex(char const*, unsigned, std::allocator<char> const&) (in /osiris32/home/sr/a.out-centos43) ==2458== by 0x4029B9: main (in /osiris32/home/sr/a.out-centos43) I also tried "yum update"-ing the CentOS box (this includes gcc 3.4.6 instead of 3.4.5) but everything remains the same. Sure, I can reproduce this, but that in no way can be a binary compatibility issue. The problem is in the libboost_regex.a linked statically into the executable. I don't agree with you on this. My understanding of binary compatibility was that when a shared library minor version number is increased (libstdc++.so 6.0.3 -> 6.0.8 in this case), running binaries linked against the older version should work just fine when at run-time only the newer version is available. Sorry, I think you are right. The relevant change is http://gcc.gnu.org/ml/libstdc++/2004-10/msg00394.html and the problem is that in this case _S_create isn't inlined (i.e. a libstdc++.so routine is used), while _S_construct is inlined: #2 0x0000003ca2c9cc41 in std::string::_Rep::_S_create () from /usr/lib64/libstdc++.so.6 #3 0x00000000004058f5 in std::string::_S_construct<char const*> () #4 0x000000000040596a in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char const*> () #5 0x000000000040ca04 in boost::re_detail::c_traits_base::do_update_collate () Which means this is GCC 3.4.6 _S_construct (which doesn't set _M_refcount) calling GCC 4.1.1 _S_create (which doesn't set _M_refcount either). I think we need something like: --- libstdc++-v3/include/bits/basic_string.tcc 2006-10-05 00:28:47.000000000 +0200 +++ libstdc++-v3/include/bits/basic_string.tcc 2006-10-13 14:24:18.000000000 +0200 @@ -588,6 +588,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std) void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); _Rep *__p = new (__place) _Rep; __p->_M_capacity = __capacity; + // ABI compatibility - 3.4.x set in _S_create both + // _M_refcount and _M_length. All callers of _S_create + // in basic_string.tcc then set just _M_length. + // In 4.0.x and later both _M_refcount and _M_length + // are initialized in the callers, unfortunately we can + // have 3.4.x compiled code with _S_create callers inlined + // calling 4.0.x+ _S_create. + __p->_M_set_sharable(); return __p; } Thanks! I have installed the patch at our development system, and everything seems fine. Fixed in gcc-4.1.1-32 in rawhide. |