clang 3.2 RC2 miscompiles libgcc?
Stefan Farfeleder
stefanf at FreeBSD.org
Thu Dec 27 15:07:34 UTC 2012
Hi,
I noticed that most of my C++ applications in recent versions of FreeBSD
head suddenly crash without me recompiling them. I tracked it down to
r243830 which imported a new clang version. The new clang seems to
compile libgcc in a wrong or at least incompatible way with what gcc
expects. In fact, the breakage only occurs with libgcc compiled by a
post-r243830 clang and an application compiled with g++ -O2. For me, the
crash happens with boost::program_options, but I'm not sure if that is
necessary for the crash.
$ cat po.cc
#include <boost/program_options.hpp>
int main(void) {
namespace po = boost::program_options;
const char *argv[] = { "a.out", "-x", 0 };
po::options_description options("Options");
options.add_options()("bla", "");
try {
po::variables_map vm;
po::store(po::parse_command_line(2, argv, options), vm);
notify(vm);
return 0;
} catch (const std::exception &ex) {
return 1;
}
}
$ g++ -O2 -I /usr/local/include -L /usr/local/lib -lboost_program_options po.cc
$ ./a.out
zsh: segmentation fault (core dumped) ./a.out
$ ldd ./a.out
./a.out:
libboost_program_options.so => /usr/local/lib/libboost_program_options.so (0x800821000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x800a7e000)
libm.so.5 => /lib/libm.so.5 (0x800d7c000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800f9e000)
libc.so.7 => /lib/libc.so.7 (0x8011ab000)
libthr.so.3 => /lib/libthr.so.3 (0x801523000)
$ ls /usr/home/stefan/scratch/r243829
libgcc_s.so.1
$ LD_LIBRARY_PATH=/usr/home/stefan/scratch/r243829 ./a.out
$ valgrind ./a.out
==47491== Memcheck, a memory error detector
==47491== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==47491== Using Valgrind-3.8.0 and LibVEX; rerun with -h for copyright info
==47491== Command: ./a.out
==47491==
==47491== Invalid read of size 8
==47491== at 0x405DAA: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char const* const*, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (in /usr/home/stefan/scratch/a.out)
==47491== by 0x401E7D: main (in /usr/home/stefan/scratch/a.out)
==47491== Address 0x2800ef8 is 24 bytes inside a block of size 27 alloc'd
==47491== at 0x1009FB6: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==47491== by 0x213F95A: operator new(unsigned long) (in /usr/lib/libsupc++.so.1)
==47491== by 0x14F08D2: ??? (in /usr/lib/libstdc++.so.6)
==47491== by 0x14EDCFD: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&, unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6)
==47491== by 0x1234B12: boost::program_options::detail::cmdline::parse_short_option(std::vector<std::string, std::allocator<std::string> >&) (in /usr/local/lib/libboost_program_options.so.4)
==47491== by 0x123843A: boost::detail::function::function_obj_invoker1<boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, boost::program_options::detail::cmdline, std::vector<std::string, std::allocator<std::string> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >, std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::invoke(boost::detail::function::function_buffer&, std::vector<std::string, std::allocator<std::string> >&) (in /usr/local/lib/libboost_program_options.so.4)
==47491== by 0x12367C1: boost::program_options::detail::cmdline::run() (in /usr/local/lib/libboost_program_options.so.4)
==47491== by 0x4051D5: boost::program_options::basic_command_line_parser<char>::run() (in /usr/home/stefan/scratch/a.out)
==47491== by 0x405B7A: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char const* const*, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (in /usr/home/stefan/scratch/a.out)
==47491== by 0x401E7D: main (in /usr/home/stefan/scratch/a.out)
==47491==
==47491== Jump to the invalid address stated on the next line
==47491== at 0x782D: ???
==47491== by 0x405DBF: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char const* const*, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (in /usr/home/stefan/scratch/a.out)
==47491== by 0x401E7D: main (in /usr/home/stefan/scratch/a.out)
==47491== Address 0x782d is not stack'd, malloc'd or (recently) free'd
==47491==
==47491==
==47491== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==47491== Bad permissions for mapped region at address 0x782D
==47491== at 0x782D: ???
==47491== by 0x405DBF: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char const* const*, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (in /usr/home/stefan/scratch/a.out)
==47491== by 0x401E7D: main (in /usr/home/stefan/scratch/a.out)
==47491==
==47491== HEAP SUMMARY:
==47491== in use at exit: 2,298 bytes in 24 blocks
==47491== total heap usage: 41 allocs, 17 frees, 2,843 bytes allocated
==47491==
==47491== LEAK SUMMARY:
==47491== definitely lost: 184 bytes in 1 blocks
==47491== indirectly lost: 82 bytes in 2 blocks
==47491== possibly lost: 88 bytes in 3 blocks
==47491== still reachable: 1,944 bytes in 18 blocks
==47491== suppressed: 0 bytes in 0 blocks
==47491== Rerun with --leak-check=full to see details of leaked memory
==47491==
==47491== For counts of detected and suppressed errors, rerun with: -v
==47491== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
You might say this is simply a bug in boost that is now uncovered by
chance. I'm not entirely sure it isn't, but I noticed that the
corruption starts at the time the throw statement within the boost code
is executed. I simply wasn't able to reproduce it without boost.
Maybe something within libgcc (some stack unwinding code?) corrupts the
stack. I'm afraid I have no clue about how libgcc and libstdc++
interact wrt to exceptions.
I put copies of a r243829 and r243830 libgcc_s.so.1 to
http://people.freebsd.org/~stefanf/tmp/ .
These were built and installed by buildworld/installworld without any
change of default flags.
Stefan
More information about the freebsd-current
mailing list