2015-05-21 6 views
55

Nehmen Sie das folgende triviale Programm:Valgrind: Speicher noch erreichbar mit trivialen Programm <iostream>

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

Wenn ich dies mit valgrind laufen, bin ich gesagt, dass es 72,704 bytes in 1 blocks sind, die still reachable sind. Es gab umfangreiche Diskussionen über SO darüber, ob man sich über immer noch erreichbare Warnungen Sorgen machen soll oder nicht - ich mache mir darüber keine Sorgen. Ich möchte nur verstehen, wie einfach einschließlich ein Standard-Bibliothek-Header eine immer noch erreichbare Warnung verursachen konnte, wenn keines der Objekte aus dieser Bibliothek im Programm selbst zugeordnet wurde. Hier

ist die volle 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 <[email protected]>: 
    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 <[email protected]>: 
    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 <[email protected]>: 
    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 <[email protected]>: 
    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 <[email protected]>: 
    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 <[email protected]> 
    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 <[email protected]> 
    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 <[email protected]> 
    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 <cmath> einschließe.

+1

ubuntu 14.04, g ++ 4.8.2, valgrind 3.10.0 und keine Lecks! Wahrscheinlich benötigt Valgrind Upgrade. – doqtor

+0

Sie sind an allen Fronten vor mir! Ich frage mich, welches Update es behoben hat. Leider kann ich Ubuntu momentan nicht aktualisieren. –

+0

Sie sollten wahrscheinlich die volle Valgrind-Ausgabe einfügen. Stellen Sie außerdem sicher, dass Sie mit --leak-check = full und --track-origins = yes laufen, um bessere Informationen zu erhalten. – mjs

Antwort

42

Es ist Valgrind Schuld. Erstens zeigt -fsanitize=leak nichts. Zweitens, Valgrind selbst states das:

Zunächst einmal: entspannen, es ist wahrscheinlich kein Fehler, sondern eine Funktion. Viele Implementierungen der C++ - Standardbibliotheken verwenden ihren eigenen Speicher Pool-Allokatoren. Speicher für eine ganze Reihe von zerstörten Objekten wird nicht sofort freigegeben und an das Betriebssystem zurückgegeben, aber in den Pool (s) zur späteren Wiederverwendung gehalten. Die Tatsache, dass die Pools beim Beenden des Programms nicht freigegeben werden, bewirkt, dass Valgrind diesen Speicher als immer noch erreichbar meldet. Das Verhalten, Pools am Ausgang nicht freizugeben, könnte einen Fehler der Bibliothek genannt werden.

Mithilfe von GCC können Sie die STL zwingen, malloc zu verwenden und so bald wie möglich Speicher wie freizugeben, indem Sie Speicher-Caching global deaktivieren. In acht nehmen! Doing wird also wahrscheinlich Ihr Programm verlangsamen, manchmal drastisch.

Kompilieren Sie mit GCC 2.91, 2.95, 3.0 und 3.1 alle Quellen mithilfe der STL mit -D__USE_MALLOC. In acht nehmen! Dies wurde von GCC beginnend mit Version 3.3 entfernt.

Mit GCC 3.2.2 und höher sollten Sie die Umgebungsvariable GLIBCPP_FORCE_NEW exportieren, bevor Sie Ihr Programm ausführen.

Mit GCC 3.4 und höher hat diese Variable den Namen in GLIBCXX_FORCE_NEW geändert.

[...]]

Ich denke, diese Pools angeblichen Speicher nach Programm Kündigung, in dem so genannten Start-up-Code befreit werden, die main, unter den anderen Einstellungen aufruft. Interne Funktionen, die außerhalb des Benutzercodes definiert sind, sollten so behandelt werden, als ob sie nicht existieren würden. Aus diesem Grund kann (und sollte) Valgrind keine weiteren Freigaben sehen.

5

Betrachten Sie die folgende triviale Include-Datei:

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

Wie hilft das? – bcumming

+9

Leider wurde die Frage von der Form, die ich beantwortete, streng bearbeitet. Die ursprüngliche Frage war: "* Ich würde nur gerne verstehen, wie einfach das Hinzufügen eines Standardbibliotheksheaders zu einer immer noch erreichbaren Warnung führen kann, wenn keines der Objekte aus dieser Bibliothek im Programm selbst zugewiesen wurde. *" Der Beispielcode antwortet darauf Frage. –

+0

Ah, das macht Sinn. Leider konnte ich genau das gleiche Problem reproduzieren, ohne Header hinzuzufügen. – bcumming

3

Für gcc 6 und höher, ein verwandtes Bugfix angekommen:

Mit gcc 5, können Sie auch die gleiche Warnung iostream ohne einschließlich bekommen kann.

Wenn Sie eine ähnliche Warnung sehen, die sich auf dl-init.c bezieht und Sie gcc 5 verwenden, sollten Sie auf eine neuere Version (gcc> = 6) aktualisieren oder versuchen, mit clang zu kompilieren.

Verwandte Themen