Bug 98281

Summary: 'message's in ctx->Debug.LogMessages[] seem to leak.
Product: Mesa Reporter: Suzuki, Shinji <shinji.suzuki>
Component: Mesa coreAssignee: mesa-dev
Status: RESOLVED FIXED QA Contact: mesa-dev
Severity: normal    
Priority: medium    
Version: 11.2   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments: free Log.Messages[].message within debug_destroy().
A program to reproduce leak by calling glGetString(GL_EXTENSIONS) with core-profile

Description Suzuki, Shinji 2016-10-16 19:40:55 UTC
Created attachment 127335 [details] [review]
free  Log.Messages[].message within debug_destroy().

My app generates a call to debug_message_store() from within glewInit() and valgrind reports memory leak from 'msg->message = malloc(length+1);' in the former.
Comment 1 Edward O'Callaghan 2016-10-16 22:08:08 UTC
I believe this is actually a false positive.. The reasoning is that debug_message_store() builds up a ring of messages.
Comment 2 Suzuki, Shinji 2016-10-17 10:40:26 UTC
The amount of memory being in use may be bounded. But I believe there are blocks that don't get released until process termination. Having unreleased memory brings bad user experience to users of valgrind or any kind of memory debugging tools.
Comment 3 Emil Velikov 2016-10-17 13:04:43 UTC
Of the top of my head, it sounds like one is using PushDebugGroup without a corresponding Pop.

Can you attach a simple program which reproduces this ? Ideally one which does not depend on glew, in order to isolate a problem with it.
Comment 4 Eero Tamminen 2016-10-17 14:32:03 UTC
(In reply to Suzuki, Shinji from comment #2)
> The amount of memory being in use may be bounded. But I believe there are
> blocks that don't get released until process termination. Having unreleased
> memory brings bad user experience to users of valgrind or any kind of memory
> debugging tools.

While libraries should not leak even in their destroy/exit functions... If you just want to debug run-time leaks instead of things leaked in the application termination procedure, there's a way to do that with Valgrind.

Just terminate the program with a signal that Valgrind can catch, but the program itself doesn't (e.g. SIGBUS, SIGXCPU or SIGTRAP are rarely caught by programs, but Valgrind catches etc).  That way program's termination code (and any library functions called by it) cannot leak memory, and Valgrind will list only leaks happening during normal run-time.
Comment 5 Suzuki, Shinji 2016-10-17 16:15:01 UTC
(In reply to Eero Tamminen from comment #4)
> Just terminate the program with a signal that Valgrind can catch, but the
Thank you for the tip. Very useful when I have to wade my way through tons of false positives. But I still cherish rare occasion when valgrind quits quietly.
Comment 6 Suzuki, Shinji 2016-10-17 16:22:15 UTC
(In reply to Emil Velikov from comment #3)
> Can you attach a simple program which reproduces this ? Ideally one which
> does not depend on glew, in order to isolate a problem with it.

Please have a look on the following attachment. In a nutshell, calling glGetString(GL_EXTENSIONS) within a core-profile context seems to generate the leak.

==25470== 46 bytes in 1 blocks are definitely lost in loss record 78 of 189
==25470==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25470==    by 0x8DED4C8: debug_message_store (debug_output.c:226)
==25470==    by 0x8DED6EC: debug_log_message (debug_output.c:634)
==25470==    by 0x8DED6EC: log_msg_locked_and_unlock (debug_output.c:868)
==25470==    by 0x8E0D49C: _mesa_error (errors.c:330)
==25470==    by 0x8E7FBD3: _mesa_GetString (getstring.c:139)
==25470==    by 0x401DF8: main (test.cpp:193)
Comment 7 Suzuki, Shinji 2016-10-17 16:24:33 UTC
Created attachment 127363 [details]
A program to reproduce leak by calling glGetString(GL_EXTENSIONS) with core-profile
Comment 8 Emil Velikov 2016-10-17 16:51:27 UTC
(In reply to Suzuki, Shinji from comment #6)
> (In reply to Emil Velikov from comment #3)
> > Can you attach a simple program which reproduces this ? Ideally one which
> > does not depend on glew, in order to isolate a problem with it.
> 
> Please have a look on the following attachment. In a nutshell, calling
> glGetString(GL_EXTENSIONS) within a core-profile context seems to generate
> the leak.
> 
> ==25470== 46 bytes in 1 blocks are definitely lost in loss record 78 of 189
> ==25470==    at 0x4C2DB8F: malloc (in
> /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==25470==    by 0x8DED4C8: debug_message_store (debug_output.c:226)
> ==25470==    by 0x8DED6EC: debug_log_message (debug_output.c:634)
> ==25470==    by 0x8DED6EC: log_msg_locked_and_unlock (debug_output.c:868)
> ==25470==    by 0x8E0D49C: _mesa_error (errors.c:330)
> ==25470==    by 0x8E7FBD3: _mesa_GetString (getstring.c:139)
> ==25470==    by 0x401DF8: main (test.cpp:193)

Hmm yes. IIRC this happens because the spec dictates that the stack depth must be 1 to begin with, at which point we detect that we should 'do_log' in _mesa_error() which effectively adds the debug message.

Might be worth checking how other implementations behave in such a case (just do anything illegal) and read through the spec what the exact behaviour should be.

Just some ideas, I'm busy with something else atm :-\
Comment 9 Timothy Arceri 2018-04-13 05:42:11 UTC
Thanks for the bug report and sorry for delay in fixing.

Fix sent to list: https://patchwork.freedesktop.org/patch/216870/
Comment 10 Timothy Arceri 2018-04-13 12:22:06 UTC
Fixed by:

commit a63e69f5f0b4d960bd106068d8c7d13b82fea759
Author: Timothy Arceri <tarceri@itsqueeze.com>
Date:   Fri Apr 13 15:23:57 2018 +1000

    mesa: free debug messages when destroying the debug state
    
    Fixes: 04a8baad3721 "mesa: refactor _mesa_PopDebugGroup and _mesa_free_errors_data"
    
    Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98281
Comment 11 Suzuki, Shinji 2018-04-13 12:30:07 UTC
Thank you very much for not having forgotten about this bug and getting it fixed.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.