Boost logo

Boost Users :

From: Søren Holstebroe (sh_at_[hidden])
Date: 2007-05-31 10:57:59


This problem was found in boost 1.33.1 using VC++ 8.0. I haven't tried 1.34.0, but the cmdline code seems unchanged.

from cmdline.cpp
--------------------------------------
    std::vector<option>
    cmdline::parse_long_option(std::vector<string>& args)
    {
        vector<option> result;
        const std::string& tok = args[0];
        if (tok.size() >= 3 && tok[0] == '-' && tok[1] == '-')
        {
            string name, adjacent;

            string::size_type p = tok.find('=');
            if (p != tok.npos)
            {
                name = tok.substr(2, p-2);
                adjacent = tok.substr(p+1);
                if (adjacent.empty())
                    throw invalid_command_line_syntax(name,
                      invalid_command_line_syntax::empty_adjacent_parameter);
            }
            else
            {
                name = tok.substr(2);
            }
            option opt;
            opt.string_key = name;
            if (!adjacent.empty())
                opt.value.push_back(adjacent);
            opt.original_tokens.push_back(tok);
            result.push_back(opt);
            args.erase(args.begin());
        }
        return result;
    }
--------------------------------------

The line
args.erase(args.begin());
crashes in MS VC++ 8.0 in release optimized configuration, though it works fine in debug mode.
Could this be a compiler problem with loop unrolling and the const std::string& tok = args[0]; reference ?
As seen in the stack trace, std::vector::erase tries to copy a "Bad Ptr" string and obviously fails miserably.
Interestingly the program hangs in std::_Distance2 if I provide no command line arguments (it looks like a very long bad pointer loop, not an infinite loop).

I might try recompiling boost with different compile options, but it is quite time consuming to experiment with.

best regards
Søren Holstebroe

Code:
        namespace po = boost::program_options;
        po::options_description desc("Allowed options");
        desc.add_options()
                ("help", "produce help message")
                ;
        po::variables_map vm;
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);

Stack trace:

> msvcr80.dll!memcpy(unsigned char * dst=0x00c20048, unsigned char * src=0xabababab, unsigned long count=458755) Line 188 Asm
         msvcr80.dll!memcpy_s(void * dst=0x00c20048, unsigned int sizeInBytes=458767, const void * src=0xabababab, unsigned int count=458755) Line 67 + 0xc bytes C
         msvcp80.dll!std::char_traits<char>::_Copy_s(char * _First1=0x00c20048, unsigned int _Size_in_bytes=458767, const char * _First2=0xabababab, unsigned int _Count=458755) Line 576 C++
         msvcp80.dll!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & _Right=<Bad Ptr>, unsigned int _Roff=0, unsigned int _Count=4294967295) Line 1059 + 0x2c bytes C++
         msvcp80.dll!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::operator=(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & _Right=<Bad Ptr>) Line 1044 C++
         PS.Vision.Console.exe!std::_Copy_opt<std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *>() + 0x4a bytes C++
         PS.Vision.Console.exe!std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::erase() + 0x2d bytes C++
         PS.Vision.Console.exe!boost::program_options::detail::cmdline::parse_long_option() + 0x28e bytes C++
         PS.Vision.Console.exe!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::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > &>::operator()() + 0x40 bytes C++
         PS.Vision.Console.exe!boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline *>,boost::arg<1> >::operator()<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::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > &>,boost::_bi::list1<std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > &> >() + 0x22 bytes C++
         PS.Vision.Console.exe!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::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > &>,boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline *>,boost::arg<1> > >::operator()<std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >() + 0x2d bytes C++
         PS.Vision.Console.exe!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::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > &>,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::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > &>::invoke() + 0x1d bytes C++
         PS.Vision.Console.exe!boost::function1<std::vector<boost::program_options::basic_option<char>,std::allocator<boost::program_options::basic_option<char> > >,std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > &,std::allocator<boost::function_base> >::operator()() + 0x5b bytes C++
         PS.Vision.Console.exe!boost::program_options::detail::cmdline::run() + 0x371 bytes C++
         PS.Vision.Console.exe!boost::program_options::basic_command_line_parser<wchar_t>::run() Line 102 + 0x12 bytes C++
         PS.Vision.Console.exe!boost::program_options::parse_command_line<wchar_t>(int argc=5, wchar_t * * argv=0x003b5718, const boost::program_options::options_description & desc={...}, int style=0, boost::function1<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > const &,std::allocator<boost::function_base> > ext={...}) Line 119 + 0x9d bytes C++


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net