0

The following code works as expected but when run with valgrind it will report an "Invalid read of size 8" error.

#include <iostream>
#include <boost/filesystem.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

namespace po = boost::program_options;

int main(int argc, char* argv[])
{
    po::options_description desc("Allowed options");
    desc.add_options()
            ("report,r", po::value<std::string>(), "single input image");
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);
    if(vm.count("report")){
        boost::filesystem::path reportFile = boost::filesystem::path(vm["report"].as<std::string>());
        boost::filesystem::path reportPath = reportFile.parent_path();
        std::string reportParentPath = reportPath.string();
        std::cout << reportParentPath << std::endl;
    }
}

when run with arguments ./boostFilesystemTest -r folder/file.html the programm returns 'folder' (as expected):

What valgrind reports:

==23831== Memcheck, a memory error detector
==23831== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==23831== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==23831== Command: ./boostFilesystemTest -r folder/file.html
==23831== 
folder
==23831== Invalid read of size 8
==23831==    at 0x63CEBC0: wcscmp (in /lib64/libc-2.15.so)
==23831==    by 0x5B9E4C3: std::moneypunct<wchar_t, false>::~moneypunct() (in /usr/lib64/libstdc++.so.6.0.17)
==23831==    by 0x5B9E548: std::moneypunct<wchar_t, false>::~moneypunct() (in /usr/lib64/libstdc++.so.6.0.17)       
==23831==    by 0x5B936B4: std::locale::_Impl::~_Impl() (in /usr/lib64/libstdc++.so.6.0.17)                         
==23831==    by 0x5B937EC: std::locale::~locale() (in /usr/lib64/libstdc++.so.6.0.17)                               
==23831==    by 0x636BC4E: __cxa_finalize (in /lib64/libc-2.15.so)                                                  
==23831==    by 0x5708272: ??? (in /usr/lib64/libboost_filesystem.so.1.49.0)                                        
==23831==    by 0x400EDDE: _dl_fini (in /lib64/ld-2.15.so)                                                          
==23831==    by 0x636B8B0: __run_exit_handlers (in /lib64/libc-2.15.so)                                             
==23831==    by 0x636B934: exit (in /lib64/libc-2.15.so)                                                            
==23831==    by 0x635545B: (below main) (in /lib64/libc-2.15.so)                                                    
==23831==  Address 0x6906668 is 0 bytes after a block of size 8 alloc'd                                             
==23831==    at 0x4C2A147: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
==23831==    by 0x5B9E1A9: std::moneypunct<wchar_t, false>::_M_initialize_moneypunct(__locale_struct*, char const*) (in /usr/lib64/libstdc++.so.6.0.17)                                                                                 
==23831==    by 0x5B95BE6: std::locale::_Impl::_Impl(char const*, unsigned long) (in /usr/lib64/libstdc++.so.6.0.17)
==23831==    by 0x5B96689: std::locale::locale(char const*) (in /usr/lib64/libstdc++.so.6.0.17)                     
==23831==    by 0x571348E: boost::filesystem3::path::wchar_t_codecvt_facet() (in /usr/lib64/libboost_filesystem.so.1.49.0)                                                                                                              
==23831==    by 0x5714A34: boost::filesystem3::path::parent_path() const (in /usr/lib64/libboost_filesystem.so.1.49.0)                                                                                                                  
==23831==    by 0x405CDF: main (main.cpp:19)                                                                        
==23831==                                                                                                           
==23831== Invalid read of size 8                                                                                    
==23831==    at 0x63CEBC0: wcscmp (in /lib64/libc-2.15.so)                                                          
==23831==    by 0x5B9E3B3: std::moneypunct<wchar_t, true>::~moneypunct() (in /usr/lib64/libstdc++.so.6.0.17)        
==23831==    by 0x5B9E438: std::moneypunct<wchar_t, true>::~moneypunct() (in /usr/lib64/libstdc++.so.6.0.17)        
==23831==    by 0x5B936B4: std::locale::_Impl::~_Impl() (in /usr/lib64/libstdc++.so.6.0.17)                         
==23831==    by 0x5B937EC: std::locale::~locale() (in /usr/lib64/libstdc++.so.6.0.17)
==23831==    by 0x636BC4E: __cxa_finalize (in /lib64/libc-2.15.so)
==23831==    by 0x5708272: ??? (in /usr/lib64/libboost_filesystem.so.1.49.0)
==23831==    by 0x400EDDE: _dl_fini (in /lib64/ld-2.15.so)
==23831==    by 0x636B8B0: __run_exit_handlers (in /lib64/libc-2.15.so)
==23831==    by 0x636B934: exit (in /lib64/libc-2.15.so)
==23831==    by 0x635545B: (below main) (in /lib64/libc-2.15.so)
==23831==  Address 0x6906898 is 0 bytes after a block of size 8 alloc'd
==23831==    at 0x4C2A147: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23831==    by 0x5B9DC19: std::moneypunct<wchar_t, true>::_M_initialize_moneypunct(__locale_struct*, char const*) (in /usr/lib64/libstdc++.so.6.0.17)
==23831==    by 0x5B95C33: std::locale::_Impl::_Impl(char const*, unsigned long) (in /usr/lib64/libstdc++.so.6.0.17)
==23831==    by 0x5B96689: std::locale::locale(char const*) (in /usr/lib64/libstdc++.so.6.0.17)
==23831==    by 0x571348E: boost::filesystem3::path::wchar_t_codecvt_facet() (in /usr/lib64/libboost_filesystem.so.1.49.0)
==23831==    by 0x5714A34: boost::filesystem3::path::parent_path() const (in /usr/lib64/libboost_filesystem.so.1.49.0)
==23831==    by 0x405CDF: main (main.cpp:19)
==23831== 
==23831== 
==23831== HEAP SUMMARY:
==23831==     in use at exit: 0 bytes in 0 blocks
==23831==   total heap usage: 539 allocs, 539 frees, 35,943 bytes allocated
==23831== 
==23831== All heap blocks were freed -- no leaks are possible
==23831== 
==23831== For counts of detected and suppressed errors, rerun with: -v
==23831== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)

I do not see where this "Invalid read of size 8" comes from and how the code can be fixed. Does anybody have an idea?

I used boost 1.49.0 on openSuse 12.2.

Edit

Running with LANG=C does not yield the invalid read of size 8 when testing with valgrind. The reason for this is unknown to me.

Sjoerd222888
  • 3,228
  • 3
  • 31
  • 64
  • Be aware that some compiler and library optimizations can cause invalid read and write warnings near the top of the stack by using unallocated stack space as temporary space (which you can ignore after verifying it is not caused by a code bug, such as passing a bad pointer to a library). – user2672165 Jan 04 '15 at 20:40
  • 1
    It looks locale related. Try with `LANG=C` perhaps to compare – sehe Jan 04 '15 at 23:17
  • Why do you think it is local related? With 'LANG=C' it does indeed not display any invalid reads. – Sjoerd222888 Jan 09 '15 at 14:25

3 Answers3

1

I'm guessing that the implementation of wcscmp has fancy code to read 8 bytes at a time as a single register fetch. It's supposed to read a byte at a time and stop at the \0, but has to deal with multibyte characters and not stop prematurely.

JDługosz
  • 5,592
  • 3
  • 24
  • 45
0

As commented by sehe, it is really locale related. Running with LANG=C does not yield the invalid read of size 8 when testing with valgrind.

Community
  • 1
  • 1
Sjoerd222888
  • 3,228
  • 3
  • 31
  • 64
0

Putting

::std::locale::global(::std::locale(""));

in the beginning of main() worked for me, I don't see silly valgrind warnings anymore.

Igor Semenov
  • 483
  • 5
  • 13