Valgrind 在 boost::filesystem::path::parent_path() 上报告大小 8 的无效读取
Valgrind reports Invalid read of size 8 on boost::filesystem::path::parent_path()
以下代码按预期工作,但在使用 valgrind 运行时会报告 "Invalid read of size 8" 错误。
#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;
}
}
当使用参数 ./boostFilesystemTest -r folder/file.html
运行时,程序 returns 'folder'(如预期):
valgrind 报告的内容:
==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)
我看不出这个 "Invalid read of size 8" 的来源以及如何修复代码。有人有想法吗?
我在 openSuse 12.2 上使用了 boost 1.49.0。
编辑
在使用 valgrind 测试时,使用 LANG=C
运行不会产生大小为 8 的无效读取。我不知道这是什么原因。
正如 sehe 评论的那样,这确实与语言环境有关。 运行 LANG=C
使用 valgrind 测试时不会产生大小为 8 的无效读取。
放
::std::locale::global(::std::locale(""));
在 main() 的开头为我工作,我不再看到愚蠢的 valgrind 警告。
我猜测 wcscmp
的实现有花哨的代码,可以一次读取 8 个字节作为单个寄存器获取。它应该一次读取一个字节并在 [=11=]
处停止,但必须处理多字节字符并且不能过早停止。
以下代码按预期工作,但在使用 valgrind 运行时会报告 "Invalid read of size 8" 错误。
#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;
}
}
当使用参数 ./boostFilesystemTest -r folder/file.html
运行时,程序 returns 'folder'(如预期):
valgrind 报告的内容:
==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)
我看不出这个 "Invalid read of size 8" 的来源以及如何修复代码。有人有想法吗?
我在 openSuse 12.2 上使用了 boost 1.49.0。
编辑
在使用 valgrind 测试时,使用 LANG=C
运行不会产生大小为 8 的无效读取。我不知道这是什么原因。
正如 sehe 评论的那样,这确实与语言环境有关。 运行 LANG=C
使用 valgrind 测试时不会产生大小为 8 的无效读取。
放
::std::locale::global(::std::locale(""));
在 main() 的开头为我工作,我不再看到愚蠢的 valgrind 警告。
我猜测 wcscmp
的实现有花哨的代码,可以一次读取 8 个字节作为单个寄存器获取。它应该一次读取一个字节并在 [=11=]
处停止,但必须处理多字节字符并且不能过早停止。