Valgrind在应用程序运行时打印带有错误的摘要,但表示完成时不会发生泄漏

时间:2018-06-12 11:39:30

标签: c++ memory-leaks fork valgrind poco-libraries

我试图用valgrind查明应用程序的内存错误。

Valgrind显示了一个奇怪的行为,到目前为止我还没有观察到它:Valgrind在应用程序运行时打印带有错误的摘要但是说完成后所有释放都没有泄漏

不幸的是,我无法透露它背后的应用程序源代码,但我可以告诉它

  • 应用程序是多线程的
  • 该应用程序使用zmq
  • 应用程序是用C ++(11)
  • 编写的
  • 应用程序使用gcc-4.9.2
  • 构建
  • 在Debian上运行:Debian 3.16.0-4-amd64#1 SMP Debian 3.16.51-3(2017-12-13)x86_64 GNU / Linux(来自uname -a)
  • 我已经下载了valgrind 3.13.0源快照,并使用相同的编译器在同一系统上构建它

也许某人有暗示或暗示这里会发生什么?我不确定该程序是否正常运行。在调试或测试时,我发现应用程序没有问题,即附加了gdb,应用程序执行正常关闭。

以下是发生的事情:

valgrind ./<application>


==11431== Memcheck, a memory error detector
==11431== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11431== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==11431== Command: ./<<application>>
==11431== 

                     << output from application being analyzed >>

==11446== 
==11446== HEAP SUMMARY:
==11446==     in use at exit: 36,963,243 bytes in 12,456 blocks
==11446==   total heap usage: 112,306 allocs, 99,850 frees, 167,728,353 bytes allocated
==11446== 
==11446== LEAK SUMMARY:
==11446==    definitely lost: 13,419 bytes in 163 blocks
==11446==    indirectly lost: 24,368 bytes in 486 blocks
==11446==      possibly lost: 5,741 bytes in 106 blocks
==11446==    still reachable: 36,919,715 bytes in 11,701 blocks
==11446==                       of which reachable via heuristic:
==11446==                         stdstring          : 211,119 bytes in 5,162 blocks
==11446==         suppressed: 0 bytes in 0 blocks
==11446== Rerun with --leak-check=full to see details of leaked memory
==11446== 
==11446== For counts of detected and suppressed errors, rerun with: -v
==11446== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==11448== 
==11448== HEAP SUMMARY:
==11448==     in use at exit: 37,699,870 bytes in 12,837 blocks
==11448==   total heap usage: 115,854 allocs, 103,017 frees, 168,950,644 bytes allocated
==11448== 
==11448== LEAK SUMMARY:
==11448==    definitely lost: 14,252 bytes in 155 blocks
==11448==    indirectly lost: 24,864 bytes in 498 blocks
==11448==      possibly lost: 5,749 bytes in 106 blocks
==11448==    still reachable: 37,655,005 bytes in 12,078 blocks
==11448==                       of which reachable via heuristic:
==11448==                         stdstring          : 214,732 bytes in 5,238 blocks
==11448==         suppressed: 0 bytes in 0 blocks
==11448== Rerun with --leak-check=full to see details of leaked memory
==11448== 
==11448== For counts of detected and suppressed errors, rerun with: -v
==11448== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==11449== 
==11449== HEAP SUMMARY:
==11449==     in use at exit: 37,817,537 bytes in 12,875 blocks
==11449==   total heap usage: 119,125 allocs, 106,250 frees, 170,106,138 bytes allocated
==11449== 
==11449== LEAK SUMMARY:
==11449==    definitely lost: 12,013 bytes in 146 blocks
==11449==    indirectly lost: 24,864 bytes in 498 blocks
==11449==      possibly lost: 5,749 bytes in 106 blocks
==11449==    still reachable: 37,774,911 bytes in 12,125 blocks
==11449==                       of which reachable via heuristic:
==11449==                         stdstring          : 215,361 bytes in 5,252 blocks
==11449==                         multipleinheritance: 992 bytes in 1 blocks
==11449==         suppressed: 0 bytes in 0 blocks
==11449== Rerun with --leak-check=full to see details of leaked memory
==11449== 
==11449== For counts of detected and suppressed errors, rerun with: -v
==11449== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

               << output from application being analyzed, app is shutting down now >>

==11431== 
==11431== HEAP SUMMARY:
==11431==     in use at exit: 0 bytes in 0 blocks
==11431==   total heap usage: 343,376 allocs, 343,376 frees, 329,511,726 bytes allocated
==11431== 
==11431== All heap blocks were freed -- no leaks are possible
==11431== 
==11431== For counts of detected and suppressed errors, rerun with: -v
==11431== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

2 个答案:

答案 0 :(得分:3)

@Vincent Saulue-Laborde,谢谢你引导我走向正确的方向。

fork电话后面Poco::Process::launch的双重摘要结果。

这是一个最小的例子 - 请注意,这个debian上没有“route”(但是,当为实际的arm-target交叉编译这个应用程序时):

#include <iostream>
#include <Poco/Process.h>
#include <Poco/Pipe.h>

int main()
{
    Poco::Pipe out_pipe;
    if (Poco::Process::launch("route", {}, 0, &out_pipe, 0).wait() == EXIT_SUCCESS) { }
    return 0;
}

使用valgrind运行它并添加开关--trace-children:

    valgrind --leak-check=full --trace-children=yes ./hello_world
==1814== Memcheck, a memory error detector
==1814== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1814== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1814== Command: ./hello_world
==1814== 
==1815== 
==1815== HEAP SUMMARY:
==1815==     in use at exit: 10,612 bytes in 102 blocks
==1815==   total heap usage: 113 allocs, 11 frees, 13,028 bytes allocated
==1815== 
==1815== 16 bytes in 1 blocks are definitely lost in loss record 3 of 102
==1815==    at 0x4C28215: operator new(unsigned long) (vg_replace_malloc.c:334)
==1815==    by 0x7B40147: Poco::ProcessImpl::launchByForkExecImpl(std::string const&, std::vector<std::string, std::allocator<std::string> > const&, std::string const&, Poco::Pipe*, Poco::Pipe*, Poco::Pipe*, std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > > const&) (in /home/user/dev/zedboard/build/deps/host/Debug/lib/libPocoFoundation.so.60)
==1815==    by 0x7B41648: Poco::Process::launch(std::string const&, std::vector<std::string, std::allocator<std::string> > const&, Poco::Pipe*, Poco::Pipe*, Poco::Pipe*) (in /home/user/dev/zedboard/build/deps/host/Debug/lib/libPocoFoundation.so.60)
==1815==    by 0x401E09: main (main.cpp:8)
==1815== 
==1815== LEAK SUMMARY:
==1815==    definitely lost: 16 bytes in 1 blocks
==1815==    indirectly lost: 0 bytes in 0 blocks
==1815==      possibly lost: 0 bytes in 0 blocks
==1815==    still reachable: 10,596 bytes in 101 blocks
==1815==                       of which reachable via heuristic:
==1815==                         stdstring          : 3,123 bytes in 87 blocks
==1815==         suppressed: 0 bytes in 0 blocks
==1815== Reachable blocks (those to which a pointer was found) are not shown.
==1815== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1815== 
==1815== For counts of detected and suppressed errors, rerun with: -v
==1815== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==1814== 
==1814== HEAP SUMMARY:
==1814==     in use at exit: 0 bytes in 0 blocks
==1814==   total heap usage: 116 allocs, 116 frees, 13,837 bytes allocated
==1814== 
==1814== All heap blocks were freed -- no leaks are possible
==1814== 
==1814== For counts of detected and suppressed errors, rerun with: -v
==1814== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

也许我应该为Poco提交一个错误...

答案 1 :(得分:0)

您正在看到子进程的报告。每个报告在等号之间都有一个进程ID。内存泄漏报告与最终报告不同。

启动子进程但不能通过执行目标可执行文件而从valgrind的视图中消失时,它必须终止。不幸的是,valgrind然后打印出内存泄漏报告,其中包含在库代码中无法真正阻止的泄漏。

如果可能的话,可以使用--child-silent-after-fork=yes来启动valgrind,这只会使派生子进程中的所有报告都保持沉默。当然,如果不需要调查子进程是否存在内存泄漏,这当然是一个有效的选择。