简体   繁体   English

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

[英]Valgrind prints summary with errors while application is running but says no leaks possible when finished

I am trying to pinpoint memory errors of an application with valgrind. 我试图用valgrind查明应用程序的内存错误。

Valgrind shows a strange behaviour that I haven't observed so far with it: Valgrind prints summary with errors while application is running but says all freed no leaks possible when finished Valgrind显示了一个奇怪的行为,到目前为止我还没有观察到它:Valgrind在应用程序运行时打印带有错误的摘要但是说完所有释放都没有泄漏

Unfortunately, I can not disclose the application source code behind it, but I can tell that 不幸的是,我无法透露它背后的应用程序源代码,但我可以这么说

  • the application is multi-threaded 该应用程序是多线程的
  • the application uses zmq 该应用程序使用zmq
  • the application is written in C++(11) 该应用程序是用C ++编写的(11)
  • the application is built with gcc-4.9.2 该应用程序是使用gcc-4.9.2构建的
  • runs on Debian: Debian 3.16.0-4-amd64 #1 SMP Debian 3.16.51-3 (2017-12-13) x86_64 GNU/Linux (from uname -a) 在Debian上运行:Debian 3.16.0-4-amd64#1 SMP Debian 3.16.51-3(2017-12-13)x86_64 GNU / Linux(来自uname -a)
  • I have downloaded valgrind 3.13.0 source snapshot and built it on same system with same compiler 我已经下载了valgrind 3.13.0源快照,并使用相同的编译器在同一系统上构建它

Maybe someone has a hint or clue what happens here? 也许有人暗示或暗示这里发生了什么? I am uncertain if the program runs fine or not. 我不确定该程序是否正常运行。 When debugging or testing, I discover no problems with the application, ie also with gdb attached, the application performs a graceful shutdown. 在调试或测试时,我发现应用程序没有问题,即附加了gdb,应用程序执行正常关闭。

Here's what happens: 这是发生的事情:

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)

@Vincent Saulue-Laborde, thanks you guided me to the right direction. @Vincent Saulue-Laborde,谢谢你引导我走向正确的方向。

The double-summary results from a fork behind a Poco::Process::launch call. 来自Poco::Process::launch调用后面的fork的双重摘要结果。

Here's a minimal example - note that "route" is not available on this debian (but it is, when cross-compiling this application for the actual arm-target): 这是一个最小的例子 - 注意这个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;
}

running this with valgrind and adding switch --trace-children: 用valgrind运行它并添加switch --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)

maybe I should file a bug for Poco... 也许我应该为Poco提交一个错误...

You are seeing reports of child processes. 您正在查看子进程的报告。 Each report has a process id between the equal signs. 每个报告都有等号之间的进程ID。 Which is different for the reports with memory leakage than for the final report. 具有内存泄漏的报告与最终报告的报告不同。

When a child process is started but can't just vanish out of valgrind's view with executing the target executable then it must terminate. 当子进程启动但不能通过执行目标可执行文件从valgrind的视图中消失时,它必须终止。 Unfortunately valgrind then prints a memory leak report with leaks that are not really preventable in the library code. 不幸的是,valgrind然后打印一个内存泄漏报告,其泄漏在库代码中是不可避免的。

If possible a quite work-around is starting valgrind using --child-silent-after-fork=yes which simply silences all reporting from the forked child processes. 如果可能的话,使用--child-silent-after-fork=yes启动valgrind是一个非常--child-silent-after-fork=yes解决方法, --child-silent-after-fork=yes会使分叉的子进程的所有报告--child-silent-after-fork=yes This of course is only a valid option if no child process needs to be investigated for memory leakage. 如果不需要调查内存泄漏的子进程,这当然只是一个有效的选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM