After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 725048 - gl: The display handle isn't freed correctly
gl: The display handle isn't freed correctly
Status: VERIFIED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-gl
git master
Other All
: Normal critical
: 1.3.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2014-02-24 10:15 UTC by Adrien SCH.
Modified: 2014-03-04 10:22 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Test case (4.05 KB, text/x-csrc)
2014-02-24 10:15 UTC, Adrien SCH.
  Details
Dead lock threads backtrace (11.95 KB, application/octet-stream)
2014-02-27 13:35 UTC, Adrien SCH.
  Details
test case with gstcontext (8.04 KB, text/x-csrc)
2014-03-04 00:50 UTC, Matthew Waters (ystreet00)
  Details
use the GObject type to propogate GstGLCOntext (2.98 KB, patch)
2014-03-04 07:18 UTC, Matthew Waters (ystreet00)
none Details | Review

Description Adrien SCH. 2014-02-24 10:15:27 UTC
Created attachment 270102 [details]
Test case

Bug discovered when exploring the GstGlContext memory leak (https://bugzilla.gnome.org/show_bug.cgi?id=724816).

Still after the correct release of GstGlContext, the display handler isn't freed correctly.
Comment 1 Matthew Waters (ystreet00) 2014-02-24 13:08:34 UTC
commit 103235a8ed2efb6cd8a7e5f6ce1d5a9e9815975d
Author: Matthew Waters <ystreet00@gmail.com>
Date:   Mon Feb 24 23:55:58 2014 +1100

    x11: close both of the display's we use
    
    (the comment doesn't seem to apply anymore)
    
    https://bugzilla.gnome.org/show_bug.cgi?id=725048
Comment 2 Adrien SCH. 2014-02-24 14:27:54 UTC
The previous correction doesn't fix the bug. I still got the message "Maximum number of clients reached" after a while.
Comment 3 Adrien SCH. 2014-02-24 16:00:40 UTC
(In reply to comment #2)
> The previous correction doesn't fix the bug. I still got the message "Maximum
> number of clients reached" after a while.

Forget my previous comment.

The specified modification causes a SEG FAULT in :
  • #0 xcb_writev
    from /usr/lib/x86_64-linux-gnu/libxcb.so.1
  • #1 _XSend
    from /usr/lib/x86_64-linux-gnu/libX11.so.6
  • #2 XQueryExtension
    from /usr/lib/x86_64-linux-gnu/libX11.so.6
  • #3 XInitExtension
    from /usr/lib/x86_64-linux-gnu/libX11.so.6
  • #4 ??
    from /usr/lib/x86_64-linux-gnu/libGL.so.1
  • #5 ??
    from /usr/lib/x86_64-linux-gnu/libGL.so.1
  • #6 glXDestroyContext
    from /usr/lib/x86_64-linux-gnu/libGL.so.1
  • #7 gst_gl_context_glx_destroy_context
    at gstglcontext_glx.c line 253
  • #8 gst_gl_context_create_thread
    at gstglcontext.c line 803

See test case application.

Note : Every case can be tested in the test application by update the demux_pad_added method.
Comment 4 Matthew Waters (ystreet00) 2014-02-27 10:17:35 UTC
b31a34a22ed8504fe4b8e645c2d3ef2ba1e122eb
Author: Matthew Waters <ystreet00@gmail.com>
Date:   Fri Feb 28 17:42:51 2014 +1100

    context: call window_class->close last
    
    We should destroy resources before closing the display connection
    
    Fixes https://bugzilla.gnome.org/show_bug.cgi?id=725048
Comment 5 Adrien SCH. 2014-02-27 13:35:30 UTC
Created attachment 270470 [details]
Dead lock threads backtrace

Dead appears following the commit : b31a34a22ed8504fe4b8e645c2d3ef2ba1e122eb
Comment 6 Adrien SCH. 2014-02-27 13:37:34 UTC
Using the test application, I observed a deadlock when the first pipeline is stopping. 

I start to wonder if the context should be share between the different pipeline and context. It is possible ? May it resolve the issue ?
Comment 7 Matthew Waters (ystreet00) 2014-02-27 23:11:07 UTC
I've never seen that occur on my system (intel or nvidia).  It looks like the concurrent glXMakCurrent calls deadlock on each other which probably requires updating the GL/X stack.

For me, your test application works fine most of the time :P.  It usually segfaults in gstreamer-vaapi's display cache implementation on startup :/.  If it gets past there, everything's fine.
Comment 8 Adrien SCH. 2014-03-03 13:04:27 UTC
Did you apply you patch against vaapidecode (unref the ref to the pool) ? Because after an update to MESA 10.0.3 I receive a SEGFAULT when the test application unref the pipeline.

Back trace : 

Thread 4 (Thread 0x7ffff530f700 (LWP 10778))

  • #0 __lll_lock_wait
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S line 135
  • #1 _L_lock_974
    from /lib/x86_64-linux-gnu/libpthread.so.0
  • #2 __GI___pthread_mutex_lock
    at pthread_mutex_lock.c line 64
  • #3 xcb_writev
    from /usr/lib/x86_64-linux-gnu/libxcb.so.1
  • #4 _XSend
    from /usr/lib/x86_64-linux-gnu/libX11.so.6
  • #5 XQueryExtension
    from /usr/lib/x86_64-linux-gnu/libX11.so.6
  • #6 XInitExtension
    from /usr/lib/x86_64-linux-gnu/libX11.so.6
  • #7 ??
    from /usr/lib/x86_64-linux-gnu/libGL.so.1
  • #8 ??
    from /usr/lib/x86_64-linux-gnu/libGL.so.1
  • #9 ??
    from /usr/lib/x86_64-linux-gnu/libGL.so.1
  • #10 glXMakeCurrentReadSGI
    from /usr/lib/x86_64-linux-gnu/libGL.so.1
  • #11 vaDestroySurfaceGLX_impl_libva
    at va_glx_impl.c line 914
  • #12 _gst_vaapi_texture_destroy_objects
    at gstvaapitexture.c line 80
  • #13 gst_vaapi_texture_destroy
    at gstvaapitexture.c line 118
  • #14 gst_vaapi_object_finalize
    at gstvaapiobject.c line 51
  • #15 gst_vaapi_mini_object_free
    at gstvaapiminiobject.c line 34
  • #16 gst_vaapi_mini_object_unref
    at gstvaapiminiobject.c line 137
  • #17 gst_vaapi_mini_object_replace
    at gstvaapiminiobject.c line 170
  • #18 gst_vaapi_object_replace_internal
    at gstvaapiobject_priv.h line 238
  • #19 gst_vaapi_object_replace
    at gstvaapiobject.c line 142
  • #20 gst_vaapi_texture_replace
    at gstvaapitexture.c line 380
  • #21 meta_texture_free
    at gstvaapivideometa_texture.c line 43
  • #22 _gst_buffer_free
    at gstbuffer.c line 563
  • #23 default_stop
    at gstbufferpool.c line 382
  • #24 do_stop
    at gstbufferpool.c line 402
  • #25 gst_buffer_pool_set_active
    at gstbufferpool.c line 468
  • #26 gst_buffer_pool_finalize
    at gstbufferpool.c line 197
  • #27 gst_vaapi_video_buffer_pool_finalize
    at gstvaapivideobufferpool.c line 64
  • #28 g_object_unref
    at /tmp/buildd/glib2.0-2.38.2/./gobject/gobject.c line 3197
  • #29 gst_object_unref
    at gstobject.c line 275
  • #30 gst_video_decoder_finalize
    at gstvideodecoder.c line 841
  • #31 g_object_unref
    at /tmp/buildd/glib2.0-2.38.2/./gobject/gobject.c line 3197
  • #32 gst_object_unref
    at gstobject.c line 275
  • #33 gst_bin_remove_func
    at gstbin.c line 1564
  • #34 gst_bin_dispose
    at gstbin.c line 528
  • #35 g_object_unref
    at /tmp/buildd/glib2.0-2.38.2/./gobject/gobject.c line 3160
  • #36 gst_object_unref
    at gstobject.c line 275
  • #37 gst_bin_remove_func
    at gstbin.c line 1564
  • #38 gst_bin_dispose
    at gstbin.c line 528
  • #39 g_object_unref
    at /tmp/buildd/glib2.0-2.38.2/./gobject/gobject.c line 3160
  • #40 display_run
    at ../main.c line 131
  • #41 run_display
    at ../main.c line 154
  • #42 g_thread_proxy
    at /tmp/buildd/glib2.0-2.38.2/./glib/gthread.c line 798
  • #43 start_thread
    at pthread_create.c line 311
  • #44 clone
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S line 113

Comment 9 Matthew Waters (ystreet00) 2014-03-03 14:22:47 UTC
So it looks like we free the gl context before gstreamer-vaapi is finished with it...and so mesa tries to create another one which involves __glXInitialize...which fails with the spectacular backtrace you have there.  

Essentially the problem is that we destroy too early and gstreamer-vaapi does not know the context has disappeared.  One workaround is to delay context destruction inside the element which is what I think cluttersink/webkit has (probably indirectly).  Ideally gstreamer-vaapi would hold a reference to the GL context that it's using however it does not know which context before GstVideoGLTextureUploadMeta::upload is called.

(gdb) bt
  • #0 gst_gl_context_finalize
    at gstglcontext.c line 272
  • #1 g_object_unref
    at gobject.c line 3197
  • #2 g_value_unset
    at gvalue.c line 274
  • #3 gst_structure_free
    at gststructure.c line 379
  • #4 array_free
    at garray.c line 367
  • #5 g_value_unset
    at gvalue.c line 274
  • #6 gst_structure_free
    at gststructure.c line 379
  • #7 _gst_query_free
    at gstquery.c line 202
  • #8 gst_query_unref
    at ../../../gst/gstquery.h line 235
  • #9 gst_base_transform_set_allocation
    at gstbasetransform.c line 816
  • #10 gst_base_transform_activate
    at gstbasetransform.c line 2349
  • #11 gst_base_transform_sink_activate_mode
  • #12 gst_pad_activate_mode
    at gstpad.c line 1083
  • #13 gst_pad_set_active
    at gstpad.c line 969
  • #14 activate_pads
    at gstelement.c line 2687
  • #0 xcb_writev
    at xcb_out.c line 311
  • #1 _XSend
    at xcb_io.c line 495
  • #2 XQueryExtension
    at QuExt.c line 47
  • #3 XInitExtension
    at InitExt.c line 47
  • #4 __glXInitialize
    at glxext.c line 826
  • #5 driFetchDrawable
    at dri_common.c line 389
  • #6 dri2_bind_context
    at dri2_glx.c line 147
  • #7 MakeContextCurrent
    at glxcurrent.c line 259
  • #8 ??
    from /usr/lib/libva-glx.so.1
  • #9 _gst_vaapi_texture_destroy_objects
    at gstvaapitexture.c line 80
  • #10 gst_vaapi_texture_destroy
    at gstvaapitexture.c line 118
  • #11 gst_vaapi_object_finalize
    at gstvaapiobject.c line 51
  • #12 gst_vaapi_mini_object_free
    at gstvaapiminiobject.c line 34
  • #13 gst_vaapi_mini_object_unref
    at gstvaapiminiobject.c line 137
  • #14 gst_vaapi_mini_object_replace
    at gstvaapiminiobject.c line 170
  • #15 gst_vaapi_object_replace_internal
    at gstvaapiobject_priv.h line 238

Comment 10 Adrien SCH. 2014-03-03 16:01:19 UTC
With my knowledge, I may suggest that the XCloseDisplay that you previously uncoment created this side effect. For me, the X11 display is closed when the GLContext is released but this operation perturbs the vaapi element. 

So the challenge here is (maybe - again with my little knowledge) to close the display at the very end of the releasing procedure. I will try on my side to apply this hypothesis, but you will have a better solution to resolve this issue.
Comment 11 Nicolas Dufresne (ndufresne) 2014-03-03 17:43:56 UTC
You're application lives longer then your pipeline, can't you simply create your context before you create your first pipeline and share that. Then you'd keep that context open till the end of your application, when all your pipeline has reached NULL state.(See gst_element_set_context(), sequence of operation is described in GstContext description).
Comment 12 Adrien SCH. 2014-03-03 19:40:49 UTC
It's possible to have an example ?
Comment 13 Matthew Waters (ystreet00) 2014-03-04 00:50:39 UTC
Created attachment 270861 [details]
test case with gstcontext

This is your example with GstContext integration.  However, GstGLContext is not propogated through GstContext (a little confusing, yes), but the GstGLDisplay is.  Currently there isn't a way of getting the GstGLContext out of the pipeline.  We might need to change that.
Comment 14 Matthew Waters (ystreet00) 2014-03-04 00:53:54 UTC
No, the GstContext version still segfaults with the same error.  The display being closed is not the issue, it's the fact that we have destroyed the context that gstreamer-vaapi wants to use to destroy its GL objects.
Comment 15 Matthew Waters (ystreet00) 2014-03-04 02:08:33 UTC
Reverting the XCloseDisplay change makes things work again albiet with the display leak.  However that's a side effect of the real issue.
Comment 16 Nicolas Dufresne (ndufresne) 2014-03-04 02:41:22 UTC
Mathew, why isn't your context ref-counted combine with a foreign flag for when the display comes from the application ? That's how it used to be in the 0.10.
Comment 17 Matthew Waters (ystreet00) 2014-03-04 02:50:16 UTC
That's exactly how it happens within GstGLDisplay, it's just that each context/window creates their own Display Connection which is closed as a result of the context being destroyed before vaapi is done with it.
Comment 18 Nicolas Dufresne (ndufresne) 2014-03-04 03:02:00 UTC
Hmm, ok, you may ignore me, I haven't looked at this code for a long time. So now we have multiple display connection per pipeline by default ? Also, if they are shared, why doesn't VAAPI take a ref on it ?
Comment 19 Matthew Waters (ystreet00) 2014-03-04 03:56:16 UTC
Yes, multiple by default.  VAAPI doesn't take a ref because it doesn't know about the context and it hasn't needed to.  Taking a ref on either the GstGLContext or the Display would work.  The first requiring the least work.

Just some background.  The reason it is like this is, with GstVideoOverlay case, we cannot call XInitThreads for integration with gtk+.  It will also segfault inside X11 on a lock unless XinitThreads is called before gtk_init which in general, does not happen. See tests/examples/gtk/filtervideooverlay/ for an example to test with.  So instead, we use at least one Display connection per thread.  If this turns out to be too complicated I'll move to requiring XInitThreads to be called.
Comment 20 Matthew Waters (ystreet00) 2014-03-04 07:18:37 UTC
Created attachment 270873 [details] [review]
use the GObject type to propogate GstGLCOntext

This works for me :).  You'll also need the patches in the following bugs:
https://bugzilla.gnome.org/show_bug.cgi?id=725642
https://bugzilla.gnome.org/show_bug.cgi?id=725643
Comment 21 Adrien SCH. 2014-03-04 10:22:03 UTC
Validated cases : 

Single pipeline : 
Vaapi elements only : OK
Vaapi + GL : OK
Vaapi + GL + Raw : OK

Multiple pipelines : 
Vaapi elements only : OK
Vaapi + GL : OK
Vaapi + GL + Raw : OK

Good job :)