Ikke's Blog

Post details: Small Valgrind introduction

Nov 19
Small Valgrind introduction

Everyone writing C or C++ code should know what a memory leak is. You allocate some memory, and never free it.
It can be very hard to make your code memleak free, or even just to know whether your code contains any memleaks.
Luckily, in the Free Software world, we got a great tool to check our code for memleaks (or other errors): Valgrind.

As I don't have time to write a lot now, I'll just give a very simple sample of it's usage.

Here's my code (very bad code, obviously, but hey ;-)):

#include <stdio.h>
#include <stdlib.h>

static void function() {
        char *test = (char *)malloc(100 * sizeof(char));
        test[0] = '\0';

        printf("Function\n");

        /* Leaking 100 chars here, 100 bytes */
}

int main(int argc, char *argv[]) {
        int *i = NULL;

        function();
        i = (int *)malloc(50 * sizeof(int));
        printf("Done\n");

        return 0;

        /* Leaking 50 ints here. On x86, this is 50*4=200 bytes */
}

As you can see, we leak memory twice: once 100 bytes, once 200.
Let's compile and run our code:

$ gcc -o test -Wall -g test.c
$ ./test
Function
Done

Great, our code works fine (or at least, it looks like it).

Now we introduce valgrind. First we'll do a simple memory allocation check:

$ valgrind --tool=memcheck ./test ==18819== Memcheck, a memory error detector for x86-linux.
==18819== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==18819== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==18819== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==18819== For more details, rerun with: -v
==18819==
Function
Done
==18819==
==18819== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
==18819== malloc/free: in use at exit: 300 bytes in 2 blocks.
==18819== malloc/free: 2 allocs, 0 frees, 300 bytes allocated.
==18819== For a detailed leak analysis,  rerun with: --leak-check=yes
==18819== For counts of detected errors, rerun with: -v

Valgrind tells us we leaked 300 bytes, in 2 blocks (one malloc call returns one block, obviously).
It also tells us to re-run the test with the --leak-check=yes flag, which is a good advice:

$ valgrind --tool=memcheck --leak-check=yes ./test
==18826== Memcheck, a memory error detector for x86-linux.
==18826== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==18826== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==18826== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==18826== For more details, rerun with: -v
==18826==
Function
Done
==18826==
==18826== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
==18826== malloc/free: in use at exit: 300 bytes in 2 blocks.
==18826== malloc/free: 2 allocs, 0 frees, 300 bytes allocated.
==18826== For counts of detected errors, rerun with: -v
==18826== searching for pointers to 2 not-freed blocks.
==18826== checked 1404368 bytes.
==18826==
==18826== 100 bytes in 1 blocks are definitely lost in loss record 1 of 2
==18826==    at 0x1B906B82: malloc (vg_replace_malloc.c:131)
==18826==    by 0x80483B5: function (test.c:5)
==18826==    by 0x80483F4: main (test.c:14)
==18826==
==18826==
==18826== 200 bytes in 1 blocks are definitely lost in loss record 2 of 2
==18826==    at 0x1B906B82: malloc (vg_replace_malloc.c:131)
==18826==    by 0x8048400: main (test.c:15)
==18826==
==18826== LEAK SUMMARY:
==18826==    definitely lost: 300 bytes in 2 blocks.
==18826==    possibly lost:   0 bytes in 0 blocks.
==18826==    still reachable: 0 bytes in 0 blocks.
==18826==         suppressed: 0 bytes in 0 blocks.
==18826== Reachable blocks (those to which a pointer was found) are not shown.
==18826== To see them, rerun with: --show-reachable=yes

Great, here Valgrind tells us exactly what we're doing wrong.
There are 2 blocks where we leak memory:

  • The first one is at code path
    main (test.c:14) -> function (test.c:5) -> malloc (vg_replace_malloc.c:131)
    leaking 100 bytes.
    The vg_replace_malloc.c file isn't ours, it's a valgrind file where the malloc() wrapper (which keeps track of our allocations/free's/...) is located. We're mostly interested in the "function (test.c:5)" part. If we look at line 5, we see this is

    char *test = (char *)malloc(100 * sizeof(char));
    our first allocation. And indeed, if we look further, we never free these 100 chars.
  • Second is at main (test.c:15). Again, we can look at this line:
    i = (int *)malloc(50 * sizeof(int));
    and indeed, we never free these allocated integers again. We allocated 50 ints, and on x86 one int is 32 bits (4 bytes), so we leak 200 bytes (and valgrind was correct once again :-)).

Obviously, valgrind got much more options or checks:

$ valgrind
valgrind: Missing --tool option
Available tools:
        memcheck
        addrcheck
        cachegrind
        corecheck
        helgrind
        massif
        lackey
        none
        callgrind
valgrind: Use --help for more information.

I don't know all of them, actually I only use the memcheck thing, but even when only using one tool, it can be a very useful program.

I got one minor issue with valgrind currently: when it detects memory leaks in some program, it still returns 0 in the end, so it's not easy to integrate valgrind checks in automake's "make check" target. If someone got any pointers how to do this, please let me know!

Comments:

Comment from: stephanie [Visitor] · http://gnurbs.blogsome.com
wee! cool cool! i did the same activity weeks ago .. thought i'd share you my experiment also ... :D http://gnurbs.blogsome.com/2005/11/04/im-just-a-kid/#comments

i also would like to thank you for your entry about glib's gmodule. it was soo enlightening! very educational!
PermalinkPermalink 11/20/05 @ 15:39
Comment from: stephanie [Visitor] · http://gnurbs.blogsome.com
btw, how come you cast malloc() ? it's ok not to cast as casting is implicitly done.
PermalinkPermalink 11/20/05 @ 15:41
Comment from: 石雕工艺 [Visitor] · http://www.hdscw.com
PermalinkPermalink 11/20/05 @ 15:42
Comment from: Ikke [Member] · http://www.eikke.com
Heh, you got almost the same article ;-)
Thanks for your friendly remars, it's always encouraging to read such things.

About casting malloc's return value: I always do it like this, as -Wall -Werror tends to break builds when you don't cast explicitly. I dislike implicit casts anyway (except "normal" ones like int-to-short etc).

Ikke
PermalinkPermalink 11/20/05 @ 16:04
Comment from: stephanie [Visitor] · http://gnurbs.blogsome.com
likewise dude! i've subscribe to your feed btw.. :D would like to read more about your adventures with programming. keep 'em coming coz i really like to your entries.

yet again, i've learned something new! -Wall-Werror and explicit casting. i'll experiment more about that next time i do a compile.

thanks again for the entry about gmodule. :D you are correct. gmodules are fun!
PermalinkPermalink 11/21/05 @ 00:11
Comment from: Eric Campbell [Visitor] · http://www.bbc.co.uk/
Great post! I'm looking forward for more. Play Opponents is very good Cards: http://www.cnn.com/WORLD/ , Opponents will Stake unconditionally right Girl will Forecast Plane without any questions , Black Pair Anticipate or not when Grass is Plane it will Hedge Chips
PermalinkPermalink 12/10/05 @ 21:16
Comment from: Alvis Koon [Visitor]
Good!

I am also doing Nokia 770 development.
How can I use this memory leak checker?

The debugging test run is usually:
run-standalone.sh ./app_name

How can we work around this wrapper shell script?
PermalinkPermalink 04/14/06 @ 03:20
Comment from: Ikke [Member] · http://www.eikke.com
I'm not sure, never used valgrind in the scratchbox environment... I guess first you should compile valgrind in the scratchbox environment, then modify that shellscript so it uses valgrind instead of directly starting $1...
PermalinkPermalink 04/14/06 @ 13:10
Comment from: Travis Ford [Visitor] · http://www.moviepoopshoot.com/
double cosmos is very good cards: http://www.serenitymovie.com/ when pair forecast mistery forecast , memorizing soldier becomes black circle in final
PermalinkPermalink 04/17/06 @ 07:05
Comment from: Travis Cole [Visitor] · http://www.ganonstower.com/movie.shtml
[url=http://www.transporter2movie.com/]when pair loose boy loose[/url] greedy tournament is always central plane tremendous, green, astonishing nothing comparative to full: http://www.dvdempire.com/Exec/v4_item.asp?userid=description%
PermalinkPermalink 04/17/06 @ 17:11
Comment from: Free Sprint Ringtone [Visitor] · http://free-ring-tones.awardspace.com
Thanks!
Want to share
free ringtone maker
Be free:
free verizon cell phone ringtone
All my friends wants also
free ringtone and wallpaper
Very unusual
free real music ringtone
Ask somebody
free jamster ringtone
PermalinkPermalink 06/11/06 @ 08:59
Comment from: fashion jewelry [Visitor] · http://fashionjewelry.world-of-love.ru
Watch - how to buy and be top level
watch jewelry
PermalinkPermalink 06/29/06 @ 10:42

This post has 1 feedback awaiting moderation...

Leave a comment:

Your email address will not be displayed on this site.
Your URL will be displayed.

Allowed XHTML tags: <p, ul, ol, li, dl, dt, dd, address, blockquote, ins, del, span, bdo, br, em, strong, dfn, code, samp, kdb, var, cite, abbr, acronym, q, sub, sup, tt, i, b, big, small>
(Line breaks become <br />)
(Set cookies for name, email and url)
(Allow users to contact you through a message form (your email will NOT be displayed.))

Categories

Who's Online?

  • Guest Users: 470

Misc

XML Feeds

What is RSS?