Cairo and memory leaks fix with valgrind - c

In my program, even if do all the obvious housekeeping, such as calling cairo_destroy(), cairo_surface_destroy()..., valgrind always finds memory leaks, the leaks are in cairo dependencies (freetype, pixman, ...). How do I cleanup after cairo, so that valgrind won't detect any leaks, or are the leaks normal?
Sample output
==1861== HEAP SUMMARY:
==1861== in use at exit: 1,996,663 bytes in 532 blocks
==1861== total heap usage: 21,915 allocs, 21,383 frees, 95,411,698 bytes allocated
==1861==
==1861== LEAK SUMMARY:
==1861== definitely lost: 0 bytes in 0 blocks
==1861== indirectly lost: 0 bytes in 0 blocks
==1861== possibly lost: 0 bytes in 0 blocks
==1861== still reachable: 1,996,663 bytes in 532 blocks
==1861== suppressed: 0 bytes in 0 blocks
==1861== Reachable blocks (those to which a pointer was found) are not shown.
==1861== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1861==
==1861== For counts of detected and suppressed errors, rerun with: -v
==1861== Use --track-origins=yes to see where uninitialised values come from
==1861== ERROR SUMMARY: 1961 errors from 7 contexts (suppressed: 1 from 1)
UPDATE:
This question says, the "leaks" are normal, does there exist a way to do the cleanup, so valgrind becomes happy?

For cairo there is cairo_debug_reset_static_data().
While writing this as a comment, I was looking into pixman's source and the implementation of _pixman_choose_implementation() and apparently you cannot "clean up" pixman.
I have no clue about freetype.
Edit:
For fontconfig (related to freetype, so possibly interesting here), there is FcFini().

Related

valgrind not able find memory leak

I have encountered a weird issue. A process(written in c) is leaking memory but I am not able to locate why it is happening. Memory usage is increasing continuously when process handles traffic and at some point OS(linux) is killing it with error 'out of memory'.
I tried to debug this using valgrind with the following flags:
--show-reachable=yes --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --track-fds=yes --num-callers=20 --log-file=/tmp/valgrind-out.txt
Output file is as follows:
==5564== LEAK SUMMARY:
==5564== definitely lost: 0 bytes in 0 blocks
==5564== indirectly lost: 0 bytes in 0 blocks
==5564== possibly lost: 646,916 bytes in 1,156 blocks
==5564== still reachable: 4,742,112 bytes in 2,191 blocks
==5564== suppressed: 0 bytes in 0 blocks
Definitely lost is shown as 0 and there is no indication on where it is leaking. I have gone through still reachable segment, they all seem fine.
I wont be able to post code as it is a huge code with 100k+ lines. Basically what it does it sends some packets over tcp socket as a client. Sever is a simple python script which replies with response. My codes works as expected. This leak is the only trouble.
Any suggestion on debugging this issue?

Valgrind reporting memory definitely lost without errors

I am testing C code for memory leaks and can't seem to find the source of the leaks because there are 0 errors. Valgrind reports that there is a (quite significant) memory leak:
==30492== Memcheck, a memory error detector
==30492== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==30492== Using Valgrind-3.14.0.GIT and LibVEX; rerun with -h for copyright
info
==30492== Command: ./a.out --leak-check=full --track-origins=yes
==30492==
(This is where the input and output cases are displayed, which are a lot)
==30492==
==30492== HEAP SUMMARY:
==30492== in use at exit: 39,155 bytes in 167 blocks
==30492== total heap usage: 380 allocs, 213 frees, 53,426 bytes allocated
==30492==
==30492== LEAK SUMMARY:
==30492== definitely lost: 20,480 bytes in 2 blocks
==30492== indirectly lost: 2,064 bytes in 1 blocks
==30492== possibly lost: 0 bytes in 0 blocks
==30492== still reachable: 348 bytes in 9 blocks
==30492== suppressed: 16,263 bytes in 155 blocks
==30492== Rerun with --leak-check=full to see details of leaked memory
==30492==
==30492== For counts of detected and suppressed errors, rerun with: -v
==30492== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
The code is written in a few files and consists of hundreds of lines, so posting it here would probably be a bit much. Could anyone explain what could be the problem here? Or would you need to see the actual code to give an answer? I can find only little documentation on valgrind and am quite stuck here.
(valgrind suggests to rerun with --leak-check=full, but that is what I did to get this output)
It is possible to get false positives (e.g. in shared library initializers, or things like libcrypto.so which does leak some allocation).
However, you should always check - most likely you're forgetting some allocation.
In your output, we can see:
Command: ./a.out --leak-check=full --track-origins=yes`
This indicates you've invoked valgrind with:
valgrind ./a.out --leak-check=full --track-origins=yes
You should use this:
valgrind --leak-check=full --track-origins=yes ./a.out
If you find a leak (or other diagnostic) that you cannot control because it's internal to a third-party library, you can make a suppression file

c programming - difference between compiling in Ubuntu and compiling in Alpine - gcc - valgrind

I'm trying to understand some differences I've noticed when compiling a simple C program with gcc on Ubuntu (canonical ubuntu) and on Alpine (a docker container).
The program is the following:
int main(void)
{
printf("test\n");
return 0;
}
The command used to compile is the same for each terminal (Ubuntu and Alpine).
Valgrind detects no error on Ubuntu and 1 error on Alpine:
==311== Invalid free() / delete / delete[] / realloc()
==311== at 0x4C939EA: free (vg_replace_malloc.c:530)
==311== by 0x4057B69: ??? (in /lib/ld-musl-x86_64.so.1)
==311== Address 0x4e9b180 is in a rw- mapped file
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so segment
==311==
test
==311==
==311== HEAP SUMMARY:
==311== in use at exit: 404 bytes in 1 blocks
==311== total heap usage: 1 allocs, 1 frees, 404 bytes allocated
==311==
==311== LEAK SUMMARY:
==311== definitely lost: 0 bytes in 0 blocks
==311== indirectly lost: 0 bytes in 0 blocks
==311== possibly lost: 0 bytes in 0 blocks
==311== still reachable: 404 bytes in 1 blocks
==311== suppressed: 0 bytes in 0 blocks
==311== Rerun with --leak-check=full to see details of leaked memory
==311==
==311== For counts of detected and suppressed errors, rerun with: -v
==311== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
What is the explanation for that?
Valgrind calls special glibc functions to deallocate memory on process exit (while normally, glibc just lets the kernel do that). Musl likely doesn't have that because it is poor bloat.
Valgrind also has suppression files to deal with false positives or useless reports from system libraries. Some porting work is required to create them, and it looks like Alpine hasn't done that yet, or the files have become obsolete due to further musl development.
Sometimes, suppression files require debuginfo symbols, and valgrind couldn't find them in the run you quoted, so this is another thing to try.

How can I run valgrind with --leak-check=full in child processes?

I wrote a program that sometimes leaks in its child processes. To try to figure out why, I run
valgrind --leak-check=full --trace-children=yes ./shell
The --leak-check=full works correctly on the parent process, but it is explicitly not applied to any child processes. For example,
==14044== Memcheck, a memory error detector
==14044== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==14044== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==14044== Command: ./shell
==14044==
Shell by: user
(pid=14044)/home/user/user/shell$ invalid_command --flag-that-is-ignored
Command executed by pid=14044
invalid_command: not found
==14046==
==14046== HEAP SUMMARY:
==14046== in use at exit: 120 bytes in 1 blocks
==14046== total heap usage: 16 allocs, 15 frees, 552 bytes allocated
==14046==
==14046== LEAK SUMMARY:
==14046== definitely lost: 0 bytes in 0 blocks
==14046== indirectly lost: 0 bytes in 0 blocks
==14046== possibly lost: 0 bytes in 0 blocks
==14046== still reachable: 120 bytes in 1 blocks
==14046== suppressed: 0 bytes in 0 blocks
==14046== Reachable blocks (those to which a pointer was found) are not shown.
==14046== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==14046==
==14046== For counts of detected and suppressed errors, rerun with: -v
==14046== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
(pid=14044)/home/user/user/shell$ exit
==14044==
==14044== HEAP SUMMARY:
==14044== in use at exit: 0 bytes in 0 blocks
==14044== total heap usage: 26 allocs, 26 frees, 845 bytes allocated
==14044==
==14044== All heap blocks were freed -- no leaks are possible
==14044==
==14044== For counts of detected and suppressed errors, rerun with: -v
==14044== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
As you can see, when I call invalid_command from within my program, it correctly sees that invalid_command is not a command and prints an error accordingly. This child process then cleans up and exits, and valgrind prints out a leak summary. But the leak summary says rerun with: --leak-check=full despite the fact that I did run it with that flag!
When I exit the parent process, I have no memory leaks and it appears that --leak-check=full applied to the parent process correctly.
How can I make --leak-check=full apply to the child processes that I create? The program is written in C and I'm just using the normal fork(); exec(); wait(); paradigm.
The following combination of options solved my problem:
valgrind --leak-check=full --show-leak-kinds=all --trace-children=yes ./shell
If any of these are omitted, the output will be as shown above (it will not include line numbers).
I think you are looking for the --trace-children=yes option.

Valrind reports "still reachable" in empyt function

I'm using valgrind to check about the memory usage of my C application. After the first tests valgrind reports:
"still reachable: 2,248 bytes in 1 blocks".
I checked the code but I was not able to find the problem at mere sight. So I started to comment sections of the code to try to find the problem.
I was shocked when in my code I only have left
int main(void)
{
};
and STILL get the message, with the only difference in the amount of bytes.
I'm really puzzled with this...
Here is the complete messagge:
Running with options : valgrind --leak-check=full --show-reachable=yes
==2557== HEAP SUMMARY:
==2557== in use at exit: 2,248 bytes in 1 blocks
==2557== total heap usage: 362 allocs, 361 frees, 14,579 bytes allocated
==2557==
==2557== 2,248 bytes in 1 blocks are still reachable in loss record 1 of 1
==2557== at 0x4006171: calloc (vg_replace_malloc.c:593)
==2557== by 0x4D72250B: monstartup (in /usr/lib/libc-2.15.so)
==2557== by 0x8048650: __gmon_start__ (in /home/elias/Documents/SL_HTTP/Endosos/bin/Debug/Endosos)
==2557== by 0x4005421: ??? (in /usr/local/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==2557==
==2557== LEAK SUMMARY:
==2557== definitely lost: 0 bytes in 0 blocks
==2557== indirectly lost: 0 bytes in 0 blocks
==2557== possibly lost: 0 bytes in 0 blocks
==2557== still reachable: 2,248 bytes in 1 blocks
==2557== suppressed: 0 bytes in 0 blocks
==2557==
==2557== For counts of detected and suppressed errors, rerun with: -v
==2557== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Profiling timer expired
I'm compiling with gcc 4.7.2 in Fedrora 17
Any advice will be appreciated. Thanks.
This is perfectly fine and safe to ignore. In this case this is memory that seems to have been allocated by profiling (you're probably compiling code with profiling enabled or linking to some library that does).
Your environment will do a bunch of things to set up before calling main and those things can allocate memory. Since they know that this memory will be used until the program exits they don't bother to free it on exit because that just takes time for no benefit. Most of that memory will be reported as "still reachable" by valgrind and can be safely ignored.
Thanks to all.
You were right.
I'm using Code:Blocks 12.11 and by default it had enable -pg in the compiler settings.

Resources