PRE-2016瓦尔格林: 使用 < iostream > 的普通程序仍然可以访问内存

编辑: 我已经投票结束了,现在这是不正确的。

2016年3月,瓦尔恩获得了一个选项“-run-cxx-freeres = < yes | no >”(默认为 yes)。这将调用一个 libstdc + + 函数来释放用于 iostream 之类事物的一次性分配。如果您使用的是2016年之后的瓦尔格林和 libstdc + + ,那么您将获得

==9356== HEAP SUMMARY:
==9356==     in use at exit: 0 bytes in 0 blocks
==9356==   total heap usage: 1 allocs, 1 frees, 72,704 bytes allocated
==9356==
==9356== All heap blocks were freed -- no leaks are possible

原文:

以下面这些琐碎的程序为例:

#include <iostream>
int main() {
return 0;
}

如果我运行这个使用瓦尔格林,我被告知,有 72,704 bytes in 1 blocksstill reachable。关于是否需要担心仍然可以到达的警告,已经进行了广泛的讨论——我不关心这个。我只是想了解,当标准库头 包括的任何对象都没有在程序本身中分配时,它是如何简单地导致仍然可到达的警告的。

以下是完整的 valgrind输出:

$ valgrind --leak-check=full --track-origins=yes --show-reachable=yes ./ValgrindTest
==27671== Memcheck, a memory error detector
==27671== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==27671== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==27671== Command: ./ValgrindTest
==27671==
==27671==
==27671== HEAP SUMMARY:
==27671==     in use at exit: 72,704 bytes in 1 blocks
==27671==   total heap usage: 1 allocs, 0 frees, 72,704 bytes allocated
==27671==
==27671== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==27671==    at 0x4C2AB9D: malloc (vg_replace_malloc.c:296)
==27671==    by 0x4EC060F: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==27671==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==27671==    by 0x400F3DE: call_init (dl-init.c:52)
==27671==    by 0x400F3DE: _dl_init (dl-init.c:134)
==27671==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==27671==
==27671== LEAK SUMMARY:
==27671==    definitely lost: 0 bytes in 0 blocks
==27671==    indirectly lost: 0 bytes in 0 blocks
==27671==      possibly lost: 0 bytes in 0 blocks
==27671==    still reachable: 72,704 bytes in 1 blocks
==27671==         suppressed: 0 bytes in 0 blocks
==27671==
==27671== For counts of detected and suppressed errors, rerun with: -v
==27671== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

还有一个对象转储:

$ objdump -d ValgrindTest


ValgrindTest:     file format elf64-x86-64




Disassembly of section .init:


0000000000400718 <_init>:
400718:   48 83 ec 08             sub    $0x8,%rsp
40071c:   e8 8b 00 00 00          callq  4007ac <call_gmon_start>
400721:   48 83 c4 08             add    $0x8,%rsp
400725:   c3                      retq


Disassembly of section .plt:


0000000000400730 <_ZNSt8ios_base4InitC1Ev@plt-0x10>:
400730:   ff 35 ba 08 20 00       pushq  0x2008ba(%rip)        # 600ff0 <_GLOBAL_OFFSET_TABLE_+0x8>
400736:   ff 25 bc 08 20 00       jmpq   *0x2008bc(%rip)        # 600ff8 <_GLOBAL_OFFSET_TABLE_+0x10>
40073c:   0f 1f 40 00             nopl   0x0(%rax)


0000000000400740 <_ZNSt8ios_base4InitC1Ev@plt>:
400740:   ff 25 ba 08 20 00       jmpq   *0x2008ba(%rip)        # 601000 <_GLOBAL_OFFSET_TABLE_+0x18>
400746:   68 00 00 00 00          pushq  $0x0
40074b:   e9 e0 ff ff ff          jmpq   400730 <_init+0x18>


0000000000400750 <__libc_start_main@plt>:
400750:   ff 25 b2 08 20 00       jmpq   *0x2008b2(%rip)        # 601008 <_GLOBAL_OFFSET_TABLE_+0x20>
400756:   68 01 00 00 00          pushq  $0x1
40075b:   e9 d0 ff ff ff          jmpq   400730 <_init+0x18>


0000000000400760 <__cxa_atexit@plt>:
400760:   ff 25 aa 08 20 00       jmpq   *0x2008aa(%rip)        # 601010 <_GLOBAL_OFFSET_TABLE_+0x28>
400766:   68 02 00 00 00          pushq  $0x2
40076b:   e9 c0 ff ff ff          jmpq   400730 <_init+0x18>


0000000000400770 <_ZNSt8ios_base4InitD1Ev@plt>:
400770:   ff 25 a2 08 20 00       jmpq   *0x2008a2(%rip)        # 601018 <_GLOBAL_OFFSET_TABLE_+0x30>
400776:   68 03 00 00 00          pushq  $0x3
40077b:   e9 b0 ff ff ff          jmpq   400730 <_init+0x18>


Disassembly of section .text:


0000000000400780 <_start>:
400780:   31 ed                   xor    %ebp,%ebp
400782:   49 89 d1                mov    %rdx,%r9
400785:   5e                      pop    %rsi
400786:   48 89 e2                mov    %rsp,%rdx
400789:   48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
40078d:   50                      push   %rax
40078e:   54                      push   %rsp
40078f:   49 c7 c0 80 09 40 00    mov    $0x400980,%r8
400796:   48 c7 c1 f0 08 40 00    mov    $0x4008f0,%rcx
40079d:   48 c7 c7 90 08 40 00    mov    $0x400890,%rdi
4007a4:   e8 a7 ff ff ff          callq  400750 <__libc_start_main@plt>
4007a9:   f4                      hlt
4007aa:   90                      nop
4007ab:   90                      nop


00000000004007ac <call_gmon_start>:
4007ac:   48 83 ec 08             sub    $0x8,%rsp
4007b0:   48 8b 05 29 08 20 00    mov    0x200829(%rip),%rax        # 600fe0 <_DYNAMIC+0x1f0>
4007b7:   48 85 c0                test   %rax,%rax
4007ba:   74 02                   je     4007be <call_gmon_start+0x12>
4007bc:   ff d0                   callq  *%rax
4007be:   48 83 c4 08             add    $0x8,%rsp
4007c2:   c3                      retq
4007c3:   90                      nop
4007c4:   90                      nop
4007c5:   90                      nop
4007c6:   90                      nop
4007c7:   90                      nop
4007c8:   90                      nop
4007c9:   90                      nop
4007ca:   90                      nop
4007cb:   90                      nop
4007cc:   90                      nop
4007cd:   90                      nop
4007ce:   90                      nop
4007cf:   90                      nop


00000000004007d0 <deregister_tm_clones>:
4007d0:   b8 37 10 60 00          mov    $0x601037,%eax
4007d5:   55                      push   %rbp
4007d6:   48 2d 30 10 60 00       sub    $0x601030,%rax
4007dc:   48 83 f8 0e             cmp    $0xe,%rax
4007e0:   48 89 e5                mov    %rsp,%rbp
4007e3:   77 02                   ja     4007e7 <deregister_tm_clones+0x17>
4007e5:   5d                      pop    %rbp
4007e6:   c3                      retq
4007e7:   b8 00 00 00 00          mov    $0x0,%eax
4007ec:   48 85 c0                test   %rax,%rax
4007ef:   74 f4                   je     4007e5 <deregister_tm_clones+0x15>
4007f1:   5d                      pop    %rbp
4007f2:   bf 30 10 60 00          mov    $0x601030,%edi
4007f7:   ff e0                   jmpq   *%rax
4007f9:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)


0000000000400800 <register_tm_clones>:
400800:   b8 30 10 60 00          mov    $0x601030,%eax
400805:   55                      push   %rbp
400806:   48 2d 30 10 60 00       sub    $0x601030,%rax
40080c:   48 c1 f8 03             sar    $0x3,%rax
400810:   48 89 e5                mov    %rsp,%rbp
400813:   48 89 c2                mov    %rax,%rdx
400816:   48 c1 ea 3f             shr    $0x3f,%rdx
40081a:   48 01 d0                add    %rdx,%rax
40081d:   48 d1 f8                sar    %rax
400820:   75 02                   jne    400824 <register_tm_clones+0x24>
400822:   5d                      pop    %rbp
400823:   c3                      retq
400824:   ba 00 00 00 00          mov    $0x0,%edx
400829:   48 85 d2                test   %rdx,%rdx
40082c:   74 f4                   je     400822 <register_tm_clones+0x22>
40082e:   5d                      pop    %rbp
40082f:   48 89 c6                mov    %rax,%rsi
400832:   bf 30 10 60 00          mov    $0x601030,%edi
400837:   ff e2                   jmpq   *%rdx
400839:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)


0000000000400840 <__do_global_dtors_aux>:
400840:   80 3d e9 07 20 00 00    cmpb   $0x0,0x2007e9(%rip)        # 601030 <__bss_start>
400847:   75 11                   jne    40085a <__do_global_dtors_aux+0x1a>
400849:   55                      push   %rbp
40084a:   48 89 e5                mov    %rsp,%rbp
40084d:   e8 7e ff ff ff          callq  4007d0 <deregister_tm_clones>
400852:   5d                      pop    %rbp
400853:   c6 05 d6 07 20 00 01    movb   $0x1,0x2007d6(%rip)        # 601030 <__bss_start>
40085a:   f3 c3                   repz retq
40085c:   0f 1f 40 00             nopl   0x0(%rax)


0000000000400860 <frame_dummy>:
400860:   48 83 3d 80 05 20 00    cmpq   $0x0,0x200580(%rip)        # 600de8 <__JCR_END__>
400867:   00
400868:   74 1e                   je     400888 <frame_dummy+0x28>
40086a:   b8 00 00 00 00          mov    $0x0,%eax
40086f:   48 85 c0                test   %rax,%rax
400872:   74 14                   je     400888 <frame_dummy+0x28>
400874:   55                      push   %rbp
400875:   bf e8 0d 60 00          mov    $0x600de8,%edi
40087a:   48 89 e5                mov    %rsp,%rbp
40087d:   ff d0                   callq  *%rax
40087f:   5d                      pop    %rbp
400880:   e9 7b ff ff ff          jmpq   400800 <register_tm_clones>
400885:   0f 1f 00                nopl   (%rax)
400888:   e9 73 ff ff ff          jmpq   400800 <register_tm_clones>
40088d:   90                      nop
40088e:   90                      nop
40088f:   90                      nop


0000000000400890 <main>:
400890:   55                      push   %rbp
400891:   48 89 e5                mov    %rsp,%rbp
400894:   b8 00 00 00 00          mov    $0x0,%eax
400899:   5d                      pop    %rbp
40089a:   c3                      retq


000000000040089b <_Z41__static_initialization_and_destruction_0ii>:
40089b:   55                      push   %rbp
40089c:   48 89 e5                mov    %rsp,%rbp
40089f:   48 83 ec 10             sub    $0x10,%rsp
4008a3:   89 7d fc                mov    %edi,-0x4(%rbp)
4008a6:   89 75 f8                mov    %esi,-0x8(%rbp)
4008a9:   83 7d fc 01             cmpl   $0x1,-0x4(%rbp)
4008ad:   75 27                   jne    4008d6 <_Z41__static_initialization_and_destruction_0ii+0x3b>
4008af:   81 7d f8 ff ff 00 00    cmpl   $0xffff,-0x8(%rbp)
4008b6:   75 1e                   jne    4008d6 <_Z41__static_initialization_and_destruction_0ii+0x3b>
4008b8:   bf 34 10 60 00          mov    $0x601034,%edi
4008bd:   e8 7e fe ff ff          callq  400740 <_ZNSt8ios_base4InitC1Ev@plt>
4008c2:   ba 28 10 60 00          mov    $0x601028,%edx
4008c7:   be 34 10 60 00          mov    $0x601034,%esi
4008cc:   bf 70 07 40 00          mov    $0x400770,%edi
4008d1:   e8 8a fe ff ff          callq  400760 <__cxa_atexit@plt>
4008d6:   c9                      leaveq
4008d7:   c3                      retq


00000000004008d8 <_GLOBAL__sub_I_main>:
4008d8:   55                      push   %rbp
4008d9:   48 89 e5                mov    %rsp,%rbp
4008dc:   be ff ff 00 00          mov    $0xffff,%esi
4008e1:   bf 01 00 00 00          mov    $0x1,%edi
4008e6:   e8 b0 ff ff ff          callq  40089b <_Z41__static_initialization_and_destruction_0ii>
4008eb:   5d                      pop    %rbp
4008ec:   c3                      retq
4008ed:   90                      nop
4008ee:   90                      nop
4008ef:   90                      nop


00000000004008f0 <__libc_csu_init>:
4008f0:   48 89 6c 24 d8          mov    %rbp,-0x28(%rsp)
4008f5:   4c 89 64 24 e0          mov    %r12,-0x20(%rsp)
4008fa:   48 8d 2d df 04 20 00    lea    0x2004df(%rip),%rbp        # 600de0 <__init_array_end>
400901:   4c 8d 25 c8 04 20 00    lea    0x2004c8(%rip),%r12        # 600dd0 <__frame_dummy_init_array_entry>
400908:   4c 89 6c 24 e8          mov    %r13,-0x18(%rsp)
40090d:   4c 89 74 24 f0          mov    %r14,-0x10(%rsp)
400912:   4c 89 7c 24 f8          mov    %r15,-0x8(%rsp)
400917:   48 89 5c 24 d0          mov    %rbx,-0x30(%rsp)
40091c:   48 83 ec 38             sub    $0x38,%rsp
400920:   4c 29 e5                sub    %r12,%rbp
400923:   41 89 fd                mov    %edi,%r13d
400926:   49 89 f6                mov    %rsi,%r14
400929:   48 c1 fd 03             sar    $0x3,%rbp
40092d:   49 89 d7                mov    %rdx,%r15
400930:   e8 e3 fd ff ff          callq  400718 <_init>
400935:   48 85 ed                test   %rbp,%rbp
400938:   74 1c                   je     400956 <__libc_csu_init+0x66>
40093a:   31 db                   xor    %ebx,%ebx
40093c:   0f 1f 40 00             nopl   0x0(%rax)
400940:   4c 89 fa                mov    %r15,%rdx
400943:   4c 89 f6                mov    %r14,%rsi
400946:   44 89 ef                mov    %r13d,%edi
400949:   41 ff 14 dc             callq  *(%r12,%rbx,8)
40094d:   48 83 c3 01             add    $0x1,%rbx
400951:   48 39 eb                cmp    %rbp,%rbx
400954:   75 ea                   jne    400940 <__libc_csu_init+0x50>
400956:   48 8b 5c 24 08          mov    0x8(%rsp),%rbx
40095b:   48 8b 6c 24 10          mov    0x10(%rsp),%rbp
400960:   4c 8b 64 24 18          mov    0x18(%rsp),%r12
400965:   4c 8b 6c 24 20          mov    0x20(%rsp),%r13
40096a:   4c 8b 74 24 28          mov    0x28(%rsp),%r14
40096f:   4c 8b 7c 24 30          mov    0x30(%rsp),%r15
400974:   48 83 c4 38             add    $0x38,%rsp
400978:   c3                      retq
400979:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)


0000000000400980 <__libc_csu_fini>:
400980:   f3 c3                   repz retq
400982:   90                      nop
400983:   90                      nop


Disassembly of section .fini:


0000000000400984 <_fini>:
400984:   48 83 ec 08             sub    $0x8,%rsp
400988:   48 83 c4 08             add    $0x8,%rsp
40098c:   c3                      retq

为了完整起见,我使用:
Ubuntu: 12.04
瓦尔格林: 3.10.1 < strike > 3.7.0
G + + : 4.8.1

注意: 这种情况不会发生在我包含其他报头的时候,比如 <fstream>或者 <cmath>

30037 次浏览

考虑以下简单的 include 文件:

#ifndef TRIVIAL_INCLUDE_FILE
#define TRIVIAL_INCLUDE_FILE
static int *x = new int (0);
#endif

这是瓦尔冈的错。首先,-fsanitize=leak没有显示任何东西。其次,瓦尔冈本身 国家:

首先: 放松,它可能不是一个 bug,而是一个特性 C + + 标准库的实现使用它们自己的内存 池分配器。相当数量的被破坏对象的内存是 没有立即释放并返回给操作系统,而是保存在 池以供以后重用 程序的退出导致瓦尔格伦报告这段记忆为静止 在出口处不释放池的行为可以被调用 但是图书馆的一个漏洞。

使用 GCC,您可以强制 STL 使用 malloc 并释放内存 通过全局禁用内存缓存来尽快实现 所以可能会降低程序的运行速度,有时会大幅度降低。

使用 GCC 2.91、2.95、3.0和3.1,使用 STL 编译所有源代码 注意! 这是从 GCC 中删除的,从 版本3.3。

使用 gcc3.2.2及更高版本,您应该导出环境变量 GLIBCPP _ FORCE _ NEW 在运行程序之前。

在 GCC 3.4及更高版本中,该变量的名称更改为 GLIBCXX _ FORCE _ NEW.

[...]

我猜想这些所谓的内存池被释放 之后程序的终止,在所谓的启动代码,调用 main,在其他设置。在用户代码之外定义的内部函数应该被视为不存在,这就是为什么 ValGraduate 不能(也不应该)看到更多的空闲。

对于 gcc6或更高版本,有一个相关的 bug 修复程序:

使用 gcc5,您也可以在不包括 iostream的情况下获得相同的警告。

因此,如果您看到类似的警告提及 dl-init.c,并且正在使用 gcc 5,请考虑升级到更新的版本(gcc > = 6) ,或者尝试使用 clang 进行编译。