EDIT: updated with some new info (Bold'ed). Also, the code and Valgrinds output is updated.
I recently started using SDL2 as my graphics library.
After developing some stuff, I decided to run Valgrind and found out that I am leaking memory... a lot of memory.
After narrowing it down I compiled this code (In C):
#include <SDL2/SDL.h>
int main(int argc, char** argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
SDL_Quit();
return 0;
}
This is the make file:
CC = gcc
CCFLAGS = -Wall -o0
LDFLAGS = -lSDL2
SOURCES= main.c
OBJECTS=$(SOURCES:.c=.o)
EXE = Test
.PHONY:
all: $(OBJECTS)
$(CC) $(OBJECTS) $(CCFLAGS) $(LDFLAGS) -o $(EXE)
clean:
rm $(OBJECTS) $(EXE)
And got this Valgrind error:
==30933== Memcheck, a memory error detector
==30933== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==30933== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==30933== Command: ./Test
==30933==
==30933==
==30933== HEAP SUMMARY:
==30933== in use at exit: 308,407 bytes in 559 blocks
==30933== total heap usage: 9,346 allocs, 8,787 frees, 2,502,489 bytes allocated
==30933==
==30933== LEAK SUMMARY:
==30933== definitely lost: 197,226 bytes in 6 blocks
==30933== indirectly lost: 6,272 bytes in 8 blocks
==30933== possibly lost: 0 bytes in 0 blocks
==30933== still reachable: 104,909 bytes in 545 blocks
==30933== suppressed: 0 bytes in 0 blocks
==30933== Rerun with --leak-check=full to see details of leaked memory
==30933==
==30933== For counts of detected and suppressed errors, rerun with: -v
==30933== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 1)
I looked around and saw many people complain about memory leaks in SDL, but they all were very small (about 16 bytes, not 200,000!).
Also, I checked other examples from the internet, trying to run them on my computer, and they all had that same leak (from what I'm assuming is SDL_Init).
I am running on Ubuntu13-64Bit.
Yes, there are some leaks in SDL, but it can come from different places and some of them aren't really SDL's fault.
For instance, my video card driver (nvidia) leaks a good 10Mb of memory. X11 is also known for some big leaks. I wouldn't worry that much, there are some things you can't control.
In your specific case, I would run valgrind with the flags --leak-check=full --track-origins=yes --show-reachable=yes, see if the leak is really coming from SDL and post a bug about it in http://bugzilla.libsdl.org if it isn't already reported.
Related
I'm having a memory error in my Qt-based application, I'm trying to use the Valgrind tool to detect the error but unfortunately when using Valgrind with my executable it runs and finishes without opening the GUI.
My command used is:
valgrind --track-origin=yes executable_path
The output is:
==4982== Memcheck, a memory error detector
==4982== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==4982== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==4982== Command: executable_path
==4982==
==4982== HEAP SUMMARY:
==4982== in use at exit: 2,661,594 bytes in 33,665 blocks
==4982== total heap usage: 36,967 allocs, 3,302 frees, 3,228,496 bytes allocated
==4982==
==4982== LEAK SUMMARY:
==4982== definitely lost: 0 bytes in 0 blocks
==4982== indirectly lost: 0 bytes in 0 blocks
==4982== possibly lost: 1,962,915 bytes in 27,027 blocks
==4982== still reachable: 698,679 bytes in 6,638 blocks
==4982== suppressed: 0 bytes in 0 blocks
==4982== Rerun with --leak-check=full to see details of leaked memory
==4982==
==4982== For counts of detected and suppressed errors, rerun with: -v
==4982== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 10 from 6)
My expectation is that this command will open the GUI and I'll do the steps for reproducing the issue then when I close the tool the report is written in the terminal, so what is wrong with the command that causes Valgrind to finish before even opening the tool.
I was toying around with Valgrind, when I noticed something weird:
my C++ program does nothing, yet there is 1 memory alloc and 1 free.
My simple program:
int main() {
return 0;
}
when compiled with g++ and checked with Valgrind
> g++ main.cpp
> valgrind --leak-check=full --track-origins=yes ./a.out
==40790== Memcheck, a memory error detector
==40790== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==40790== Using Valgrind-3.16.0.GIT and LibVEX; rerun with -h for copyright info
==40790== Command: ./a.out
==40790==
==40790==
==40790== HEAP SUMMARY:
==40790== in use at exit: 0 bytes in 0 blocks
==40790== total heap usage: 1 allocs, 1 frees, 72,704 bytes allocated
==40790==
==40790== All heap blocks were freed -- no leaks are possible
==40790==
==40790== For lists of detected and suppressed errors, rerun with: -s
==40790== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
My question: My program does nothing. Where does the alloc and free come from?
Interestingly enough, the same program compiled with gcc, shows zero allocs and frees:
> gcc main.c
> valgrind --leak-check=full --track-origins=yes ./a.out
==40740== Memcheck, a memory error detector
==40740== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==40740== Using Valgrind-3.16.0.GIT and LibVEX; rerun with -h for copyright info
==40740== Command: ./a.out
==40740==
==40740==
==40740== HEAP SUMMARY:
==40740== in use at exit: 0 bytes in 0 blocks
==40740== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==40740==
==40740== All heap blocks were freed -- no leaks are possible
==40740==
==40740== For lists of detected and suppressed errors, rerun with: -s
==40740== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Follow up question: Why do the two memory allocations differ, for the same piece of code?
compiler: gcc (GCC) 10.1.0
valgrind: valgrind-3.16.0.GIT
The main function is the entry point of your code. It doesn't have to be (and seldom is) the entry point to the process for the operating system that is loading your program.
There's usually plenty of code running first to set up things needed for the standard library (like setting up the standard I/O streams, and fetching the actual arguments from the operating system) before your main function is called.
And it's important to note that the main function is called like any other function. Once it returns it will return to the initialization code which will now clean up after itself (like freeing memory it might have allocated, and closing streams, etc.).
I'm investigating memory leak problems in a C++ application running on an embedded linux system (Yocto 1.5) with an ARM CPU.
Valgrind 3.8.1 is installed on the target.
The C++ program is compiled with gcc 4.8 with -g and -Og and is not stripped.
I've launched valgrind with the command below:
$ valgrind --tool=memcheck --leak-check=full /tmp/e3event-daemon -c /etc/e3event-daemon/config.json
Output of valgrind:
==7035== Memcheck, a memory error detector
==7035== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7035== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7035== Command: /tmp/e3event-daemon -c /etc/e3event-daemon/config.json
==7035==
==7035==
==7035== HEAP SUMMARY:
==7035== in use at exit: 4 bytes in 1 blocks
==7035== total heap usage: 421 allocs, 420 frees, 148,246 bytes allocated
==7035==
==7035== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7035== at 0x4834558: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-arm-linux.so)
==7035==
==7035== LEAK SUMMARY:
==7035== definitely lost: 4 bytes in 1 blocks
==7035== indirectly lost: 0 bytes in 0 blocks
==7035== possibly lost: 0 bytes in 0 blocks
==7035== still reachable: 0 bytes in 0 blocks
==7035== suppressed: 0 bytes in 0 blocks
==7035==
==7035== For counts of detected and suppressed errors, rerun with: -v
==7035== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
A memory leak is reported but a by 0x8048691: main (in ... line is missing. If I run the same program on my Ubuntu Linux machine (valgrind 3.10.1) I get this line which indicates where the problem is.
What should I do to get this by 0x8048691: main (in ... printed?
I have around 350 lines code where I am parsing xml file and creating another 2 sheets out of it using C++.
After adding the last 2 or 3 functions I started having memory error,
Signal: SIGSEGV (Segmentation fault)
Removing them didn't solve the error so definitely I edited something else. I searched online and found about valgrind which showed me errors that I can't translate.
As per the valgrind manual, I have to check from below to up so as per the last one,
==7276== 4,064 bytes in 1 blocks are definitely lost in loss record 52 of 54
==7276== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7276== by 0x456BDD: ??? (in /usr/bin/g++-5)
==7276== by 0x4EC260D: _obstack_begin (obstack.c:176)
==7276== by 0x456FCE: ??? (in /usr/bin/g++-5)
==7276== by 0x43BA49: ??? (in /usr/bin/g++-5)
==7276== by 0x43BAC0: ??? (in /usr/bin/g++-5)
==7276== by 0x4E5A82F: (below main) (libc-start.c:291)
For line 291 is the append line in the below code,
if (vlan_ether)
sprintf(cConfStr, "**.Switch%ld.eth[%d].queue.VlanClassifier = true\n", srcindex + 1, portno);
else if (!vlan_ether)
sprintf(cConfStr, "**.Switch%ld.eth[%d].queue.etherType = false\n", srcindex + 1, portno);
else
cout << "Switch" << srcindex + 1 << "port# " << portno << " Classifier is not specified." << endl;
confStr.append(string(cConfStr));
Removing the above lines didn't do any change, while line 176 is a comment so am hesitating that valgrind is not showing the lines of error.
So I am not sure what to show you in my question from the code. Still I am definite that it should be related to string and char usage In which I used them several times.
char cNedStr[600];
char cConfStr[600];
sprintf(cConfStr, "%d ", intervalvector[q]);
confStr.append(string(cConfStr));
The Valgrind result as per below,
amr#amr-PC:~$ valgrind --leak-check=yes g++ main.cpp pugixml.cpp headers.h -Wall -std=c++11
EDIT:
amr#amr-PC:~/ClionProjects/converter$ valgrind ./a.out
==7624== Memcheck, a memory error detector
==7624== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==7624== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==7624== Command: ./a.out
==7624== Invalid free() / delete / delete[] / realloc()
==7624== at 0x4C2F24B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7624== by 0x5714FF7: __run_exit_handlers (exit.c:82)
==7624== by 0x5715044: exit (exit.c:104)
==7624== by 0x56FB836: (below main) (libc-start.c:325)
==7624== Address 0x35663a37323a6536 is not stack'd, malloc'd or (recently) free'd
==7624==
==7624==
==7624== HEAP SUMMARY:
==7624== in use at exit: 72,704 bytes in 1 blocks
==7624== total heap usage: 525 allocs, 525 frees, 214,887 bytes allocated
==7624==
==7624== LEAK SUMMARY:
==7624== definitely lost: 0 bytes in 0 blocks
==7624== indirectly lost: 0 bytes in 0 blocks
==7624== possibly lost: 0 bytes in 0 blocks
==7624== still reachable: 72,704 bytes in 1 blocks
==7624== suppressed: 0 bytes in 0 blocks
==7624== Rerun with --leak-check=full to see details of leaked memory
==7624==
==7624== For counts of detected and suppressed errors, rerun with: -v
==7624== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
First compile, without the header file, (default output is a.out):
g++ main.cpp pugixml.cpp -Wall -std=c++11
Then check using valgrind:
valgrind --leak-check=yes ./a.out
Other comments:
You could consider adding the following flags to g++:
-Wextra (more warnings)
-pedantic (turns off extensions and generates more warnings)
-g (debug symbols)
-O3 (maximum optimization, not recommended for debugging!)
I have developed a pure-C implementation of FIFO lists (queues) in files fifo.h and fifo.c, and have written a test programme testfifo.c which I compile to ./bin/testfifo. The node structure is defined in list.h.
I run my programme through Valgrind on OS X 10.6 like this
valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./bin/testfifo
and get the following output
==54688== Memcheck, a memory error detector
==54688== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==54688== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==54688== Command: bin/testfifo
==54688==
--54688-- bin/testfifo:
--54688-- dSYM directory is missing; consider using --dsymutil=yes
==54688==
==54688== HEAP SUMMARY:
==54688== in use at exit: 88 bytes in 1 blocks
==54688== total heap usage: 11 allocs, 10 frees, 248 bytes allocated
==54688==
==54688== LEAK SUMMARY:
==54688== definitely lost: 0 bytes in 0 blocks
==54688== indirectly lost: 0 bytes in 0 blocks
==54688== possibly lost: 0 bytes in 0 blocks
==54688== still reachable: 0 bytes in 0 blocks
==54688== suppressed: 88 bytes in 1 blocks
==54688==
==54688== For counts of detected and suppressed errors, rerun with: -v
==54688== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
According to the leak summary, there are no leaks, but I am still wondering what the "suppressed" leaks are. Besides, the number of alloc's and free's do not match, and hence I am unsure if there are leaks or not.
----EDIT----
Running
valgrind --tool=memcheck --leak-check=full --show-reachable=yes -v ./bin/testfifo
on OS X 10.6 produces a quite long and confusing output, but I have run
valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./bin/testfifo
on a Linux machine an got this output:
==32688== Memcheck, a memory error detector
==32688== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==32688== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==32688== Command: bin/testfifo
==32688==
==32688==
==32688== HEAP SUMMARY:
==32688== in use at exit: 0 bytes in 0 blocks
==32688== total heap usage: 10 allocs, 10 frees, 160 bytes allocated
==32688==
==32688== All heap blocks were freed -- no leaks are possible
==32688==
==32688== For counts of detected and suppressed errors, rerun with: -v
==32688== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
alloc's and free's now match, so the extra alloc on OS X seems to be due to some system library, as has been suggested.
I have run the very same command with the -v option, in order to reveal the 4 suppressed errors, but I have not got any easily understandable new information.
Those are leaks outside of your code, in (probably shared) libraries or known false positives. Running valgrind with -v should inform you about the suppressions used.