Nehmen Sie das folgende triviale Programm:
#include <iostream>
int main() {
return 0;
}
Wenn ich dies mit valgrind ausführe, wird mir gesagt, dass es solche 72,704 bytes in 1 blocks
gibt still reachable
. Es gab umfangreiche Diskussionen über SO darüber, ob man sich über noch erreichbare Warnungen Sorgen machen sollte oder nicht - darüber mache ich mir keine Sorgen. Ich möchte nur verstehen, wie das einfache Einfügen eines Standard-Bibliotheks-Headers zu einer immer noch erreichbaren Warnung führen kann, wenn keines der Objekte aus dieser Bibliothek im Programm selbst zugewiesen wurde.
Hier ist die vollständige valgrind
Ausgabe:
$ 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)
Und ein Objekt-Dump:
$ 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
Der Vollständigkeit
halber verwende ich:
Ubuntu: 12.04
Valgrind: 3.10.1 3.7.0
g ++: 4.8.1
NB: Als Randnotiz passiert dies nicht, wenn ich andere Header wie <fstream>
oder einbinde <cmath>
.
-fsanitize=leak
Antworten:
Es ist Valgrinds Schuld. Erstens
-fsanitize=leak
zeigt nichts. Zweitens stellt Valgrind selbst fest :Ich denke, diese angeblichen Speicherpools werden nach Beendigung des Programms freigegeben , unter anderem im sogenannten Startcode, der aufruft
main
. Interne Funktionen, die außerhalb des Benutzercodes definiert sind, sollten so behandelt werden, als ob sie nicht vorhanden wären. Deshalb kann (und sollte) Valgrind keine weiteren Freigaben sehen.quelle
Betrachten Sie die folgende triviale Include-Datei:
#ifndef TRIVIAL_INCLUDE_FILE #define TRIVIAL_INCLUDE_FILE static int *x = new x (0); #endif
quelle
error: expected type-specifier before ‘x’
Für gcc 6 und höher ist eine entsprechende Fehlerbehebung eingetroffen:
Mit gcc 5 können Sie dieselbe Warnung auch erhalten, ohne sie einzuschließen
iostream
.Wenn Sie also eine ähnliche Warnung sehen
dl-init.c
und gcc 5 verwenden, sollten Sie ein Upgrade auf eine neuere Version (gcc> = 6) in Betracht ziehen oder versuchen, mit clang zu kompilieren.quelle
total heap usage: 1 allocs, 1 frees, 72,704 bytes allocated
, damit ich keine Leckage (WSL1) bestätigen kann .