5
votes

On OSX Valgrind reports this memory leak, Where is it coming from? The code is c compiled with g++ as c++ code (i do this for function overloading).

==13088== 18 bytes in 1 blocks are definitely lost in loss record 82 of 264
==13088==    at 0x1F25DC: malloc_zone_malloc (vg_replace_malloc.c:267)
==13088==    by 0xA1AEDA: malloc_set_zone_name (in /usr/lib/system/libsystem_c.dylib)
==13088==    by 0xA1B4A7: _malloc_initialize (in /usr/lib/system/libsystem_c.dylib)
==13088==    by 0xA1B5DD: malloc_good_size (in /usr/lib/system/libsystem_c.dylib)
==13088==    by 0x4EFA6E: __CFStringChangeSizeMultiple (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==13088==    by 0x4F3900: CFStringAppend (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==13088==    by 0x506F91: _convertToURLRepresentation (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==13088==    by 0x60F963: _CFURLInit (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==13088==    by 0x4FF268: CFURLCreateWithFileSystemPathRelativeToBase (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==13088==    by 0x4FF8EE: CFURLCreateWithFileSystemPath (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==13088==    by 0x515735: _CFBundleGetMainBundleAlreadyLocked (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==13088==    by 0x515663: CFBundleGetMainBundle (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==13088==    by 0x539533: cacheBundleInfo (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==13088==    by 0x5394B3: _CFAppVersionCheckLessThan (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==13088==    by 0x56C35B: __CFInitialize (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==13088==    by 0x8FE11243: ImageLoaderMachO::doImageInit(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==13088==    by 0x8FE10CB3: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==13088==    by 0x8FE0E21F: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==13088==    by 0x8FE0E1B5: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==13088==    by 0x8FE0F1BF: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==13088==    by 0x8FE03655: dyld::initializeMainExecutable() (in /usr/lib/dyld)
==13088==    by 0x8FE07EF1: dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**) (in /usr/lib/dyld)
==13088==    by 0x8FE012EE: dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*) (in /usr/lib/dyld)
==13088==    by 0x8FE01062: _dyld_start (in /usr/lib/dyld)
==13088==    by 0xFFF: ???

EDIT: also, how would I release this memory?

4
Also possibly relevant: mail-archive.com/[email protected]/…bames53
@bames53 difference is that this leak is in the 'definitely lost' category, not 'still reachable'chacham15
Yes - this is 'definitely lost' memory, and that is a big difference. But it is still outside your control; it is being allocated (and lost?) before your program gets properly started. I would add it as a suppression without qualms.Jonathan Leffler

4 Answers

5
votes

The allocation is completely out of your control; the free is likewise substantially impossible for you. This should be added to the list of known, detected, recorded but ignored items ('suppressed' is the jargon).

When I run a program under valgrind 3.7.0 on MacOS X 10.7.2, I get a summary like:

==71989== 
==71989== HEAP SUMMARY:
==71989==     in use at exit: 6,191 bytes in 33 blocks
==71989==   total heap usage: 33 allocs, 0 frees, 6,191 bytes allocated
==71989== 
==71989== LEAK SUMMARY:
==71989==    definitely lost: 0 bytes in 0 blocks
==71989==    indirectly lost: 0 bytes in 0 blocks
==71989==      possibly lost: 0 bytes in 0 blocks
==71989==    still reachable: 6,191 bytes in 33 blocks
==71989==         suppressed: 0 bytes in 0 blocks
==71989== Rerun with --leak-check=full to see details of leaked memory
==71989== 
==71989== For counts of detected and suppressed errors, rerun with: -v
==71989== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)

This is from a program that does no explicit memory allocation - printf() may trigger some allocation, but most of those bytes are allocated in system libraries. You've clearly got a deeper than normal value set for the traceback (--num-callers=N).

Look in the manual for how to add a suppression record properly, but valgrind --help offers:

--num-callers=<number>    show <number> callers in stack traces [12]
--error-limit=no|yes      stop showing new errors if too many? [yes]
--error-exitcode=<number> exit code to return if errors found [0=disable]
--show-below-main=no|yes  continue stack traces below main() [no]
--suppressions=<filename> suppress errors described in <filename>
--gen-suppressions=no|yes|all    print suppressions for errors? [no]

So, you could get valgrind to generate the suppression string for you to add to a file which you then use in subsequent runs.

Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc
0
votes

It looks more like it's in one of the libraries you're using, if so then make sure you're using the library's API properly, but also know that sometimes a library allocates global resources, when initialized for example, which it doesn't not free until the program exits.

For example, consider this situation:

void init_lib(){
    static char *buf=NULL;
    if (buf==NULL) {
       buf = malloc(18);
    }
    .....
}

How can the library free this buffer before exiting? it can't, until the program exits and its memory is reclaimed by the OS.

See Common pitfalls here

Edit: technically, in the above example, buf can be free'd as suggested by one of the comments below, but many libraries don't bother doing that because buf will be used for the duration of the program and the memory will be reclaimed when the program exits, so valgrind reports it as a memory leak.

0
votes

On OS X you need to run valgrind with --dsymutil=yes to get more useful information about leak location

0
votes

I am not sure which version of osx you are running. But on the version i am running valgrind reports those errors as ignorable.