We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2591 - Memory leaks
Summary: Memory leaks
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: *don't know* (show other bugs)
Version: 2.0.3
Hardware: x86_64 Linux
: P2 normal
Assignee: Ryan C. Gordon
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-06-17 22:49 UTC by lectem
Modified: 2014-07-07 17:28 UTC (History)
1 user (show)

See Also:


Attachments
Fix DBus related memory leak. (1.69 KB, patch)
2014-07-06 21:19 UTC, Alex Baines
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description lectem 2014-06-17 22:49:48 UTC
Hi,
I just ran my game through valgrind to see if it had memory leaks, and there were a lot.
But those memory leaks are due to SDL_Init, I tried on an empty project, see the code below :

int main ( int argc, char* argv[] )
{
    SDL_Init( SDL_INIT_VIDEO );
    SDL_Quit();
    return 0;
}


Valgrind shows me this output :

==3956== HEAP SUMMARY:
==3956==     in use at exit: 61,096 bytes in 446 blocks
==3956==   total heap usage: 8,263 allocs, 7,817 frees, 11,536,031 bytes allocated

Would it be possible to fix it? It's hard to spot my own errors if the SDL itself doesn't free everything.
Thanks

PS:I'm not sure if it's important but I'm running Backtrack with Nvidia latest drivers, and the SDL2 compiled correctly.
Comment 1 Ryan C. Gordon 2014-06-18 03:31:14 UTC
You can run valgrind with --leak-check=full and --show-leak-kinds=all to get a real flood of data about where leaks happened.

Doing this on your test program shows that most of these happen in:

- dlopen()  (apparently glibc leaks some memory?)
- XOpenIM (Xlib)
- Some stuff from Nvidia's OpenGL driver
- D-Bus functions

Note that most of this is "still reachable" and not "definitely lost"...which is to say that there's still (what could be) a valid pointer to the allocated block somewhere in memory. In some cases (probably dlopen is doing this), the code is intentionally keeping a cache of some sort around, with the intention of it living until the process terminates. This isn't really a "leak" in that it's intentional behavior.

The D-Bus ones _might_ be something we're doing wrong, but I'd have to research more. At any rate, most of these are either intentionally not freed, or at least out of our control in external libraries.

The only one that might be ours is this...

==18003== 88 bytes in 1 blocks are still reachable in loss record 52 of 95
==18003==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18003==    by 0x4C2CF1F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18003==    by 0x4EEFE68: SDL_realloc_REAL (SDL_malloc.c:41)
==18003==    by 0x4EF1008: SDL_TLSSet_REAL (SDL_thread.c:66)
==18003==    by 0x4EF1426: SDL_GetErrBuf (SDL_thread.c:241)
==18003==    by 0x4E4C321: SDL_ClearError_REAL (SDL_error.c:216)
==18003==    by 0x4E4AD72: SDL_InitSubSystem_REAL (SDL.c:116)
==18003==    by 0x4E4AF3A: SDL_Init_REAL (SDL.c:244)
==18003==    by 0x4E90234: SDL_Init_DEFAULT (SDL_dynapi_procs.h:89)
==18003==    by 0x4E95D3D: SDL_Init (SDL_dynapi_procs.h:89)
==18003==    by 0x400715: main (test.c:528)

...but that might be that the TLS slot array is meant to live past SDL_Quit().

--ryan.
Comment 2 Alex Baines 2014-07-06 17:03:25 UTC
(In reply to Ryan C. Gordon from comment #1)
> The D-Bus ones _might_ be something we're doing wrong, but I'd have to
> research more. At any rate, most of these are either intentionally not
> freed, or at least out of our control in external libraries.

I'm taking a look at the SDL D-Bus code now, since I wrote a lot of it, but I can't see any obvious places that memory is leaking; the messages are all being unref'd correctly as far as I can tell.

I'll keep investigating but the problem may well be internal to the D-Bus library.
Comment 3 Alex Baines 2014-07-06 21:01:13 UTC
(In reply to Alex Baines from comment #2)
> (In reply to Ryan C. Gordon from comment #1)
> > The D-Bus ones _might_ be something we're doing wrong, but I'd have to
> > research more. At any rate, most of these are either intentionally not
> > freed, or at least out of our control in external libraries.
> 
> I'm taking a look at the SDL D-Bus code now, since I wrote a lot of it, but
> I can't see any obvious places that memory is leaking; the messages are all
> being unref'd correctly as far as I can tell.
> 
> I'll keep investigating but the problem may well be internal to the D-Bus
> library.

As a follow up, the following trivial program has the same leaks reported by valgrind, so the problems are almost certainly internal to DBus.

#include <dlfcn.h>
#include <dbus/dbus.h>

DBusConnection *session_conn;
DBusConnection *(*bus_get_private)(DBusBusType, DBusError *);
void (*connection_close)(DBusConnection *);
void (*connection_unref)(DBusConnection *);

int main(void){
	void* handle = dlopen("libdbus-1.so.3", RTLD_NOW);

	bus_get_private = dlsym(handle, "dbus_bus_get_private");
	connection_close = dlsym(handle, "dbus_connection_close");
	connection_unref = dlsym(handle, "dbus_connection_unref");

	session_conn = bus_get_private(DBUS_BUS_SESSION, NULL);

	connection_close(session_conn);
	connection_unref(session_conn);

	dlclose(handle);

	return 0;
}
Comment 4 Alex Baines 2014-07-06 21:19:51 UTC
Created attachment 1738 [details]
Fix DBus related memory leak.

Turns out I was wrong and there's a dbus_shutdown function that I had no idea about until now. 

Calling it fixes the leaks, I have attached a patch.
Comment 5 lectem 2014-07-07 01:47:21 UTC
Great news !
I'll try this right away =D
Comment 6 Sam Lantinga 2014-07-07 17:28:57 UTC
The patch is in, thanks!
https://hg.libsdl.org/SDL/rev/84ae33058c67