Date: Thu, 27 Dec 2012 16:07:25 +0100 From: Stefan Farfeleder <stefanf@FreeBSD.org> To: current@freebsd.org Cc: dim@freebsd.org Subject: clang 3.2 RC2 miscompiles libgcc? Message-ID: <20121227150724.GA1431@mole.fafoe.narf.at>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20121227150724.GA1431>