Valgrind: Memoria aún alcanzable con un progtwig trivial usando

Tome el siguiente progtwig trivial:

#include  int main() { return 0; } 

Si ejecuto esto usando valgrind, me dicen que hay 72,704 bytes in 1 blocks que still reachable se pueden 72,704 bytes in 1 blocks . Hubo extensas discusiones sobre SO sobre si preocuparse o no por las advertencias aún alcanzables, no me preocupa eso. Me gustaría simplemente comprender cómo la simple inclusión de un encabezado de biblioteca estándar podría causar una advertencia aún inalcanzable, cuando ninguno de los objetos de esa biblioteca se asignaron en el progtwig mismo.

Aquí está la salida completa de 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) 

Y un volcado de objetos:

 $ objdump -d ValgrindTest ValgrindTest: file format elf64-x86-64 Disassembly of section .init: 0000000000400718 : 400718: 48 83 ec 08 sub $0x8,%rsp 40071c: e8 8b 00 00 00 callq 4007ac  400721: 48 83 c4 08 add $0x8,%rsp 400725: c3 retq Disassembly of section .plt: 0000000000400730 : 400730: ff 35 ba 08 20 00 pushq 0x2008ba(%rip) # 600ff0  400736: ff 25 bc 08 20 00 jmpq *0x2008bc(%rip) # 600ff8  40073c: 0f 1f 40 00 nopl 0x0(%rax) 0000000000400740 : 400740: ff 25 ba 08 20 00 jmpq *0x2008ba(%rip) # 601000  400746: 68 00 00 00 00 pushq $0x0 40074b: e9 e0 ff ff ff jmpq 400730  0000000000400750 : 400750: ff 25 b2 08 20 00 jmpq *0x2008b2(%rip) # 601008  400756: 68 01 00 00 00 pushq $0x1 40075b: e9 d0 ff ff ff jmpq 400730  0000000000400760 : 400760: ff 25 aa 08 20 00 jmpq *0x2008aa(%rip) # 601010  400766: 68 02 00 00 00 pushq $0x2 40076b: e9 c0 ff ff ff jmpq 400730  0000000000400770 : 400770: ff 25 a2 08 20 00 jmpq *0x2008a2(%rip) # 601018  400776: 68 03 00 00 00 pushq $0x3 40077b: e9 b0 ff ff ff jmpq 400730  Disassembly of section .text: 0000000000400780 : 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  4007a9: f4 hlt 4007aa: 90 nop 4007ab: 90 nop 00000000004007ac : 4007ac: 48 83 ec 08 sub $0x8,%rsp 4007b0: 48 8b 05 29 08 20 00 mov 0x200829(%rip),%rax # 600fe0  4007b7: 48 85 c0 test %rax,%rax 4007ba: 74 02 je 4007be  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 : 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  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  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 : 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  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  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 : 400840: 80 3d e9 07 20 00 00 cmpb $0x0,0x2007e9(%rip) # 601030  400847: 75 11 jne 40085a  400849: 55 push %rbp 40084a: 48 89 e5 mov %rsp,%rbp 40084d: e8 7e ff ff ff callq 4007d0  400852: 5d pop %rbp 400853: c6 05 d6 07 20 00 01 movb $0x1,0x2007d6(%rip) # 601030  40085a: f3 c3 repz retq 40085c: 0f 1f 40 00 nopl 0x0(%rax) 0000000000400860 : 400860: 48 83 3d 80 05 20 00 cmpq $0x0,0x200580(%rip) # 600de8  400867: 00 400868: 74 1e je 400888  40086a: b8 00 00 00 00 mov $0x0,%eax 40086f: 48 85 c0 test %rax,%rax 400872: 74 14 je 400888  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  400885: 0f 1f 00 nopl (%rax) 400888: e9 73 ff ff ff jmpq 400800  40088d: 90 nop 40088e: 90 nop 40088f: 90 nop 0000000000400890 : 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 : 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  4008af: 81 7d f8 ff ff 00 00 cmpl $0xffff,-0x8(%rbp) 4008b6: 75 1e jne 4008d6  4008b8: bf 34 10 60 00 mov $0x601034,%edi 4008bd: e8 7e fe ff ff callq 400740  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  4008d6: c9 leaveq 4008d7: c3 retq 00000000004008d8 : 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  4008eb: 5d pop %rbp 4008ec: c3 retq 4008ed: 90 nop 4008ee: 90 nop 4008ef: 90 nop 00000000004008f0 : 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  400901: 4c 8d 25 c8 04 20 00 lea 0x2004c8(%rip),%r12 # 600dd0  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  400935: 48 85 ed test %rbp,%rbp 400938: 74 1c je 400956  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  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 : 400980: f3 c3 repz retq 400982: 90 nop 400983: 90 nop Disassembly of section .fini: 0000000000400984 : 400984: 48 83 ec 08 sub $0x8,%rsp 400988: 48 83 c4 08 add $0x8,%rsp 40098c: c3 retq 

Para completar, estoy usando:
Ubuntu: 12.04
Valgrind: 3.10.1 3.7.0
g ++: 4.8.1

NB: Como nota al margen, esto no ocurre cuando otros encabezados como o .

Es culpa de Valgrind. Primero, -fsanitize=leak no muestra nada. En segundo lugar, Valgrind declara que:

Antes que nada: relájate, probablemente no sea un error, sino una característica. Muchas implementaciones de las bibliotecas estándar de C ++ usan sus propios asignadores de grupo de memoria. La memoria de un buen número de objetos destruidos no se libera inmediatamente y se devuelve al sistema operativo, sino que se guarda en el (los) grupo (s) para su posterior reutilización. El hecho de que las agrupaciones no se liberen a la salida del progtwig hace que Valgrind informe que esta memoria todavía es alcanzable. Sin embargo, el comportamiento de no liberar pools en la salida podría llamarse un error de la biblioteca.

Usando GCC, puede forzar al STL a usar malloc y liberar memoria tan pronto como sea posible deshabilitando globalmente el almacenamiento en memoria caché. ¡Tener cuidado! Si lo hace, probablemente disminuirá la velocidad de su progtwig, a veces drásticamente.

Con GCC 2.91, 2.95, 3.0 y 3.1, compile todas las fonts usando STL con -D__USE_MALLOC. ¡Tener cuidado! Esto fue eliminado de GCC comenzando con la versión 3.3.

Con GCC 3.2.2 y posterior, debe exportar la variable de entorno GLIBCPP_FORCE_NEW antes de ejecutar su progtwig.

Con GCC 3.4 y posterior, esa variable ha cambiado de nombre a GLIBCXX_FORCE_NEW.

[…]

Supongo que esos supuestos pools de memoria se liberan después de la finalización del progtwig, en el llamado código de inicio que llama main , entre las otras configuraciones. Las funciones internas definidas fuera del código del usuario se deben tratar como si no existieran, es por eso que Valgrind no puede (y no debería) ver más liberadas.

Considere el siguiente archivo de inclusión trivial:

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

Para gcc 6 y superior, llegó una corrección de errores relacionada:

  • Informe de error: “Advertencia sobre la memoria” todavía alcanzable “cuando se utiliza libstdc ++ desde gcc 5”
  • Discusión sobre el rastreador de errores Arch Linux

Con gcc 5, también puede recibir la misma advertencia sin incluir iostream .

Entonces, si ve una advertencia similar refiriéndose a dl-init.c y está usando gcc 5, considere actualizar a una versión más nueva (gcc> = 6), o intente comstackr con clang.