Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AMD GLX Memory Leak #307

Open
awsdert opened this issue Jun 19, 2021 · 13 comments
Open

AMD GLX Memory Leak #307

awsdert opened this issue Jun 19, 2021 · 13 comments

Comments

@awsdert
Copy link

awsdert commented Jun 19, 2021

Not sure if this is from glew or not, not even sure it's this project's code that's being relied on, figure you can help me identify regardless, anyways this is what I get from valgrind when I run it on my own app:

==53259== Memcheck, a memory error detector
==53259== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==53259== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==53259== Command: ./d.out
==53259==
==53259==
==53259== HEAP SUMMARY:
==53259==     in use at exit: 345,932 bytes in 3,442 blocks
==53259==   total heap usage: 48,558 allocs, 45,116 frees, 19,349,259 bytes allocated
==53259==
==53259== 844 bytes in 1 blocks are definitely lost in loss record 2,336 of 2,362
==53259==    at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==53259==    by 0x5B3D8BC: ???
==53259==    by 0x5B3DB97: ???
==53259==    by 0x49D0B89: glxewInit (in /usr/lib/libGLEW.so.2.2.0)
==53259==    by 0x49DC231: glewInit (in /usr/lib/libGLEW.so.2.2.0)
==53259==    by 0x10D156: main (main.c:386)
==53259==
==53259== LEAK SUMMARY:
==53259==    definitely lost: 844 bytes in 1 blocks
==53259==    indirectly lost: 0 bytes in 0 blocks
==53259==      possibly lost: 0 bytes in 0 blocks
==53259==    still reachable: 345,032 bytes in 3,439 blocks
==53259==         suppressed: 56 bytes in 2 blocks
==53259== Reachable blocks (those to which a pointer was found) are not shown.
==53259== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==53259==
==53259== For lists of detected and suppressed errors, rerun with: -s
==53259== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)

I originally had more but to be sure it wasn't my own code causing the the bulk of them I ended up writing my own version of malloc & co with a prefix attached. I'm on Manjaro Cinnamon x64 btw.

@nigels-com
Copy link
Owner

Thanks for the report.

It looks like it's GLX that is leaking the block of 844 bytes.
The function glxewInit is making a few GLX calls, but nothing that is memory that GLEW ought to be managing, from what I can tell.

GLEW doesn't have a finaliser API, and even if it did I'm not sure that GLX does.
But I'll flag this as a bug for now.

BTW does glewinfo leak on your setup? Can you attach the first 20 lines or so of the output?

$ LD_LIBRARY_PATH=`pwd`/lib valgrind -- bin/glewinfo
...
==3702201== HEAP SUMMARY:
==3702201==     in use at exit: 15,755 bytes in 43 blocks
==3702201==   total heap usage: 5,302 allocs, 5,259 frees, 153,699,201 bytes allocated
==3702201== 
==3702201== LEAK SUMMARY:
==3702201==    definitely lost: 0 bytes in 0 blocks
==3702201==    indirectly lost: 0 bytes in 0 blocks
==3702201==      possibly lost: 0 bytes in 0 blocks
==3702201==    still reachable: 15,755 bytes in 43 blocks
==3702201==         suppressed: 0 bytes in 0 blocks
==3702201== Rerun with --leak-check=full to see details of leaked memory

@nigels-com nigels-com self-assigned this Jun 20, 2021
@nigels-com nigels-com added the bug label Jun 20, 2021
@awsdert
Copy link
Author

awsdert commented Jun 20, 2021

leaks.txt
Yeah it reports leaks, just used the command 'valgrind glewinfo' as what you gave didn't work for me.

@awsdert
Copy link
Author

awsdert commented Jun 24, 2021

Might I suggest doing what lua does and just provide a couple of parameters for a memory allocater and user data, this would allow glew to use them if needed but ignore them if not, either way it plays ball, I personally think that every library should provide such options.

Edit: To keep API compatability you could use a seperate iniatiser function called glewInitWithAllocator( glewAllocCB allocCB, void* ud ) then have glewInit just call glewInitWithAllocator( NULL, NULL ) and pass the buck

@awsdert awsdert closed this as completed Jun 24, 2021
@awsdert awsdert reopened this Jun 24, 2021
@awsdert
Copy link
Author

awsdert commented Jun 24, 2021

Closed by accident, browser behaving badly atm

@nigels-com
Copy link
Owner

Not sure how it helps here.
GLEW is a fairly thin wrapper over GLX (or EGL).
I don't know if there is a good way to tell GLX to free this particular memory block.
I get the impression that this particular leak is specific to your GLX implementation. AMD? Intel? Mesa?

$ ldd lib/libGLEW.so
	linux-vdso.so.1 (0x00007ffeb08fb000)
	libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007fb5e9e1d000)
	libGLdispatch.so.0 => /lib/x86_64-linux-gnu/libGLdispatch.so.0 (0x00007fb5e9d65000)
	libGLX.so.0 => /lib/x86_64-linux-gnu/libGLX.so.0 (0x00007fb5e9d31000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb5e9b3f000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fb5e9b39000)
	libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007fb5e99fc000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fb5e9f79000)
	libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fb5e99d0000)
	libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007fb5e99ca000)
	libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fb5e99c2000)
	libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fb5e99a8000)

$ nm -u lib/libGLEW.so 
                 w __cxa_finalize
                 U glXGetClientString
                 U glXGetProcAddressARB
                 U glXQueryVersion
                 w __gmon_start__
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable

@awsdert
Copy link
Author

awsdert commented Jun 24, 2021

Maybe, like I said, I'm not sure if glew is responsible for it or something further down the line, I'm not sure where to look when it involves implementation. I know it's AMD because my whole computer is a custom AMD build. If you're familiar with where to post such issues then please tell, I'll post the issue there as well and link it back to this thread, one way or another I'd like to track down the source of the leak and plug it.

@nigels-com
Copy link
Owner

Indeed. Extracted from @awsdert 's glewinfo log:

GLEW version 2.2.0
Reporting capabilities of display , visual 0x502
Running on a AMD Radeon (TM) RX 480 Graphics (POLARIS10, DRM 3.40.0, 5.12.9-1-MANJARO, LLVM 12.0.0) from AMD
OpenGL version 4.6 (Compatibility Profile) Mesa 21.1.2 is supported

@nigels-com
Copy link
Owner

If you want to narrow it further, put some early-outs (return GLEW_ERROR_NO_GLX_DISPLAY) before the following calls in glxewInit:

  • _glewInit_GLX_VERSION_1_2
  • glXGetCurrentDisplay
  • glXQueryVersion
  • glXGetClientString
  • _glewInit_GLX_VERSION_1_3

Should be enough for valgrind to diagnose the specific GLX function that is allocating the block. I would guess glXGetClientString as the most likely.

@awsdert
Copy link
Author

awsdert commented Jun 24, 2021

Alright, I'll give that a try after I finish converting https://github.com/ssloy/tinyrenderer to ANSI C so I can understand how to use OpenGL properly, as it stands I'm finding the guides useless because they half-ass the information.

Edit: For anyone wanting to copy my idea of learning from an existing project, this is where I found the above: https://github.com/raizam/gamedev_libraries#rendering

@nigels-com nigels-com changed the title Memory Leak AMD GLX Memory Leak Jun 30, 2021
@MisterMjir
Copy link

I was using GLEW by directly including the header and .c file and the leak was at glXGetClientString in glxewInit. The docs don't mention anything about it needing to be freed, but I just added

if (*extStart != '\0') {
  XFree((void *) extStart);
}

right before the return GLEW_OK. This is kinda hacky and I'm not sure if it's 100% correct so I'm not gonna open and make a pull request with that, but valgrind doesn't complain about the leak after adding that.

I also happen to have an AMD cpu, so I'm not sure if this fixes GLX leaks on other platforms or if those even have this leak to begin with.

@awsdert
Copy link
Author

awsdert commented Sep 19, 2021 via email

@DanRStevens
Copy link

I'm also seeing valgrind reported memory leaks related to GLEW in a game project I was working on, one of which appears to match up well with the error listed above.

As per the suggestion to run valgrind against glewinfo, I tried that as well, and the memory leak was detected that way as well.

Hardware is an Intel NUC (NUC10i357FN), running Ubuntu 22.04.


glewinfo


GLEW Extension Info

GLEW version 2.2.0
Reporting capabilities of display , visual 0x56b
Running on a Mesa Intel(R) UHD Graphics (CML GT2) from Intel
OpenGL version 4.6 (Compatibility Profile) Mesa 22.0.5 is supported
...


valgrind --leak-check=full --show-possibly-lost=no glewinfo

...
==48421==
==48421== HEAP SUMMARY:
==48421== in use at exit: 351,108 bytes in 2,602 blocks
==48421== total heap usage: 14,460 allocs, 11,858 frees, 4,197,637 bytes allocated
==48421==
==48421== 917 bytes in 1 blocks are definitely lost in loss record 2,116 of 2,144
==48421== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==48421== by 0x52AD9B7: ???
==48421== by 0x52ADFD2: ???
==48421== by 0x48ED1FD: glxewInit (glew.c:22808)
==48421== by 0x152493: main (glewinfo.c:18480)
==48421==
==48421== 1,208 (56 direct, 1,152 indirect) bytes in 1 blocks are definitely lost in loss record 2,120 of 2,144
==48421== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==48421== by 0x57C3460: driCreateNewDrawable (dri_util.c:668)
==48421== by 0x52C9068: ???
==48421== by 0x52BB7C7: ???
==48421== by 0x52A58D6: ???
==48421== by 0x52BBA76: ???
==48421== by 0x52ABE12: ???
==48421== by 0x4DF5462: InternalMakeCurrentVendor (libglx.c:871)
==48421== by 0x4DF7812: InternalMakeCurrentDispatch (libglx.c:926)
==48421== by 0x4DFC276: CommonMakeCurrent (libglx.c:1070)
==48421== by 0x17837F: glewCreateContext (glewinfo.c:18967)
==48421== by 0x152477: main (glewinfo.c:18473)
==48421==
==48421== LEAK SUMMARY:
==48421== definitely lost: 973 bytes in 2 blocks
==48421== indirectly lost: 1,152 bytes in 2 blocks
==48421== possibly lost: 74,088 bytes in 154 blocks
==48421== still reachable: 274,895 bytes in 2,444 blocks
==48421== suppressed: 0 bytes in 0 blocks
==48421== Reachable blocks (those to which a pointer was found) are not shown.
==48421== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==48421==
==48421== For lists of detected and suppressed errors, rerun with: -s
==48421== ERROR SUMMARY: 48 errors from 48 contexts (suppressed: 0 from 0)


Side note: I used find-dbgsym-packages to find and install any debug symbol packages that might help translate addresses to meaningful names.

sudo apt install debian-goodies

find-dbgsym-packages --all glewinfo

I: ./glewinfo not found, using /usr/bin/glewinfo instead
glew-utils-dbgsym libbsd0-dbgsym libc6-dbg libgl1-dbgsym libglew2.2-dbgsym libglvnd0-dbgsym libglx0-dbgsym libmd0-dbgsym libx11-6-dbgsym libxau6-dbgsym libxcb1-dbgsym libxdmcp6-dbg

sudo apt install glew-utils-dbgsym libbsd0-dbgsym libc6-dbg libgl1-dbgsym libglew2.2-dbgsym libglvnd0-dbgsym libglx0-dbgsym libmd0-dbgsym libx11-6-dbgsym libxau6-dbgsym libxcb1-dbgsym libxdmcp6-dbg


I also experimented with ldd and nm, as seen earlier in the thread.

ldd /usr/bin/glewinfo

linux-vdso.so.1 (0x00007ffcb0ba1000)
libGLEW.so.2.2 => /lib/x86_64-linux-gnu/libGLEW.so.2.2 (0x00007f2f8f9b4000)
libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007f2f8f92d000)
libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007f2f8f7ed000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2f8f5c5000)
libGLdispatch.so.0 => /lib/x86_64-linux-gnu/libGLdispatch.so.0 (0x00007f2f8f50d000)
libGLX.so.0 => /lib/x86_64-linux-gnu/libGLX.so.0 (0x00007f2f8f4d7000)
libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f2f8f4ad000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2f8fb2f000)
libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007f2f8f4a7000)
libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f2f8f49f000)
libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007f2f8f487000)
libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x00007f2f8f47a000)

dir /lib/x86_64-linux-gnu/libGLEW.*

-rw-r--r-- 1 root root 1232650 Sep 29 2021 /lib/x86_64-linux-gnu/libGLEW.a
lrwxrwxrwx 1 root root 16 Sep 29 2021 /lib/x86_64-linux-gnu/libGLEW.so -> libGLEW.so.2.2.0
lrwxrwxrwx 1 root root 16 Sep 29 2021 /lib/x86_64-linux-gnu/libGLEW.so.2.2 -> libGLEW.so.2.2.0
-rw-r--r-- 1 root root 747560 Sep 29 2021 /lib/x86_64-linux-gnu/libGLEW.so.2.2.0

ldd /lib/x86_64-linux-gnu/libGLEW.so

linux-vdso.so.1 (0x00007ffee97d5000)
libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007fa4e315c000)
libGLdispatch.so.0 => /lib/x86_64-linux-gnu/libGLdispatch.so.0 (0x00007fa4e30a4000)
libGLX.so.0 => /lib/x86_64-linux-gnu/libGLX.so.0 (0x00007fa4e3070000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa4e2e48000)
libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007fa4e2d08000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa4e32c2000)
libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fa4e2cdc000)
libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007fa4e2cd6000)
libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fa4e2cce000)
libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fa4e2cb6000)
libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x00007fa4e2ca9000)

nm -u /lib/x86_64-linux-gnu/libGLEW.so

nm: /lib/x86_64-linux-gnu/libGLEW.so: no symbols

dpkg -L libglew2.2-dbgsym

...
/usr/lib/debug/.build-id/3e/6d80c4b67c657a8140bfc39aebc9697a243c31.debug
...

nm -u /usr/lib/debug/.build-id/3e/6d80c4b67c657a8140bfc39aebc9697a243c31.debug

            w __cxa_finalize
            U glXGetClientString
            U glXGetProcAddressARB
            U glXQueryVersion
            w __gmon_start__
            w _ITM_deregisterTMCloneTable
            w _ITM_registerTMCloneTable

I would be willing to do more digging if you've got any suggestions.

@awsdert
Copy link
Author

awsdert commented Sep 6, 2022

Due to mis-timing the end of my broadband vs the start of my unlimited mobile data (and getting sidetracked on various things) I completely forgot about this thread, anyways just for reference valgrind is still flagging issues on my setup in case anyone has already submitted to master an attempt to fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants