Opened 13 years ago
Closed 13 years ago
#4008 closed Bugs (invalid)
Segfault in program_options::parse_command_line when compiled with -fshort-enums
Reported by: | Owned by: | Vladimir Prus | |
---|---|---|---|
Milestone: | Boost 1.43.0 | Component: | program_options |
Version: | Boost 1.42.0 | Severity: | Showstopper |
Keywords: | Cc: |
Description
Hello,
I am new to C++ and bug finding in general, so I hope am not reporting something obvious. When diving into program_options I wrote the following sample program:
// test.cpp #include <boost/program_options.hpp> #include <iostream> #include <fstream> namespace po = boost::program_options; int main(int argc, char **argv) { int result = EXIT_SUCCESS; po::options_description desc("Allowed options"); desc.add_options() ("help", "Displays help message") ("port",po::value<int>(),"Port to use") ; po::options_description cmdline_options; cmdline_options.add(desc); po::options_description config_file_options; config_file_options.add(desc); po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); if (vm.count("port")) { std::cout << "port was set to " << vm["port"].as<int>() << ".\n"; } else { std::cout << "port was not set.\n"; } return result; }
When compiled 'normally' it works:
$ g++ test.cpp -lboost_program_options $ ./a.out --port 60 port was set to 60.
but when I compile it with -fshort-enums it segfaults:
$ g++ -fshort-enums test.cpp -lboost_program_options $./a.out Segmentation fault
My gcc version:
g++ -v Reading specs from /usr/lib/gcc/i486-slackware-linux/4.2.4/specs Target: i486-slackware-linux Configured with: ../gcc-4.2.4/configure --prefix=/usr --enable-shared --enable-languages=ada,c,c++,fortran,java,objc --enable-threads=posix --enable-__cxa_atexit --disable-checking --with-gnu-ld --verbose --with-arch=i486 --target=i486-slackware-linux --host=i486-slackware-linux Thread model: posix gcc version 4.2.4
Valgrind output of the crashing binary:
valgrind a.out ==11266== Memcheck, a memory error detector. ==11266== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==11266== Using LibVEX rev 1804, a library for dynamic binary translation. ==11266== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==11266== Using valgrind-3.3.0, a dynamic binary instrumentation framework. ==11266== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==11266== For more details, rerun with: -v ==11266== ==11266== Conditional jump or move depends on uninitialised value(s) ==11266== at 0x804EF64: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804EFBC: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::~function1() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8050AD7: boost::program_options::detail::cmdline::~cmdline() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8050B6B: boost::program_options::basic_command_line_parser<char>::~basic_command_line_parser() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8056277: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char**, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804DE66: main (in /home/severin/swpr-02/examples/conf/a.out) ==11266== ==11266== Conditional jump or move depends on uninitialised value(s) ==11266== at 0x804EF7A: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804EFBC: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::~function1() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8050AD7: boost::program_options::detail::cmdline::~cmdline() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8050B6B: boost::program_options::basic_command_line_parser<char>::~basic_command_line_parser() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8056277: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char**, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804DE66: main (in /home/severin/swpr-02/examples/conf/a.out) ==11266== ==11266== Use of uninitialised value of size 4 ==11266== at 0x804EF39: boost::detail::function::basic_vtable1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear(boost::detail::function::function_buffer&) (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804EF99: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804EFBC: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::~function1() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8050AD7: boost::program_options::detail::cmdline::~cmdline() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8050B6B: boost::program_options::basic_command_line_parser<char>::~basic_command_line_parser() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8056277: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char**, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804DE66: main (in /home/severin/swpr-02/examples/conf/a.out) ==11266== ==11266== Use of uninitialised value of size 4 ==11266== at 0x804EF42: boost::detail::function::basic_vtable1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear(boost::detail::function::function_buffer&) (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804EF99: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804EFBC: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::~function1() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8050AD7: boost::program_options::detail::cmdline::~cmdline() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8050B6B: boost::program_options::basic_command_line_parser<char>::~basic_command_line_parser() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8056277: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char**, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804DE66: main (in /home/severin/swpr-02/examples/conf/a.out) vex x86->IR: unhandled instruction bytes: 0x67 0x5 0x8 0x0 ==11266== ==11266== Invalid read of size 4 ==11266== at 0x805A539: ??? ==11266== by 0x804EF99: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804EFBC: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::~function1() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8050AD7: boost::program_options::detail::cmdline::~cmdline() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8050B6B: boost::program_options::basic_command_line_parser<char>::~basic_command_line_parser() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8056277: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char**, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804DE66: main (in /home/severin/swpr-02/examples/conf/a.out) ==11266== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==11266== ==11266== Process terminating with default action of signal 11 (SIGSEGV) ==11266== Access not within mapped region at address 0x0 ==11266== at 0x805A539: ??? ==11266== by 0x804EF99: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804EFBC: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::~function1() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8050AD7: boost::program_options::detail::cmdline::~cmdline() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8050B6B: boost::program_options::basic_command_line_parser<char>::~basic_command_line_parser() (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x8056277: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char**, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (in /home/severin/swpr-02/examples/conf/a.out) ==11266== by 0x804DE66: main (in /home/severin/swpr-02/examples/conf/a.out) ==11266== ==11266== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 23 from 1) ==11266== malloc/free: in use at exit: 568 bytes in 33 blocks. ==11266== malloc/free: 39 allocs, 6 frees, 704 bytes allocated. ==11266== For counts of detected errors, rerun with: -v ==11266== searching for pointers to 33 not-freed blocks. ==11266== checked 119,684 bytes. ==11266== ==11266== LEAK SUMMARY: ==11266== definitely lost: 0 bytes in 0 blocks. ==11266== possibly lost: 136 bytes in 6 blocks. ==11266== still reachable: 432 bytes in 27 blocks. ==11266== suppressed: 0 bytes in 0 blocks. ==11266== Rerun with --leak-check=full to see details of leaked memory. Segmentation fault
If I can help you finding the cause, just write me an e-mail :-)
Change History (6)
comment:1 by , 13 years ago
comment:2 by , 13 years ago
Another Addition: I compiled gcc 4.4.3 to see if it is a gcc issue, but I still get the crashes. Here is the valgrind output for the binary compiler with gcc 4.4.3:
$ /home/severin/software/gcc/bin/g++ -fshort-enums -g -Wl,-R,/home/severin/software/gcc/lib test.cpp -lboost_program_options $ valgrind a.out ==11870== Memcheck, a memory error detector. ==11870== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==11870== Using LibVEX rev 1804, a library for dynamic binary translation. ==11870== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==11870== Using valgrind-3.3.0, a dynamic binary instrumentation framework. ==11870== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==11870== For more details, rerun with: -v ==11870== ==11870== My PID = 11870, parent PID = 11794. Prog and args are: ==11870== a.out ==11870== --11870-- Warning: DWARF2 CFI reader: unhandled DW_OP_ opcode 0x55 ==11870== Conditional jump or move depends on uninitialised value(s) ==11870== at 0x8050238: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear() (function_template.hpp:854) ==11870== by 0x804F828: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::~function1() (function_template.hpp:752) ==11870== by 0x804EF85: boost::program_options::detail::cmdline::~cmdline() (cmdline.hpp:54) ==11870== by 0x804EFEC: boost::program_options::basic_command_line_parser<char>::~basic_command_line_parser() (parsers.hpp:88) ==11870== by 0x804F097: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char**, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (parsers.hpp:121) ==11870== by 0x804DD3E: main (test.cpp:21) ==11870== ==11870== Conditional jump or move depends on uninitialised value(s) ==11870== at 0x805024A: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear() (function_template.hpp:855) ==11870== by 0x804F828: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::~function1() (function_template.hpp:752) ==11870== by 0x804EF85: boost::program_options::detail::cmdline::~cmdline() (cmdline.hpp:54) ==11870== by 0x804EFEC: boost::program_options::basic_command_line_parser<char>::~basic_command_line_parser() (parsers.hpp:88) ==11870== by 0x804F097: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char**, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (parsers.hpp:121) ==11870== by 0x804DD3E: main (test.cpp:21) ==11870== ==11870== Use of uninitialised value of size 4 ==11870== at 0x8050CAB: boost::detail::function::basic_vtable1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear(boost::detail::function::function_buffer&) (function_template.hpp:503) ==11870== by 0x8050268: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear() (function_template.hpp:856) ==11870== by 0x804F828: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::~function1() (function_template.hpp:752) ==11870== by 0x804EF85: boost::program_options::detail::cmdline::~cmdline() (cmdline.hpp:54) ==11870== by 0x804EFEC: boost::program_options::basic_command_line_parser<char>::~basic_command_line_parser() (parsers.hpp:88) ==11870== by 0x804F097: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char**, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (parsers.hpp:121) ==11870== by 0x804DD3E: main (test.cpp:21) ==11870== ==11870== Use of uninitialised value of size 4 ==11870== at 0x8050CB4: boost::detail::function::basic_vtable1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear(boost::detail::function::function_buffer&) (function_template.hpp:504) ==11870== by 0x8050268: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear() (function_template.hpp:856) ==11870== by 0x804F828: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::~function1() (function_template.hpp:752) ==11870== by 0x804EF85: boost::program_options::detail::cmdline::~cmdline() (cmdline.hpp:54) ==11870== by 0x804EFEC: boost::program_options::basic_command_line_parser<char>::~basic_command_line_parser() (parsers.hpp:88) ==11870== by 0x804F097: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char**, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (parsers.hpp:121) ==11870== by 0x804DD3E: main (test.cpp:21) ==11870== ==11870== Jump to the invalid address stated on the next line ==11870== at 0x8955C3C9: ??? ==11870== by 0x8050268: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear() (function_template.hpp:856) ==11870== by 0x804F828: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::~function1() (function_template.hpp:752) ==11870== by 0x804EF85: boost::program_options::detail::cmdline::~cmdline() (cmdline.hpp:54) ==11870== by 0x804EFEC: boost::program_options::basic_command_line_parser<char>::~basic_command_line_parser() (parsers.hpp:88) ==11870== by 0x804F097: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char**, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (parsers.hpp:121) ==11870== by 0x804DD3E: main (test.cpp:21) ==11870== Address 0x8955c3c9 is not stack'd, malloc'd or (recently) free'd ==11870== ==11870== Process terminating with default action of signal 11 (SIGSEGV) ==11870== Access not within mapped region at address 0x8955C3C9 ==11870== at 0x8955C3C9: ??? ==11870== by 0x8050268: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::clear() (function_template.hpp:856) ==11870== by 0x804F828: boost::function1<std::vector<boost::program_options::basic_option<char>, std::allocator<boost::program_options::basic_option<char> > >, std::vector<std::string, std::allocator<std::string> >&>::~function1() (function_template.hpp:752) ==11870== by 0x804EF85: boost::program_options::detail::cmdline::~cmdline() (cmdline.hpp:54) ==11870== by 0x804EFEC: boost::program_options::basic_command_line_parser<char>::~basic_command_line_parser() (parsers.hpp:88) ==11870== by 0x804F097: boost::program_options::basic_parsed_options<char> boost::program_options::parse_command_line<char>(int, char**, boost::program_options::options_description const&, int, boost::function1<std::pair<std::string, std::string>, std::string const&>) (parsers.hpp:121) ==11870== by 0x804DD3E: main (test.cpp:21) ==11870== ==11870== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 23 from 1) ==11870== malloc/free: in use at exit: 568 bytes in 32 blocks. ==11870== malloc/free: 38 allocs, 6 frees, 704 bytes allocated. ==11870== For counts of detected errors, rerun with: -v ==11870== searching for pointers to 32 not-freed blocks. ==11870== checked 123,768 bytes. ==11870== ==11870== LEAK SUMMARY: ==11870== definitely lost: 0 bytes in 0 blocks. ==11870== possibly lost: 136 bytes in 6 blocks. ==11870== still reachable: 432 bytes in 26 blocks. ==11870== suppressed: 0 bytes in 0 blocks. ==11870== Rerun with --leak-check=full to see details of leaked memory.
comment:3 by , 13 years ago
I believe that -fshort-enums changes class layout. Therefore, all modules in your program should be built with the same value of that option. Do you still get the crash if you rebuild Boost with that option?
follow-up: 5 comment:4 by , 13 years ago
sorry for my late reply, but i was very busy this week.
I think you are right. However how do I compile boost with -fshort-enums or check that it compiled with it? Here is what a tried:
$ bjam cxxflags=-fshort-enums --prefix=/home/severin/software/boost_test install ... boost compiles .... $ g++ -L/home/severin/software/boost_test/lib/ -Wl,-R/home/severin/software/boost_test/lib/ -I/home/severin/software/boost_test/include/ test.cpp -lboost_program_options -fshort-enums $ ldd a.out linux-gate.so.1 => (0xffffe000) libboost_program_options.so.1.42.0 => /home/severin/software/boost_test/lib/libboost_program_options.so.1.42.0 (0xb7fbc000) (... other libs ...) $ ./a.out Segmentation fault
comment:5 by , 13 years ago
ah I just figured out, that I forgot to rebuild boost.
bjam cxxflags=-fshort-enums --prefix=/home/severin/software/boost_test install -a
(Note the -a at the end)
now the compilation with -fshot-enums works fine (but of course it crashes if I compile it without -fshort-enums). Sorry that the problem was so trivial - I am very new to C++ and did not expect that a compiler flag can cause a segfault ;-) Thank you for your solution!
comment:6 by , 13 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
Good to know that this issue has been resolved. I'm closing the ticket.
ah, I forgot to add that I use boost version 1.42 and that the bug does not occur on my iBook G4 with gcc 4.01