{"id":983,"date":"2013-02-21T00:00:00","date_gmt":"2013-02-21T00:00:00","guid":{"rendered":"https:\/\/www.fussylogic.co.uk\/blog\/?p=983"},"modified":"2013-02-21T20:11:59","modified_gmt":"2013-02-21T20:11:59","slug":"valgrind-i-memcheck","status":"publish","type":"post","link":"https:\/\/www.fussylogic.co.uk\/blog\/?p=983","title":{"rendered":"Valgrind I &#8212; memcheck"},"content":{"rendered":"<p>In this series I\u00e2\u20ac\u2122m going to give you a quick tour of the <code>valgrind<\/code> tool suite. <code>valgrind<\/code> is useful for finding those hard-to-find, serious-repercussion bugs that can sneak into your code.<\/p>\n<p>Consider this C++ program:<\/p>\n<pre><code>\/\/ C++\n#include &lt;iostream&gt;\n\/\/ C\n#include &lt;stdlib.h&gt;\n\/\/ OS\n#include &lt;sys\/types.h&gt;\n#include &lt;sys\/stat.h&gt;\n#include &lt;fcntl.h&gt;\n#include &lt;unistd.h&gt;\n\nusing namespace std;\n\nint main(void)\n{\n    cerr &lt;&lt; &quot;Leaking a file descriptor&quot; &lt;&lt; endl;\n    int fd = open(&quot;\/dev\/null&quot;, O_RDONLY);\n    \/\/ missing close()\n    fd = -1;\n\n    cerr &lt;&lt; &quot;Leaking some memory&quot; &lt;&lt; endl;\n    char *b = new char[1024];\n    \/\/ missing delete[]\n    b = NULL;\n\n    cerr &lt;&lt; &quot;Performing invalid access (out of bounds)&quot; &lt;&lt; endl;\n    char *c = new char[10];\n    \/\/ c is only 10 bytes long, so we shouldn&#39;t access the eleventh\n    c[10] = &#39;\\xff&#39;;\n    delete[] c;\n\n    cerr &lt;&lt; &quot;Performing invalid access (deleted memory)&quot; &lt;&lt; endl;\n    char *d = new char[10];\n    delete[] d;\n    d[0] = &#39;\\xff&#39;;\n\n    \/\/ Use of uninitialised value (the compiler will catch\n    \/\/ automatic variable misuse, valgrind catches heap-allocated misuse\n    int *x = new int;\n    if( *x == 10 )\n        *x = 1;\n    cerr &lt;&lt; &quot;x = &quot; &lt;&lt; x &lt;&lt; endl;\n\n\n    \/\/ If we were being really pedantic...\n    close(0);\n    close(1);\n    close(2);\n\n    return 0;\n}\n\n\/\/ Command lines for compile:\n\/\/  $ g++ -ggdb3 -O2 -Wall -rdynamic -Wextra -c -o memleaker.o memleaker.cc\n\/\/  $ g++ -pthread -o memleaker memleaker.o<\/code><\/pre>\n<p>The faults in the above should be pretty obvious (especially as I\u00e2\u20ac\u2122ve commented them). However, those faults are invisible at compile time, and fairly well hidden at runtime. They are perfectly capable of crashing your application though, at some arbitrary and unexpected time. You should strive to write good code, but nobody is perfect. <code>valgrind<\/code> is an excellent tool for rooting out these sorts of faults. Here\u00e2\u20ac\u2122s a sample run on the above program.<\/p>\n<p>First the run:<\/p>\n<pre><code>valgrind --tool=memcheck \\\n                --undef-value-errors=no \\\n                --num-callers=40 \\\n                --track-fds=yes \\\n                --leak-check=full \\\n                --show-reachable=yes \\\n                --log-file=vg-memleaker.log \\\n                .\/memleaker\nLeaking a file descriptor\nLeaking some memory\nPerforming invalid access (out of bounds)\nPerforming invalid access (deleted memory)\nx = 0x43014d8<\/code><\/pre>\n<p>The program is now complete; but <code>valgrind<\/code> has produced a useful log.<\/p>\n<pre><code>less vg-memleaker.log\n==22369== Memcheck, a memory error detector\n==22369== Copyright (C) 2002-2012, and GNU GPL&#39;d, by Julian Seward et al.\n==22369== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info\n==22369== Command: .\/memleaker\n==22369== Parent PID: 22368\n==22369== \n==22369== Invalid write of size 1\n==22369==    at 0x804881A: main (memleaker.cc:28)\n==22369==  Address 0x4301462 is 0 bytes after a block of size 10 alloc&#39;d\n==22369==    at 0x4027C34: operator new[](unsigned int) (vg_replace_malloc.c:357)\n==22369==    by 0x8048819: main (memleaker.cc:26)\n==22369== <\/code><\/pre>\n<p>This is <code>c[10] = '0xff';<\/code>, where the array is only 10 bytes long and we\u00e2\u20ac\u2122ve forgotten that index 10 of a zero-indexed array is actually the eleventh byte and so is accessing unallocated memory.<\/p>\n<pre><code>==22369== Invalid write of size 1\n==22369==    at 0x804885C: main (memleaker.cc:34)\n==22369==  Address 0x4301498 is 0 bytes inside a block of size 10 free&#39;d\n==22369==    at 0x4026C3C: operator delete[](void*) (vg_replace_malloc.c:515)\n==22369==    by 0x804885B: main (memleaker.cc:33)\n==22369== \n==22369== <\/code><\/pre>\n<p><code>d[0] = '\\xff';<\/code> isn\u00e2\u20ac\u2122t allowed when we\u00e2\u20ac\u2122ve deleted the memory that <code>d<\/code> points at.<\/p>\n<pre><code>==22369== FILE DESCRIPTORS: 2 open at exit.\n==22369== Open file descriptor 4: \/dev\/null\n==22369==    at 0x418FB73: __open_nocancel (syscall-template.S:82)\n==22369==    by 0x41B1E45: (below main) (libc-start.c:228)\n==22369== <\/code><\/pre>\n<p>Oops; forgot to close a descriptor. File descriptor leaks can eventually bring your application to a halt, since your OS will limit the number of descriptors any one process may open (<code>ulimit -n<\/code> shows 1024 on my system). When you hit that limit (even if you\u00e2\u20ac\u2122re no longer using the descriptors) every subsequent <code>open()<\/code> or <code>connect()<\/code> will fail.<\/p>\n<pre><code>==22369== Open file descriptor 3: \/home\/andyp\/dev\/projects\/valgrind\/vg-memleaker.log\n==22369==    &lt;inherited from parent&gt;\n==22369== \n==22369== <\/code><\/pre>\n<p>We can ignore this one. This is <code>valgrind<\/code>\u00e2\u20ac\u2122s log file, so won\u00e2\u20ac\u2122t be open in a real run of our system.<\/p>\n<pre><code>==22369== HEAP SUMMARY:\n==22369==     in use at exit: 1,028 bytes in 2 blocks\n==22369==   total heap usage: 4 allocs, 2 frees, 1,048 bytes allocated\n==22369== \n==22369== 4 bytes in 1 blocks are definitely lost in loss record 1 of 2\n==22369==    at 0x4028354: operator new(unsigned int) (vg_replace_malloc.c:292)\n==22369==    by 0x804886A: main (memleaker.cc:38)\n==22369== \n==22369== 1,024 bytes in 1 blocks are definitely lost in loss record 2 of 2\n==22369==    at 0x4027C34: operator new[](unsigned int) (vg_replace_malloc.c:357)\n==22369==    by 0x80487F1: main (memleaker.cc:21)\n==22369== <\/code><\/pre>\n<p><code>new<\/code> without a matching <code>delete<\/code> means a memory leak. These too will eventually exhaust either available virtual memory space (2GB on a 32-bit system) or all swap space, in the meantime bringing your server to its knees as it constantly swaps for every single memory use.<\/p>\n<pre><code>==22369== LEAK SUMMARY:\n==22369==    definitely lost: 1,028 bytes in 2 blocks\n==22369==    indirectly lost: 0 bytes in 0 blocks\n==22369==      possibly lost: 0 bytes in 0 blocks\n==22369==    still reachable: 0 bytes in 0 blocks\n==22369==         suppressed: 0 bytes in 0 blocks\n==22369== \n==22369== For counts of detected and suppressed errors, rerun with: -v\n==22369== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)<\/code><\/pre>\n<p><code>valgrind<\/code> further analyses the types of loss. For example, \u00e2\u20ac\u0153definitely lost\u00e2\u20ac\u009d is memory to which there is no longer a pointer; \u00e2\u20ac\u0153indirectly lost\u00e2\u20ac\u009d is memory to which there is a pointer, but the pointer is part of another block which is itself definitely lost. See the <a href=\"http:\/\/valgrind.org\/docs\/manual\/faq.html#faq.deflost\">docs<\/a> for more.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this series I\u00e2\u20ac\u2122m going to give you a quick tour of the valgrind tool suite. valgrind is useful for finding those hard-to-find, serious-repercussion bugs that can sneak into your code. Consider this C++ program: \/\/ C++ #include &lt;iostream&gt; \/\/ C #include &lt;stdlib.h&gt; \/\/ OS #include &lt;sys\/types.h&gt; #include &lt;sys\/stat.h&gt; #include &lt;fcntl.h&gt; #include &lt;unistd.h&gt; using namespace\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.fussylogic.co.uk\/blog\/?p=983\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[65,66,42,6,64],"_links":{"self":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/983"}],"collection":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=983"}],"version-history":[{"count":4,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/983\/revisions"}],"predecessor-version":[{"id":989,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/983\/revisions\/989"}],"wp:attachment":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=983"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=983"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=983"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}