Valgrind: Der Speicher ist mit einem einfachen Programm mit <iostream> noch erreichbar

73

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 blocksgibt 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 valgrindAusgabe:

$ 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>.

sudo make install
quelle
1
Ubuntu 14.04, g ++ 4.8.2, Valgrind 3.10.0 und keine Lecks! Benötigt wahrscheinlich ein Valgrind-Upgrade.
Doqtor
Du bist mir an allen Fronten voraus! Ich frage mich, welches Update das Problem behoben hat. Leider kann ich Ubuntu momentan nicht aktualisieren.
Sudo Make Install
Sie sollten wahrscheinlich die vollständige Valgrind-Ausgabe einfügen. Stellen Sie außerdem sicher, dass Sie mit --leak-check = full und --track-origits = yes ausgeführt werden, um bessere Informationen zu erhalten
mjs
1
Der -fsanitize=leak
Leckdesinfektionsmittel
2
Hallo PyNewb, ich habe das gleiche Problem auf meinem Arch Linux System. Genau die gleiche Anzahl von Bytes in einem Block, sowohl für einen trivialen Testfall wie Ihre Show als auch für eine größere Anwendung, die kürzlich frei von Speicherverlusten war. Sehr neugierig!
bcumming

Antworten:

60

Es ist Valgrinds Schuld. Erstens -fsanitize=leakzeigt nichts. Zweitens stellt Valgrind selbst fest :

Zuallererst: Entspannen Sie sich, es ist wahrscheinlich kein Fehler, sondern eine Funktion. Viele Implementierungen der C ++ - Standardbibliotheken verwenden ihre eigenen Speicherpoolzuordnungen. Der Speicher für eine ganze Reihe von zerstörten Objekten wird nicht sofort freigegeben und an das Betriebssystem zurückgegeben, sondern zur späteren Wiederverwendung in den Pools aufbewahrt. Die Tatsache, dass die Pools beim Beenden des Programms nicht freigegeben werden, veranlasst Valgrind, diesen Speicher als noch erreichbar zu melden. Das Verhalten, Pools am Ausgang nicht freizugeben, könnte jedoch als Fehler der Bibliothek bezeichnet werden.

Mit GCC können Sie die STL zwingen, malloc zu verwenden und Speicher so schnell wie möglich freizugeben, indem Sie das Speicher-Caching global deaktivieren. In acht nehmen! Dies wird 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 ab Version 3.3 aus GCC entfernt.

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

Ab GCC 3.4 hat diese Variable ihren Namen in GLIBCXX_FORCE_NEW geändert.

[...]

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.

edmz
quelle
8

Betrachten Sie die folgende triviale Include-Datei:

#ifndef TRIVIAL_INCLUDE_FILE
#define TRIVIAL_INCLUDE_FILE
static int *x = new x (0);
#endif
David Schwartz
quelle
23
Leider wurde die Frage in dem von mir beantworteten Formular stark bearbeitet. Die ursprüngliche Frage lautete: " Ich möchte nur verstehen, wie das einfache Einfügen eines Standardbibliotheksheaders zu einer noch erreichbaren Warnung führen kann, wenn keines der Objekte aus dieser Bibliothek im Programm selbst zugewiesen wurde. " Der Beispielcode beantwortet diese Frage.
David Schwartz
1
Ah, das macht Sinn. Leider konnte ich genau das gleiche Problem ohne Überschriften reproduzieren.
bcumming
Was genau soll das tun? Kompilieren mit g ++ gibt mirerror: expected type-specifier before ‘x’
Yatharth Agarwal
6

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.cund gcc 5 verwenden, sollten Sie ein Upgrade auf eine neuere Version (gcc> = 6) in Betracht ziehen oder versuchen, mit clang zu kompilieren.

Philipp Claßen
quelle
Ich habe genau den gleichen Fehler wie oben mit libstdc ++. So.6.0.28, daher muss es möglicherweise neuer als 6 sein
JoeManiaci
Mit Valgrind-3.14.0.SVN und g ++ (Ubuntu 7.5.0-3ubuntu1 ~ 18.04) 7.5.0 habe ich bekommen total heap usage: 1 allocs, 1 frees, 72,704 bytes allocated, damit ich keine Leckage (WSL1) bestätigen kann .
Henke