Valgrind shows memory leak with empty main without including headers

Lubuntu 15.10

I have a project with memory leaks. I can find them, so I cleaned up my main.cpp file and now it looks like this:

int main() { return 0; } 

When I check the memory with the command:

valgrind --leak-check=full --show-leak-kinds=all ./MyProgram > log1.txt 2>&1

I got these errors:

 ==5219== ==5219== LEAK SUMMARY: ==5219== definitely lost: 0 bytes in 0 blocks ==5219== indirectly lost: 0 bytes in 0 blocks ==5219== possibly lost: 728 bytes in 18 blocks ==5219== still reachable: 44,676 bytes in 224 blocks ==5219== of which reachable via heuristic: ==5219== newarray : 832 bytes in 16 blocks ==5219== suppressed: 0 bytes in 0 blocks ==5219== ==5219== For counts of detected and suppressed errors, rerun with: -v ==5219== ERROR SUMMARY: 18 errors from 18 contexts (suppressed: 0 from 0) 

Some of the errors were:

 ==5219== 2,048 bytes in 1 blocks are still reachable in loss record 240 of 242 ==5219== at 0x402E2EC: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==5219== by 0x5F7C151: g_realloc (in /lib/i386-linux-gnu/libglib-2.0.so.0.4600.2) ==5219== by 0x5F06BCB: g_value_register_transform_func (in /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4600.2) ==5219== by 0x5F08D6A: ??? (in /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4600.2) ==5219== by 0x5ED9A2D: ??? (in /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4600.2) ==5219== by 0x400EDCF: call_init.part.0 (dl-init.c:72) ==5219== by 0x400EEDF: call_init (dl-init.c:30) ==5219== by 0x400EEDF: _dl_init (dl-init.c:120) ==5219== by 0x4000ACE: ??? (in /lib/i386-linux-gnu/ld-2.21.so) ==5219== 8 bytes in 1 blocks are possibly lost in loss record 95 of 242 ==5219== at 0x402E0D8: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==5219== by 0x5F7C0DA: g_malloc0 (in /lib/i386-linux-gnu/libglib-2.0.so.0.4600.2) ==5219== by 0x5EFC587: ??? (in /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4600.2) ==5219== by 0x5F011B8: g_type_register_fundamental (in /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4600.2) ==5219== by 0x5EE929E: ??? (in /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4600.2) ==5219== by 0x5ED9A1E: ??? (in /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4600.2) ==5219== by 0x400EDCF: call_init.part.0 (dl-init.c:72) ==5219== by 0x400EEDF: call_init (dl-init.c:30) ==5219== by 0x400EEDF: _dl_init (dl-init.c:120) ==5219== by 0x4000ACE: ??? (in /lib/i386-linux-gnu/ld-2.21.so) 

Full log file: http://pastebin.com/DQxQtnzK

How do I solve this problem? What should I do?

+7
source share
1 answer

Leaks not from your code

Decryption of comments with minimal editing.

Add suppression; they are β€œleaks” caused by startup code that cannot be fixed by you and probably will not be fixed by the developers of the C ++ runtime. This is a widespread problem in Mac OS X. Typically, there are many allocations and several tens of kilobytes of memory that are allocated by the startup code. (Options include --gen-suppressions=all and --suppressions=suppressions-file .)

This gathered a comment:

FATAL: Cannot open prohibition file "suppressionions-file"

Which received the ripost (since I was under pressure from the time when I made the comment):

Read the manual. You use --gen-suppressions=all to generate suppressions [...]. Then edit the file (where you must provide an ID / name for each suppression record). You can then use the file in subsequent runs with --suppressions=name-you-created . You may need --show-leak-kinds=all , or maybe some others ( -leak-check=full , for example). Use valgrind --help , but keep in mind that the output is quite extensive.

A working example is Mac OS X 10.11.4

Source ( mincpp.cpp )

 int main() { return 0; } 

Compilation

 g++ -O3 -g -std=c++11 mincpp.cpp -o mincpp 

(I usually use many other warning options, but I really don't need to with this code.)

Initial start with valgrind

 $ valgrind mincpp ==69167== Memcheck, a memory error detector ==69167== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==69167== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info ==69167== Command: mincpp ==69167== --69167-- UNKNOWN fcntl 97! --69167-- UNKNOWN fcntl 97! (repeated 2 times) --69167-- UNKNOWN fcntl 97! (repeated 4 times) --69167-- UNKNOWN fcntl 97! (repeated 8 times) --69167-- UNKNOWN fcntl 97! (repeated 16 times) --69167-- UNKNOWN fcntl 97! (repeated 32 times) ==69167== ==69167== HEAP SUMMARY: ==69167== in use at exit: 22,195 bytes in 190 blocks ==69167== total heap usage: 255 allocs, 65 frees, 27,947 bytes allocated ==69167== ==69167== LEAK SUMMARY: ==69167== definitely lost: 4,120 bytes in 2 blocks ==69167== indirectly lost: 2,288 bytes in 6 blocks ==69167== possibly lost: 4,880 bytes in 45 blocks ==69167== still reachable: 2,344 bytes in 12 blocks ==69167== suppressed: 8,563 bytes in 125 blocks ==69167== Rerun with --leak-check=full to see details of leaked memory ==69167== ==69167== For counts of detected and suppressed errors, rerun with: -v ==69167== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) $ 

This is a big leak for such a minimal program!

Unknown fcntl messages are a nuisance, but seem to be "mostly harmless"; I probably need to rebuild valgrind again.

Generate Suppression

 $ valgrind --gen-suppressions=all --leak-check=full --show-leak-kinds=all mincpp ==69211== Memcheck, a memory error detector ==69211== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==69211== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info ==69211== Command: mincpp ==69211== --69211-- UNKNOWN fcntl 97! --69211-- UNKNOWN fcntl 97! (repeated 2 times) --69211-- UNKNOWN fcntl 97! (repeated 4 times) --69211-- UNKNOWN fcntl 97! (repeated 8 times) --69211-- UNKNOWN fcntl 97! (repeated 16 times) --69211-- UNKNOWN fcntl 97! (repeated 32 times) ==69211== ==69211== HEAP SUMMARY: ==69211== in use at exit: 22,195 bytes in 190 blocks ==69211== total heap usage: 255 allocs, 65 frees, 27,947 bytes allocated ==69211== ==69211== 24 bytes in 1 blocks are still reachable in loss record 5 of 62 ==69211== at 0x1000071FC: malloc_zone_malloc (vg_replace_malloc.c:304) ==69211== by 0x1005DC1E4: _read_images (in /usr/lib/libobjc.A.dylib) ==69211== by 0x1005E19EB: object_setClass (in /usr/lib/libobjc.A.dylib) ==69211== by 0x1005DABC7: gc_init (in /usr/lib/libobjc.A.dylib) ==69211== by 0x1005DA8C1: preopt_init (in /usr/lib/libobjc.A.dylib) ==69211== by 0x1005DA5CA: map_images_nolock (in /usr/lib/libobjc.A.dylib) ==69211== by 0x1005ECC6C: batchFinalizeOnTwoThreads(_malloc_zone_t*, void (*)(auto_zone_cursor*, void (*)(void*, void*), void*), auto_zone_cursor*, unsigned long) (in /usr/lib/libobjc.A.dylib) ==69211== by 0x7FFF5FC047CF: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld) ==69211== by 0x7FFF5FC04516: dyld::registerImageStateBatchChangeHandler(dyld_image_states, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld) ==69211== by 0x10023789D: dyld_register_image_state_change_handler (in /usr/lib/system/libdyld.dylib) ==69211== by 0x1005D907B: _objc_init (in /usr/lib/libobjc.A.dylib) ==69211== by 0x1001DFC93: _os_object_init (in /usr/lib/system/libdispatch.dylib) ==69211== { <insert_a_suppression_name_here> Memcheck:Leak match-leak-kinds: reachable fun:malloc_zone_malloc fun:_read_images fun:object_setClass fun:gc_init fun:preopt_init fun:map_images_nolock fun:_ZL25batchFinalizeOnTwoThreadsP14_malloc_zone_tPFvP16auto_zone_cursorPFvPvS3_ES3_ES2_m fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoE fun:_ZN4dyld36registerImageStateBatchChangeHandlerE17dyld_image_statesPFPKcS0_jPK15dyld_image_infoE fun:dyld_register_image_state_change_handler fun:_objc_init fun:_os_object_init } ==69211== 24 bytes in 1 blocks are still reachable in loss record 6 of 62 ==69211== at 0x1000071FC: malloc_zone_malloc (vg_replace_malloc.c:304) ==69211== by 0x1005DC1E4: _read_images (in /usr/lib/libobjc.A.dylib) ==69211== by 0x1005E19EB: object_setClass (in /usr/lib/libobjc.A.dylib) ==69211== by 0x1005DCC96: NXHashInsert (in /usr/lib/libobjc.A.dylib) ==69211== by 0x1005DB9B8: _read_images (in /usr/lib/libobjc.A.dylib) ==69211== by 0x1005DA5DA: map_images_nolock (in /usr/lib/libobjc.A.dylib) ==69211== by 0x1005ECC6C: batchFinalizeOnTwoThreads(_malloc_zone_t*, void (*)(auto_zone_cursor*, void (*)(void*, void*), void*), auto_zone_cursor*, unsigned long) (in /usr/lib/libobjc.A.dylib) ==69211== by 0x7FFF5FC047CF: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld) ==69211== by 0x7FFF5FC04516: dyld::registerImageStateBatchChangeHandler(dyld_image_states, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld) ==69211== by 0x10023789D: dyld_register_image_state_change_handler (in /usr/lib/system/libdyld.dylib) ==69211== by 0x1005D907B: _objc_init (in /usr/lib/libobjc.A.dylib) ==69211== by 0x1001DFC93: _os_object_init (in /usr/lib/system/libdispatch.dylib) ==69211== { <insert_a_suppression_name_here> Memcheck:Leak match-leak-kinds: reachable fun:malloc_zone_malloc fun:_read_images fun:object_setClass fun:NXHashInsert fun:_read_images fun:map_images_nolock fun:_ZL25batchFinalizeOnTwoThreadsP14_malloc_zone_tPFvP16auto_zone_cursorPFvPvS3_ES3_ES2_m fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoE fun:_ZN4dyld36registerImageStateBatchChangeHandlerE17dyld_image_statesPFPKcS0_jPK15dyld_image_infoE fun:dyld_register_image_state_change_handler fun:_objc_init fun:_os_object_init } … ==69211== LEAK SUMMARY: ==69211== definitely lost: 4,120 bytes in 2 blocks ==69211== indirectly lost: 2,288 bytes in 6 blocks ==69211== possibly lost: 4,880 bytes in 45 blocks ==69211== still reachable: 2,344 bytes in 12 blocks ==69211== suppressed: 8,563 bytes in 125 blocks ==69211== ==69211== For counts of detected and suppressed errors, rerun with: -v ==69211== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 12 from 12) $ 

Sometimes I add --num-callers=NN for a certain number of NN, but by default it seems to me that 12 on my assembly (I think it was less in earlier versions), which is adequate.

Generate suppressions in the min.suppressions file

 $ valgrind --gen-suppressions=all --leak-check=full --show-leak-kinds=all mincpp 2>./min.suppressions $ 

Edit min.suppressions

Delete lines starting with == and -- ; what remains are suppressions. Add names for suppressions. The end result is similar:

 { Mac-OSX-10.11.4-GCC-5.3.0-C++-Suppressions-001 Memcheck:Leak match-leak-kinds: reachable fun:malloc_zone_malloc fun:_read_images fun:object_setClass fun:gc_init fun:preopt_init fun:map_images_nolock fun:_ZL25batchFinalizeOnTwoThreadsP14_malloc_zone_tPFvP16auto_zone_cursorPFvPvS3_ES3_ES2_m fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoE fun:_ZN4dyld36registerImageStateBatchChangeHandlerE17dyld_image_statesPFPKcS0_jPK15dyld_image_infoE fun:dyld_register_image_state_change_handler fun:_objc_init fun:_os_object_init } { Mac-OSX-10.11.4-GCC-5.3.0-C++-Suppressions-002 Memcheck:Leak match-leak-kinds: reachable fun:malloc_zone_malloc fun:_read_images fun:object_setClass fun:NXHashInsert fun:_read_images fun:map_images_nolock fun:_ZL25batchFinalizeOnTwoThreadsP14_malloc_zone_tPFvP16auto_zone_cursorPFvPvS3_ES3_ES2_m fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoE fun:_ZN4dyld36registerImageStateBatchChangeHandlerE17dyld_image_statesPFPKcS0_jPK15dyld_image_infoE fun:dyld_register_image_state_change_handler fun:_objc_init fun:_os_object_init } … { Mac-OSX-10.11.4-GCC-5.3.0-C++-Suppressions-021 Memcheck:Leak match-leak-kinds: definite fun:malloc_zone_memalign fun:_ZL11addSubclassP10objc_classS0_ fun:_ZL12realizeClassP10objc_class fun:_ZL12realizeClassP10objc_class fun:_ZN4dyldL12notifySingleE17dyld_image_statesPK11ImageLoader fun:_ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE fun:_ZN11ImageLoader19processInitializersERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE fun:_ZN11ImageLoader19processInitializersERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE fun:_ZN11ImageLoader15runInitializersERKNS_11LinkContextERNS_21InitializerTimingListE fun:_ZN4dyld24initializeMainExecutableEv fun:_ZN4dyld5_mainEPK12macho_headermiPPKcS5_S5_Pm fun:_ZN13dyldbootstrap5startEPK12macho_headeriPPKclS2_Pm } 

Repeat with --suppressions=./min.suppressions

 $ valgrind --suppressions=./min.suppressions mincpp ==72028== Memcheck, a memory error detector ==72028== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==72028== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info ==72028== Command: mincpp ==72028== --72028-- UNKNOWN fcntl 97! --72028-- UNKNOWN fcntl 97! (repeated 2 times) --72028-- UNKNOWN fcntl 97! (repeated 4 times) --72028-- UNKNOWN fcntl 97! (repeated 8 times) --72028-- UNKNOWN fcntl 97! (repeated 16 times) --72028-- UNKNOWN fcntl 97! (repeated 32 times) ==72028== ==72028== HEAP SUMMARY: ==72028== in use at exit: 22,195 bytes in 190 blocks ==72028== total heap usage: 255 allocs, 65 frees, 27,947 bytes allocated ==72028== ==72028== LEAK SUMMARY: ==72028== definitely lost: 0 bytes in 0 blocks ==72028== indirectly lost: 0 bytes in 0 blocks ==72028== possibly lost: 0 bytes in 0 blocks ==72028== still reachable: 0 bytes in 0 blocks ==72028== suppressed: 22,195 bytes in 190 blocks ==72028== ==72028== For counts of detected and suppressed errors, rerun with: -v ==72028== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) $ 

This indicates that previously reported errors are now suppressed.

+8
source

All Articles