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

Memory leak in headless rendering stack #248

Open
brendan-ward opened this issue Mar 8, 2022 · 0 comments
Open

Memory leak in headless rendering stack #248

brendan-ward opened this issue Mar 8, 2022 · 0 comments
Labels
bug Something isn't working linux

Comments

@brendan-ward
Copy link
Collaborator

Detected using Valgrind within an Ubuntu Docker container, using the mbgl-render command line tool created when compiling this library. The first leak looks hard to track down, but the second larger leak appears to be related to how the renderer backend / scope is managed for headless rendering. This occurs for both the EGL and GLX backend, and appears as if this may have been around for some time.

==3942== HEAP SUMMARY:
==3942==     in use at exit: 166,814 bytes in 2,393 blocks
==3942==   total heap usage: 20,594 allocs, 18,201 frees, 43,644,156 bytes allocated
==3942== 
==3942== 64 bytes in 1 blocks are definitely lost in loss record 1,975 of 2,124
==3942==    at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==3942==    by 0xE3620CD: ???
==3942==    by 0xDAF3063: ???
==3942==    by 0x4011B89: call_init.part.0 (dl-init.c:72)
==3942==    by 0x4011C90: call_init (dl-init.c:30)
==3942==    by 0x4011C90: _dl_init (dl-init.c:119)
==3942==    by 0x5541894: _dl_catch_exception (dl-error-skeleton.c:182)
==3942==    by 0x401642C: dl_open_worker (dl-open.c:758)
==3942==    by 0x5541837: _dl_catch_exception (dl-error-skeleton.c:208)
==3942==    by 0x40155F9: _dl_open (dl-open.c:837)
==3942==    by 0x568C34B: dlopen_doit (dlopen.c:66)
==3942==    by 0x5541837: _dl_catch_exception (dl-error-skeleton.c:208)
==3942==    by 0x5541902: _dl_catch_error (dl-error-skeleton.c:227)
==3942== 
==3942== 5,355 bytes in 255 blocks are definitely lost in loss record 2,123 of 2,124
==3942==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==3942==    by 0x54803BE: strdup (strdup.c:42)
==3942==    by 0xD6666F6: ???
==3942==    by 0xD6664A4: ???
==3942==    by 0x5613436: ??? (in /usr/lib/x86_64-linux-gnu/libGLdispatch.so.0.0.0)
==3942==    by 0x5613E1C: __glDispatchMakeCurrent (in /usr/lib/x86_64-linux-gnu/libGLdispatch.so.0.0.0)
==3942==    by 0x4855419: ??? (in /usr/lib/x86_64-linux-gnu/libGLX.so.0.0.0)
==3942==    by 0x4856C57: ??? (in /usr/lib/x86_64-linux-gnu/libGLX.so.0.0.0)
==3942==    by 0x205AA1: mbgl::gl::GLXBackendImpl::activateContext() (in /tmp/build/bin/mbgl-render)
==3942==    by 0x284FB7: mbgl::gfx::BackendScope::BackendScope(mbgl::gfx::RendererBackend&, mbgl::gfx::BackendScope::ScopeType) (in /tmp/build/bin/mbgl-render)
==3942==    by 0x1CE0B6: mbgl::HeadlessFrontend::render(mbgl::Map&) (in /tmp/build/bin/mbgl-render)
==3942==    by 0x178CDD: main (in /tmp/build/bin/mbgl-render)
==3942== 
==3942== LEAK SUMMARY:
==3942==    definitely lost: 5,419 bytes in 256 blocks
==3942==    indirectly lost: 0 bytes in 0 blocks
==3942==      possibly lost: 0 bytes in 0 blocks
==3942==    still reachable: 161,395 bytes in 2,137 blocks
==3942==         suppressed: 0 bytes in 0 blocks
==3942== Reachable blocks (those to which a pointer was found) are not shown.

To reproduce, see the attached Dockerfile and JSON style.
dockerfile_and_json.zip

Or if you have valgrind already installed and the library built:

valgrind --leak-check=full --show-leak-kinds=definite /tmp/build/bin/mbgl-render -s /tmp/example-style-empty.json -o /tmp/test.png

Note: you may need to start Xvfb first if you are running truly headless here:

Xvfb ${DISPLAY} -screen 0 "1024x768x24" -ac +render -noreset -nolisten tcp  &

While investigating, I noticed there were some differences between how the backend scope guard is used in the headless renderer stack (appears to always use default, gfx::BackendScope::ScopeType::Explicit in scope guard calls) compared to Qt, etc (appears to use gfx::BackendScope::ScopeType::Implicit in most / all of the scope guard calls). However, I found it quite difficult to follow what was going on here. My initial thoughts are that it is creating but not correcly releasing GL related resources.

But perhaps someone who understands the headless rendering stack here will be able to more quickly spot the issue?

Related pymgl #1 (it was first detected here), mbgl-renderer (note: this uses the latest Mapbox NodeJS bindings, have not yet tested with latest version of NodeJS bindings added here in #217).

@louwers louwers added bug Something isn't working linux labels Aug 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working linux
Projects
None yet
Development

No branches or pull requests

2 participants