【问题标题】:Memory leak when linking against opencv与opencv链接时内存泄漏
【发布时间】:2017-01-09 07:58:05
【问题描述】:

我正在链接一个库与 opencv 库。我注意到,当我为该库运行单元测试可执行文件(使用 GTest)时,valgrind 报告内存泄漏/条件跳转或移动取决于未初始化的值,即使测试根本没有做任何事情(只是空测试方法)。

我将该问题追溯到我的 CMakeLists.txt 中的一行 - 当我删除与 opencv 的链接时,内存泄漏就消失了。这是相关的sn-p:

find_package(OpenCV REQUIRED)

set(libImageSources src/SourceImageFile.cpp)

add_library(image SHARED ${libImageSources})

# removing this line fixes the leak:
target_link_libraries(image ${OpenCV_LIBS})

否则在运行空单元测试时,我会收到如下错误:

==18681== Memcheck, a memory error detector
==18681== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==18681== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==18681== Command: ./image_test /Users/max/Documents/playground/cpp/image-server/tests
==18681==
==18681== Conditional jump or move depends on uninitialised value(s)
==18681==    at 0x7FFF5FC24A27: bcmp (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC11904: ImageLoaderMachO::validateFirstPages(linkedit_data_command const*, int, unsigned char const*, unsigned long, long long, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC16B7A: ImageLoaderMachOCompressed::instantiateFromFile(char const*, int, unsigned char const*, unsigned long, unsigned long long, unsigned long long, stat const&, unsigned int, unsigned int, linkedit_data_command const*, encryption_info_command const*, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC10A6E: ImageLoaderMachO::instantiateFromFile(char const*, int, unsigned char const*, unsigned long long, unsigned long long, stat const&, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC038C2: dyld::loadPhase6(int, stat const&, char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC08468: dyld::loadPhase5(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC08188: dyld::loadPhase4(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC07EED: dyld::loadPhase3(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC07642: dyld::loadPhase1(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC0347A: dyld::loadPhase0(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC0315E: dyld::load(char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC08705: dyld::libraryLocator(char const*, bool, char const*, ImageLoader::RPathChain const*) (in /usr/lib/dyld)
==18681==
==18681== Use of uninitialised value of size 8
==18681==    at 0x7FFF5FC24A3F: bcmp (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC11904: ImageLoaderMachO::validateFirstPages(linkedit_data_command const*, int, unsigned char const*, unsigned long, long long, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC16B7A: ImageLoaderMachOCompressed::instantiateFromFile(char const*, int, unsigned char const*, unsigned long, unsigned long long, unsigned long long, stat const&, unsigned int, unsigned int, linkedit_data_command const*, encryption_info_command const*, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC10A6E: ImageLoaderMachO::instantiateFromFile(char const*, int, unsigned char const*, unsigned long long, unsigned long long, stat const&, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC038C2: dyld::loadPhase6(int, stat const&, char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC08468: dyld::loadPhase5(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC08188: dyld::loadPhase4(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC07EED: dyld::loadPhase3(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC07642: dyld::loadPhase1(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC0347A: dyld::loadPhase0(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC0315E: dyld::load(char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC08705: dyld::libraryLocator(char const*, bool, char const*, ImageLoader::RPathChain const*) (in /usr/lib/dyld)
==18681==
==18681== Use of uninitialised value of size 8
==18681==    at 0x7FFF5FC24A44: bcmp (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC11904: ImageLoaderMachO::validateFirstPages(linkedit_data_command const*, int, unsigned char const*, unsigned long, long long, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC16B7A: ImageLoaderMachOCompressed::instantiateFromFile(char const*, int, unsigned char const*, unsigned long, unsigned long long, unsigned long long, stat const&, unsigned int, unsigned int, linkedit_data_command const*, encryption_info_command const*, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC10A6E: ImageLoaderMachO::instantiateFromFile(char const*, int, unsigned char const*, unsigned long long, unsigned long long, stat const&, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC038C2: dyld::loadPhase6(int, stat const&, char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC08468: dyld::loadPhase5(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC08188: dyld::loadPhase4(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC07EED: dyld::loadPhase3(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC07642: dyld::loadPhase1(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC0347A: dyld::loadPhase0(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC0315E: dyld::load(char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC08705: dyld::libraryLocator(char const*, bool, char const*, ImageLoader::RPathChain const*) (in /usr/lib/dyld)
==18681==
==18681== Conditional jump or move depends on uninitialised value(s)
==18681==    at 0x7FFF5FC11907: ImageLoaderMachO::validateFirstPages(linkedit_data_command const*, int, unsigned char const*, unsigned long, long long, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC16B7A: ImageLoaderMachOCompressed::instantiateFromFile(char const*, int, unsigned char const*, unsigned long, unsigned long long, unsigned long long, stat const&, unsigned int, unsigned int, linkedit_data_command const*, encryption_info_command const*, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC10A6E: ImageLoaderMachO::instantiateFromFile(char const*, int, unsigned char const*, unsigned long long, unsigned long long, stat const&, ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC038C2: dyld::loadPhase6(int, stat const&, char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC08468: dyld::loadPhase5(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC08188: dyld::loadPhase4(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC07EED: dyld::loadPhase3(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC07642: dyld::loadPhase1(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC0347A: dyld::loadPhase0(char const*, char const*, dyld::LoadContext const&, std::__1::vector<char const*, std::__1::allocator<char const*> >*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC0315E: dyld::load(char const*, dyld::LoadContext const&) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC08705: dyld::libraryLocator(char const*, bool, char const*, ImageLoader::RPathChain const*) (in /usr/lib/dyld)
==18681==    by 0x7FFF5FC0E85D: ImageLoader::recursiveLoadLibraries(ImageLoader::LinkContext const&, bool, ImageLoader::RPathChain const&) (in /usr/lib/dyld)
==18681==
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from ImageProcessingConfigurationService
[ RUN      ] ImageProcessingConfigurationService.evaluateConfigurationFile
[       OK ] ImageProcessingConfigurationService.evaluateConfigurationFile (13 ms)
[----------] 1 test from ImageProcessingConfigurationService (28 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (114 ms total)
[  PASSED  ] 1 test.
==18681==
==18681== HEAP SUMMARY:
==18681==     in use at exit: 1,346,030 bytes in 1,453 blocks
==18681==   total heap usage: 2,926 allocs, 1,473 frees, 3,045,052 bytes allocated
==18681==
==18681== LEAK SUMMARY:
==18681==    definitely lost: 10,580 bytes in 137 blocks
==18681==    indirectly lost: 10,032 bytes in 152 blocks
==18681==      possibly lost: 9,568 bytes in 183 blocks
==18681==    still reachable: 43,598 bytes in 520 blocks
==18681==         suppressed: 1,272,252 bytes in 461 blocks
==18681== Rerun with --leak-check=full to see details of leaked memory
==18681==
==18681== For counts of detected and suppressed errors, rerun with: -v
==18681== Use --track-origins=yes to see where uninitialised values come from
==18681== ERROR SUMMARY: 36 errors from 4 contexts (suppressed: 0 from 0)

编译器是 clang++ Apple LLVM 版本 7.3.0 (clang-703.0.31),OS X El Capitan (10.11.1)。

其他人遇到过这样的问题吗?看起来东西仍然有效,但错误会产生我宁愿忽略的噪音,我不确定我是否可以解决根本原因。

【问题讨论】:

  • ... that valgrind reports a memory leak/invalid free - 在错误日志中,我在动态加载程序中只看到内存泄漏加上Conditional jump or move depends on uninitialised value。没有“无效免费”左右。
  • @Tsyvarev 没错,我的意思是jump on unitialized value 消息,抱歉。我认为这很可能是 valgrind 的误报,我使用 OS X 分析器来检查内存泄漏,看起来还不错。
  • @usr1234567 我在调试时认为它与 CMake 无关,但感谢您的指点。

标签: c++ macos opencv valgrind


【解决方案1】:

这个问题似乎是 valgrind 报告的误报,我可以忽略它,因为它不是由代码引起的。

我尝试了(在撰写本文时)最新的valgrind suppressions file for macOS,但它对我不起作用,问题仍然存在。

我让valgrind dump the suppressions 需要忽略这个错误,使用如下命令:

valgrind --leak-check=full --show-reachable=yes --error-limit=no --gen-suppressions=all --log-file=l.log ./image_test

然后使用a tool to parse the log output(awk 脚本对我不起作用,因为它包含语法错误,我使用了 perl 版本)到抑制文件中:

cat l.log | ./parse_valgrind_suppressions.pl > s.supp

现在使用生成的抑制文件运行测试会忽略内存泄漏:

valgrind --suppressions=./s.supp ./image_test

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    • 1970-01-01
    • 2015-12-05
    • 2018-05-20
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    相关资源
    最近更新 更多