I am currently reading and fallowing along the "Learn C The Hard Way"-book. On exercise 4 I have to install Valgrind. I first did this locally on my Macbook running Maverick, but I received a warning that Valgrind might not work 100%.
So now I tried it with Vagrant (using VirtualBox) with an Ubuntu 12.04 box. You can check out the exact Vagrantfile (setup) and the exercise files here on my github repo.
The problem:
I don't see the line numbers and instead I get something like 0x40052B.
I compiled the files by doing the fallowing:
$ make clean # Just to be sure
$ make
$ valgrind --track-origins=yes ./ex4
I pasted the result to pastebin here.
I found the fallowing 3 questions on SO that (partly) describes the same problem, but the answer's and there solutions didn't work for me:
Valgrind not showing line numbers in spite of -g flag (on Ubuntu 11.10/VirtualBox)
How do you get Valgrind to show line errors?
Valgrind does not show line-numbers
What I have tried sofar:
Added libc6-dbg
installed gcc and tried compiling with that instead of cc.
added --track-origins=yes to the valgrind-command
Added (and later removed) compiling with -static and -oO flags
So I am not sure where to go from here? I could try and install the latest (instead of v3.7) off gcc manually although that looked rather difficult.
edit:
#abligh answer seems to be right. I made this with kaleidoscope:
On the left side you see the result of: valgrind --track-origins=yes ./ex4 and on the right side the result of valgrind ./ex4.
I guess I still need to learn allot about c and it's tools.
I think you are just missing them in the output.
Here is some of your output (copied from Pastebin):
==16314== by 0x40052B: main (ex4.c:9)
^^--- LINE NUMBER
==16314== Uninitialised value was created by a stack allocation
==16314== at 0x4004F4: main (ex4.c:4)
^^--- LINE NUMBER
Though I think your invocation is wrong to check memory leaks. I wrote a very simple program to leak one item:
#include <stdio.h>
#include <stdlib.h>
int
main (int argc, char **argv)
{
void *leak;
leak = malloc (1);
printf ("Leaked %p\n", leak);
exit (0);
}
and compiled it using your Makefile:
gcc -Wall -g test.c -o test
Running your command:
$ valgrind --track-origins=yes ./test
==26506== Memcheck, a memory error detector
==26506== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==26506== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==26506== Command: ./test
==26506==
Leaked 0x51f2040
==26506==
==26506== HEAP SUMMARY:
==26506== in use at exit: 1 bytes in 1 blocks
==26506== total heap usage: 1 allocs, 0 frees, 1 bytes allocated
==26506==
==26506== LEAK SUMMARY:
==26506== definitely lost: 0 bytes in 0 blocks
==26506== indirectly lost: 0 bytes in 0 blocks
==26506== possibly lost: 0 bytes in 0 blocks
==26506== still reachable: 1 bytes in 1 blocks
==26506== suppressed: 0 bytes in 0 blocks
==26506== Rerun with --leak-check=full to see details of leaked memory
==26506==
==26506== For counts of detected and suppressed errors, rerun with: -v
==26506== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
But invoking the way I normally invoke it:
$ valgrind --leak-check=full --show-reachable=yes ./test
==26524== Memcheck, a memory error detector
==26524== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==26524== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==26524== Command: ./test
==26524==
Leaked 0x51f2040
==26524==
==26524== HEAP SUMMARY:
==26524== in use at exit: 1 bytes in 1 blocks
==26524== total heap usage: 1 allocs, 0 frees, 1 bytes allocated
==26524==
==26524== 1 bytes in 1 blocks are still reachable in loss record 1 of 1
==26524== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26524== by 0x40059C: main (test.c:8)
==26524==
==26524== LEAK SUMMARY:
==26524== definitely lost: 0 bytes in 0 blocks
==26524== indirectly lost: 0 bytes in 0 blocks
==26524== possibly lost: 0 bytes in 0 blocks
==26524== still reachable: 1 bytes in 1 blocks
==26524== suppressed: 0 bytes in 0 blocks
==26524==
==26524== For counts of detected and suppressed errors, rerun with: -v
==26524== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Note the line numbers are again in brackets, e.g.
==26524== by 0x40059C: main (test.c:8)
^^^^^^^^ <- FILENAME AND LINE NUMBER
Related
First, I have ran valgrind to make sure that (on the default settings) there are zero errors. Then, I decided to check for leaks with something like: --leak-check=full
I have code that looks something like char* variable=malloc(sizeof(char)*(strlen(in)+1)); and valgrind reports that memory is "definitely lost."
The only other line of code I have access to (this is in a library callback function) is the line of code where in is declared. This is a function argument of type void * (though in this case I'm hoping we can safely assume the value to be null terminated.)
Having
#include <stdlib.h>
char * G;
int main()
{
char * l = malloc(10);
G = malloc(20);
}
The execution under valgrind gives :
pi#raspberrypi:/tmp $ valgrind --leak-check=full ./a.out
==11087== Memcheck, a memory error detector
==11087== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11087== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==11087== Command: ./a.out
==11087==
==11087==
==11087== HEAP SUMMARY:
==11087== in use at exit: 30 bytes in 2 blocks
==11087== total heap usage: 2 allocs, 0 frees, 30 bytes allocated
==11087==
==11087== 10 bytes in 1 blocks are definitely lost in loss record 1 of 2
==11087== at 0x4847568: malloc (vg_replace_malloc.c:299)
==11087== by 0x10453: main (mm.c:7)
==11087==
==11087== LEAK SUMMARY:
==11087== definitely lost: 10 bytes in 1 blocks
==11087== indirectly lost: 0 bytes in 0 blocks
==11087== possibly lost: 0 bytes in 0 blocks
==11087== still reachable: 20 bytes in 1 blocks
==11087== suppressed: 0 bytes in 0 blocks
==11087== Reachable blocks (those to which a pointer was found) are not shown.
==11087== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==11087==
==11087== For counts of detected and suppressed errors, rerun with: -v
==11087== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 3)
The malloc(10) is definitely lost because there is no way to access it at the end of the execution (here out of main)
The malloc(20) is not lost because still reachable through G
I've got a problem using valgrind. In my project all structures are surrounded by #pragma pack(2) to reduce memory usage.
Now, allocating memory to a pointer within a structure leads to a valgrind error, e. g.: 14 bytes in 7 blocks are definitely lost in loss record 2 of 3.
EDIT: I was not precise enough. Sure, there is a memory leak as I never call free. But the problem is, that valgrind says the memory is definetly lost. This it not the case, since param_info is static.
So why does valgrind says definitely lost and not still reachable? If I remove the pragma directives the output is as expected.
Is this to be expected? And if so, can anybody please explain why?
Here is a minimal example to reproduce the error:
#include <stdlib.h>
#pragma pack(push)
#pragma pack(2)
struct param_ref
{
short *p;
short max_p;
};
#pragma pack(pop)
int main()
{
static struct param_ref *param_info = NULL;
static short param_max = 0;
int i;
if (param_info == NULL)
{
param_max = 10;
param_info = malloc(sizeof (struct param_ref) * param_max);
for (i = 0; i < param_max; i++)
{
param_info[i].p = malloc(sizeof (short));
param_info[i].max_p = 1;
}
}
return 0;
}
And the valgrind output:
xxx#homer:~/val$ valgrind --leak-check=full ./a.out
==4156== Memcheck, a memory error detector
==4156== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4156== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4156== Command: ./a.out
==4156==
==4156==
==4156== HEAP SUMMARY:
==4156== in use at exit: 120 bytes in 11 blocks
==4156== total heap usage: 11 allocs, 0 frees, 120 bytes allocated
==4156==
==4156== 14 bytes in 7 blocks are definitely lost in loss record 2 of 3
==4156== at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4156== by 0x4005AF: main (in /home/xxx/val/a.out)
==4156==
==4156== LEAK SUMMARY:
==4156== definitely lost: 14 bytes in 7 blocks
==4156== indirectly lost: 0 bytes in 0 blocks
==4156== possibly lost: 0 bytes in 0 blocks
==4156== still reachable: 106 bytes in 4 blocks
==4156== suppressed: 0 bytes in 0 blocks
==4156== Reachable blocks (those to which a pointer was found) are not shown.
==4156== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==4156==
==4156== For counts of detected and suppressed errors, rerun with: -v
==4156== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
EDIT2: Output of valgrind without pragma directives:
xxx#homer:~/val$ valgrind --leak-check=full ./a.out
==5374== Memcheck, a memory error detector
==5374== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5374== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==5374== Command: ./a.out
==5374==
==5374==
==5374== HEAP SUMMARY:
==5374== in use at exit: 180 bytes in 11 blocks
==5374== total heap usage: 11 allocs, 0 frees, 180 bytes allocated
==5374==
==5374== LEAK SUMMARY:
==5374== definitely lost: 0 bytes in 0 blocks
==5374== indirectly lost: 0 bytes in 0 blocks
==5374== possibly lost: 0 bytes in 0 blocks
==5374== still reachable: 180 bytes in 11 blocks
==5374== suppressed: 0 bytes in 0 blocks
==5374== Reachable blocks (those to which a pointer was found) are not shown.
==5374== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==5374==
==5374== For counts of detected and suppressed errors, rerun with: -v
==5374== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Some pointers to the memory are not properly aligned for valgrind to find them due to the packing hence valgrind reports them as definitely lost. It seems it has no option for this like LeakSanitizer:
LSAN_OPTIONS=use_unaligned=1
use_unaligned : If 0, LSan will only consider properly aligned 8-byte patterns when looking for pointers. Set to 1 to include unaligned patterns. This refers to the pointer itself, not the memory being pointed at.
$ gcc so.c -fsanitize=address -g
$ ./a.out
=================================================================
==4943==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 14 byte(s) in 7 object(s) allocated from:
#0 0x7fe18898ba0a in malloc (/lib64/libasan.so.2+0x98a0a)
#1 0x4008d2 in main /home/m/so.c:28
#2 0x7fe18855378f in __libc_start_main (/lib64/libc.so.6+0x2078f)
SUMMARY: AddressSanitizer: 14 byte(s) leaked in 7 allocation(s).
$ LSAN_OPTIONS=use_unaligned=1 ./a.out
$
Valgrind reports definitely lost memory if I exit main with return 0;, but reports still reachable memory if I exit main with exit(0);.
test-reachable.c:
#include <stdlib.h>
int main() {
void *data = malloc(256);
exit(0);
}
test-lost.c:
#include <stdlib.h>
int main() {
void *data = malloc(256);
return 0;
}
Behavior:
$ gcc test-reachable.c -o test-reachable
$ valgrind --leak-check=yes ./test-reachable
==7696== Memcheck, a memory error detector
==7696== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7696== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==7696== Command: ./test-reachable
==7696==
==7696==
==7696== HEAP SUMMARY:
==7696== in use at exit: 256 bytes in 1 blocks
==7696== total heap usage: 1 allocs, 0 frees, 256 bytes allocated
==7696==
==7696== LEAK SUMMARY:
==7696== definitely lost: 0 bytes in 0 blocks
==7696== indirectly lost: 0 bytes in 0 blocks
==7696== possibly lost: 0 bytes in 0 blocks
==7696== still reachable: 256 bytes in 1 blocks
==7696== suppressed: 0 bytes in 0 blocks
==7696== Reachable blocks (those to which a pointer was found) are not shown.
==7696== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==7696==
==7696== For counts of detected and suppressed errors, rerun with: -v
==7696== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ gcc test-lost.c -o test-lost
$ valgrind --leak-check=yes ./test-lost
==7774== Memcheck, a memory error detector
==7774== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7774== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==7774== Command: ./test-lost
==7774==
==7774==
==7774== HEAP SUMMARY:
==7774== in use at exit: 256 bytes in 1 blocks
==7774== total heap usage: 1 allocs, 0 frees, 256 bytes allocated
==7774==
==7774== 256 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7774== at 0x4C2C080: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7774== by 0x40051C: main (in /tmp/test-lost)
==7774==
==7774== LEAK SUMMARY:
==7774== definitely lost: 256 bytes in 1 blocks
==7774== indirectly lost: 0 bytes in 0 blocks
==7774== possibly lost: 0 bytes in 0 blocks
==7774== still reachable: 0 bytes in 0 blocks
==7774== suppressed: 0 bytes in 0 blocks
==7774==
==7774== For counts of detected and suppressed errors, rerun with: -v
==7774== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Shouldn't these behave the same?
Shouldn't these behave the same?
No.
In test-reachable.c the memory is referenced by the stack variable data at the time of the exit of the program, so it is still reachable, while in test-lost.c the memory is not referenced anymore because the main function has already returned, the reference does not exist anymore, the memory is definitely lost.
In C++ when return in main() is called then the destructors will be called for locally scoped objects whereas if exit() is called then no destructor will be called for locally scoped objects.
I think this is similar in C with regards to objects allocated on the stack.
That probably explains why in the return case non freed memory is treated as definitely lost and in the exit(0) case the memory is reported as still reachable.
Look something strange on my mac :
$> cat main.c
#include <stdio.h>
int main(int ac, char **av) {
for (int i = 0; i < ac; i++)
printf("%s\n", av[i]);
return 0;
}
$> gcc main.c -std=c99
$> valgrind ./a.out hello my friends
And here is the result :
==725== Memcheck, a memory error detector
==725== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==725== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==725== Command: ./a.out hello my friends
==725==
--725-- ./a.out:
--725-- dSYM directory is missing; consider using --dsymutil=yes
./a.out
hello
my
friends
==725==
==725== HEAP SUMMARY:
==725== in use at exit: 6,146 bytes in 33 blocks
==725== total heap usage: 33 allocs, 0 frees, 6,146 bytes allocated
==725==
==725== LEAK SUMMARY:
==725== definitely lost: 0 bytes in 0 blocks
==725== indirectly lost: 0 bytes in 0 blocks
==725== possibly lost: 0 bytes in 0 blocks
==725== still reachable: 6,146 bytes in 33 blocks
==725== suppressed: 0 bytes in 0 blocks
==725== Rerun with --leak-check=full to see details of leaked memory
==725==
==725== For counts of detected and suppressed errors, rerun with: -v
==725== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
If someone knows why, and could explain me where does theses leaks come from, I'd be thankful !!
Have a good day :-)
These aren't leaks. Objects listed as still reachable shouldn't trouble you. If you'd have a non-zero value in the rows above then it should ring an alarm bell though!
Those 33 blocks listed as still reachable are most probably some blocks allocated inside printf calls by your standard library. Nothing to be worried about.
Consider also taking a look at this answer to a similar question.
"still reachable" when a program has terminated is really nothing to worry about.
"still reachable" means that there are allocated memory which hasn't been released, but there are still pointers pointing towards this memory. Therefor valgrind doesn't flag it as a true memory "leak".
It's often a waste of time to spend time free:ing the allocated memory before a application ends, the allocated memory will be returned to the OS anyhow since the application is terminating.
Yesterday i posted this: What's the problem with this code? [hashtable in C] and paxdiablo offered to help me. He posted a sample of code and asked me to run it through valgrind on my machine. This code normally generates: 12,4 But on my machine, i get 24,8. The doubled! I'm just curious why is that happening. Hope sb has a good explaination.
I post also paxdiablo's code (for anyone who cant find it.)
#include <stdio.h>
#include <stdlib.h>
typedef struct HashTable {
int size ;
struct List *head;
struct List *tail;
} HashTable;
typedef struct List {
char *number;
char *name;
int time;
struct List *next;
} List;
#define size_of_table 211
HashTable *createHashTable(void) {
HashTable *new_table = malloc(sizeof(*new_table)*size_of_table); //line 606
printf ("%d\n", sizeof(*new_table));
printf ("%d\n", sizeof(new_table));
if (new_table == NULL) {
return NULL;
}
int i=0;
for(i; i<size_of_table; i++) {
new_table[i].size=0;
new_table[i].head=NULL;
new_table[i].tail=NULL;
}
return new_table;
}
int main(void) {
HashTable *x = createHashTable();
free (x);
return 0;
}
Well pointers on your environment are 8 bytes wide, and your ints are also 8 bytes wide by the looks of it. Judging by the error when trying to use -m32 with gcc, I'd hazard a guess that you have the x86_64
version of glibc-devel installed and need to additionally install the x86 (32-bit) version.
Could you post the output from ldd <your_compiled_program>, too?
Let us know if this is (not) the case.
You are likely building on a 64-bit platform. 8 byte pointers. If you build it with -m32 it will build as a 32-bit application.
Running your code, I get 24,8 under a 64-bit build and 12,4 under a 32-bit build: MacOS X 10.6.6 (Intel Core 2 Duo), GCC 4.5.2, Valgrind 3.6.0.
32-bit
$ gcc -m32 -g -o vg vg.c
$ valgrind vg
==69827== Memcheck, a memory error detector
==69827== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==69827== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==69827== Command: vg
==69827==
12
4
==69827==
==69827== HEAP SUMMARY:
==69827== in use at exit: 4,416 bytes in 8 blocks
==69827== total heap usage: 9 allocs, 1 frees, 6,948 bytes allocated
==69827==
==69827== LEAK SUMMARY:
==69827== definitely lost: 0 bytes in 0 blocks
==69827== indirectly lost: 0 bytes in 0 blocks
==69827== possibly lost: 0 bytes in 0 blocks
==69827== still reachable: 4,416 bytes in 8 blocks
==69827== suppressed: 0 bytes in 0 blocks
==69827== Rerun with --leak-check=full to see details of leaked memory
==69827==
==69827== For counts of detected and suppressed errors, rerun with: -v
==69827== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$
64-bit
$ gcc -m64 -g -o vg vg.c
$ valgrind vg
==69840== Memcheck, a memory error detector
==69840== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==69840== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==69840== Command: vg
==69840==
24
8
==69840==
==69840== HEAP SUMMARY:
==69840== in use at exit: 4,184 bytes in 2 blocks
==69840== total heap usage: 3 allocs, 1 frees, 9,248 bytes allocated
==69840==
==69840== LEAK SUMMARY:
==69840== definitely lost: 0 bytes in 0 blocks
==69840== indirectly lost: 0 bytes in 0 blocks
==69840== possibly lost: 0 bytes in 0 blocks
==69840== still reachable: 4,184 bytes in 2 blocks
==69840== suppressed: 0 bytes in 0 blocks
==69840== Rerun with --leak-check=full to see details of leaked memory
==69840==
==69840== For counts of detected and suppressed errors, rerun with: -v
==69840== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$
Of course, valgrind is a red herring; the same results are printed with less verbosity around them without valgrind.