Re: [Boost-users] program_options: wild write

Peter, Once I understood that even though positional parameters have been declared, they still have to be listed as an option, I got my positional parameter to work. I've even been able to follow the examples to "hide" the positional parameter name from the --help print out. I've still got the problem that an illegal option value triggers Dr Watson. I need to create a short example that I can post. Merrill

Merrill Cornish wrote:
I've still got the problem that an illegal option value triggers Dr Watson. I need to create a short example that I can post.
Here's one to produce my segfault, which may or may not be the same as yours: #include <boost/program_options.hpp> #include <iostream> int main(int argc, char* argv[]) { try { boost::program_options::options_description desc("Test"); desc.add_options()("test", boost::program_options::value<std::string>(), "import the specified OBJ file and save it to MDLM format"); std::cerr << desc; return 0; } catch (const std::exception& except) { std::cerr << except.what() << std::endl; return 1; } } As per my message the other day, this triggers a bug in options_description.cpp's format_paragraph function, which causes a segfault on linux with g++ 4.0.2 (and an assertion failure on Visual Studio 2005 beta 2); running it under valgrind 2.4.0 on linux produces: ==5197== Memcheck, a memory error detector for x86-linux. ==5197== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al. ==5197== Using valgrind-2.4.0, a program supervision framework for x86-linux. ==5197== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al. ==5197== For more details, rerun with: -v ==5197== Test: --test arg import the specified OBJ file and save it to MDLM format ==5197== Invalid read of size 2 ==5197== at 0x1B9ABB6E: __gnu_cxx::__pool<true>::_M_reclaim_block(char*, unsigned) (in /usr/lib/libstdc++.so.6.0.6) ==5197== by 0x804A35C: __gnu_cxx::__mt_alloc<unsigned long, __gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, true>
::deallocate(unsigned long*, unsigned) (in /home/will/devel/a.out) ==5197== by 0x804A39B: std::_Bvector_base<std::allocator<bool> ::_M_deallocate() (in /home/will/devel/a.out) ==5197== by 0x804A3B3: std::_Bvector_base<std::allocator<bool> ::~_Bvector_base() (in /home/will/devel/a.out) ==5197== by 0x804A40B: std::vector<bool, std::allocator<bool> ::~vector() (in /home/will/devel/a.out) ==5197== by 0x804A79A: boost::program_options::options_description::~options_description() (in /home/will/devel/a.out) ==5197== by 0x8049863: main (in /home/will/devel/a.out) ==5197== Address 0x8 is not stack'd, malloc'd or (recently) free'd ==5197== ==5197== Process terminating with default action of signal 11 (SIGSEGV) ==5197== Access not within mapped region at address 0x8 ==5197== at 0x1B9ABB6E: __gnu_cxx::__pool<true>::_M_reclaim_block(char*, unsigned) (in /usr/lib/libstdc++.so.6.0.6) ==5197== by 0x804A35C: __gnu_cxx::__mt_alloc<unsigned long, __gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, true> ::deallocate(unsigned long*, unsigned) (in /home/will/devel/a.out) ==5197== by 0x804A39B: std::_Bvector_base<std::allocator<bool> ::_M_deallocate() (in /home/will/devel/a.out) ==5197== by 0x804A3B3: std::_Bvector_base<std::allocator<bool> ::~_Bvector_base() (in /home/will/devel/a.out) ==5197== by 0x804A40B: std::vector<bool, std::allocator<bool> ::~vector() (in /home/will/devel/a.out) ==5197== by 0x804A79A: boost::program_options::options_description::~options_description() (in /home/will/devel/a.out) ==5197== by 0x8049863: main (in /home/will/devel/a.out) ==5197== ==5197== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 25 from 1) ==5197== malloc/free: in use at exit: 857654 bytes in 79 blocks. ==5197== malloc/free: 81 allocs, 2 frees, 858704 bytes allocated. ==5197== For counts of detected errors, rerun with: -v ==5197== searching for pointers to 79 not-freed blocks. ==5197== checked 1037872 bytes. ==5197== ==5197== LEAK SUMMARY: ==5197== definitely lost: 0 bytes in 0 blocks. ==5197== possibly lost: 8160 bytes in 2 blocks. ==5197== still reachable: 849494 bytes in 77 blocks. ==5197== suppressed: 0 bytes in 0 blocks. ==5197== Reachable blocks (those to which a pointer was found) are not shown. ==5197== To see them, rerun with: --show-reachable=yes Segmentation fault
-- Will Bryant http://carcino.gen.nz/ will@core-dev.co.nz +64 21 655 443

Works fine on me. I'm using VC7.1 and boost 1.33.1 (beta). The output is: Test: --test arg import the specified OBJ file and save it to MDLM format Running the program in Purify I get one UMR ( Uninitialized Memory Read ) warning. May it be that you are using some compiler settings that make the program crash when there is such problem with reading uninitialized memory? In any event Vladimir should be able to figure out the problem. Here is what Purify spits out: [W] UMR: Uninitialized memory read in ?distance@Vconst_iterator@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@std@@YAHVconst_iterator@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z {1 occurrence} Reading 1 byte from 0x0013ec23 (1 byte at 0x0013ec23 uninitialized) Address 0x0013ec23 points into a thread's stack Address 0x0013ec23 is 225 bytes past the start of local variable 'Off' in ?distance@Vconst_iterator@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@std@@YAHVconst_iterator@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z Thread ID: 0x298 Error location ?distance@Vconst_iterator@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@std@@YAHVconst_iterator@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z [c:\program files\microsoft visual studio .net 2003\vc7\include\xutility.:489] boost::program_options::?A0xeaa31ea9::format_paragraph(basic_ostream<char,char_traits<char>::std>::std&,basic_string<char,char_traits<char>::std,allocator<char>::std>::std,UINT,UINT) [c:\boost\libs\program_options\src\options_description.cpp:387] { // is last_space within the second half ot the // current line => if (unsigned(distance(last_space, line_end)) < (line_length - indent) / 2) { line_end = last_space; boost::program_options::?A0xeaa31ea9::format_description(basic_ostream<char,char_traits<char>::std>::std&,basic_string<char,char_traits<char>::std,allocator<char>::std>::std const&,UINT,UINT) [c:\boost\libs\program_options\src\options_description.cpp:453] boost::program_options::?A0xeaa31ea9::format_one(basic_ostream<char,char_traits<char>::std>::std&,option_description::program_options::boost const&,UINT,UINT) [c:\boost\libs\program_options\src\options_description.cpp:489] boost::program_options::options_description::print(basic_ostream<char,char_traits<char>::std>::std&)const [c:\boost\libs\program_options\src\options_description.cpp:522] boost::program_options::<<(basic_ostream<char,char_traits<char>::std>::std&,options_description::program_options::boost const&) [c:\boost\libs\program_options\src\options_description.cpp:288] main [c:\cybermdx\test programs\iostreams\iostreams.cpp:22] mainCRTStartup [f:\vs70builds\3077\vc\crtbld\crt\src\crtexe.c:398] Regards, Christian

On 11/23/05, Christian Henning <chhenning@gmail.com> wrote:
Works fine on me. I'm using VC7.1 and boost 1.33.1 (beta). The output is:
Test: --test arg import the specified OBJ file and save it to MDLM format
Running the program in Purify I get one UMR ( Uninitialized Memory Read ) warning. May it be that you are using some compiler settings that make the program crash when there is such problem with reading uninitialized memory? In any event Vladimir should be able to figure out the problem.
Isnt reading unitialized memory undefined behvavior? And as such an error? [snip] -- Felipe Magno de Almeida Developer from synergy and Computer Science student from State University of Campinas(UNICAMP). Unicamp: http://www.ic.unicamp.br Synergy: http://www.synergy.com.br "There is no dark side of the moon really. Matter of fact it's all dark."

Will Bryant wrote:
Here's one to produce my segfault, which may or may not be the same as yours:
#include <boost/program_options.hpp> #include <iostream>
int main(int argc, char* argv[]) { try { boost::program_options::options_description desc("Test"); desc.add_options()("test", boost::program_options::value<std::string>(), "import the specified OBJ file and save it to MDLM format"); std::cerr << desc; return 0; } catch (const std::exception& except) { std::cerr << except.what() << std::endl; return 1; } }
As per my message the other day, this triggers a bug in options_description.cpp's format_paragraph function, which causes a segfault on linux with g++ 4.0.2 (and an assertion failure on Visual Studio 2005 beta 2); running it under valgrind 2.4.0 on linux produces:
Can you replace options_description.cpp with http://zigzag.cs.msu.su/~ghost/options_description.cpp And try again. The problem is that I can't reproduce the problem myself, neither with valgrind nor with libstdc++ debug mode, so I rely on users to tell if it's gone. - Volodya

Vladimir Prus wrote:
Can you replace options_description.cpp with
http://zigzag.cs.msu.su/~ghost/options_description.cpp
And try again. The problem is that I can't reproduce the problem myself, neither with valgrind nor with libstdc++ debug mode, so I rely on users to tell if it's gone.
Nope, with that version it fails on line 375: line_end = line_begin + line_length; At this point with the example program I gave, line_begin points to the word "format" and line_length is 55, which is way past the end of the string. What version of gcc are you using? I know in older libstdc++s was just a pointer, so doing things incrementing or decrementing an iterator past the beginning or end of the string wouldn't show up in valgrind until you deferenced it, but I would have thought that the iterator classes in later libstdc++s would show up such problems more readily. Best regards, Will -- Will Bryant http://carcino.gen.nz/ will@core-dev.co.nz +64 21 655 443
participants (5)
-
Christian Henning
-
Felipe Magno de Almeida
-
Merrill Cornish
-
Vladimir Prus
-
Will Bryant