Testing xbmc pvr; libGL threading issues...

Juergen Lock nox at jelal.kn-bremen.de
Fri Oct 21 18:57:20 UTC 2011


On Fri, Oct 14, 2011 at 11:54:50PM +0200, Juergen Lock wrote:
> Hi!
> 
>  I had been playing with opdenkamp's xbmc pvr branch and pipelka's
> xvdr xbmc addon and vdr plugin for a little while now, and finally
> have something that more or less runs.  One issue that took me a
> while to figure out were crashes in libGL when switching live
> channels:
> 
> (gdb) bt
> #0  0x00000008041abca7 in glIsTexture () from /usr/local/lib/libGL.so.1
> #1  0x0000000000b2a995 in CLinuxRendererGL::DeleteYV12Texture (
>     this=0x8340b8800, index=0) at LinuxRendererGL.cpp:1690
> #2  0x0000000000b2eae2 in CLinuxRendererGL::UnInit (this=0x8340b8800)
>     at LinuxRendererGL.cpp:1059
> #3  0x0000000000b2ed9e in CLinuxRendererGL::PreInit (this=0x8340b8800)
>     at LinuxRendererGL.cpp:719
> #4  0x0000000000b29049 in CXBMCRenderManager::PreInit (this=0x1546920)
>     at RenderManager.cpp:324
> #5  0x0000000000b8bf4f in CDVDPlayerVideo::OpenStream (this=0x835400590, 
>     hint=@0x7ffffdfcee20) at DVDPlayerVideo.cpp:183
> #6  0x0000000000b6d88e in CDVDPlayer::OpenVideoStream (this=0x835400000, 
>     iStream=0, source=256) at DVDPlayer.cpp:2891
> #7  0x0000000000b79734 in CDVDPlayer::Process (this=0x835400000)
>     at DVDPlayer.cpp:1207
> #8  0x0000000000f4a74d in CThread::staticThread (data=0x835400010)
>     at Thread.cpp:177
> 
> turns out libGL keeps thread-local pointers and xbmc called into
> libGL (glIsTexture()) from (apparently) a new thread where then
> _x86_64_get_dispatch in:
> 
> 	work/Mesa-7.6.1/src/mesa/x86-64/glapi_x86-64.S
> 
> returned NULL and thus the glIsTexture wrapper in the same .S
> got a segfault referencing that NULL pointer here:
> 
> [...]
>         .p2align        4,,15
>         .globl  GL_PREFIX(IsTexture)
>         .type   GL_PREFIX(IsTexture), @function
> GL_PREFIX(IsTexture):
> #if defined(GLX_USE_TLS)
>         call    _x86_64_get_dispatch at PLT
>         movq    2640(%rax), %r11
>         jmp     *%r11
> #elif defined(PTHREADS)
>         pushq   %rdi
>         call    _x86_64_get_dispatch at PLT
>         popq    %rdi
>         movq    2640(%rax), %r11
> 	^^^^^^^^^^^^^^^^^^^^^^^^ segfault
>         jmp     *%r11
> #else
> [...]
> 
> _x86_64_get_dispatch uses pthread_getspecific() and looks like this:
> 
> [...]
> #elif defined(PTHREADS)
> 
>         .extern _glapi_Dispatch
>         .extern _gl_DispatchTSD
>         .extern pthread_getspecific
> 
>         .p2align        4,,15
> _x86_64_get_dispatch:
>         movq    _gl_DispatchTSD at GOTPCREL(%rip), %rax
>         movl    (%rax), %edi
>         jmp     pthread_getspecific at PLT
> 
> #elif defined(THREADS)
> [...]
> 
> and some documentation about these thread-local pointers is here:
> 
> 	work/Mesa-7.6.1/docs/dispatch.html
> 
>  After some googling I stumbled across this debian ticket that has a patch:
> 
> 	http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=536106
> 
> so I changed the libGL port's files/patch-src__mesa__x86-64__glapi_x86-64.S
> into this:
> 
> --------snip------
> --- ./src/mesa/x86-64/glapi_x86-64.S.orig	2009-03-13 04:28:49.000000000 +0100
> +++ ./src/mesa/x86-64/glapi_x86-64.S	2011-01-28 18:12:18.000000000 +0100
> @@ -73,7 +73,12 @@ _x86_64_get_dispatch:
>  
>  	.p2align	4,,15
>  _x86_64_get_dispatch:
> -	movq	_gl_DispatchTSD(%rip), %rdi
> +	movq	_glapi_Dispatch(%rip), %rax
> +	testq	%rax,%rax
> +	je	1f
> +	ret
> +1:	movq	_gl_DispatchTSD at GOTPCREL(%rip), %rax
> +	movl	(%rax), %edi
>  	jmp	pthread_getspecific at PLT
>  
>  #elif defined(THREADS)
> --------snip------
> 
>  That fixed these crashes but now I got other crashes that seem to be
> related to messages like:
> 
> 	Recursive call into r300FlushCmdBufLocked!
> 
> (this is using the xorg radeon drivers, the nvidia libGL blob on
> the other box crashed in glIsTexture() too but obviously I cannot
> easily debug that) - so I looked for another workaround.  What I
> finally ended up doing was this patch:
> (files/patch-xbmc-cores-VideoRenderers-LinuxRendererGL.cpp)
> 
> --- xbmc/cores/VideoRenderers/LinuxRendererGL.cpp.orig
> +++ xbmc/cores/VideoRenderers/LinuxRendererGL.cpp
> @@ -159,6 +159,10 @@ CLinuxRendererGL::CLinuxRendererGL()
>    m_rgbPbo = 0;
>  
>    m_dllSwScale = new DllSwScale;
> +
> +#ifdef __FreeBSD__
> +  m_tid = NULL;
> +#endif
>  }
>  
>  CLinuxRendererGL::~CLinuxRendererGL()
> @@ -247,6 +251,9 @@ bool CLinuxRendererGL::ValidateRenderTar
>        (this->*m_textureCreate)(i);
>  
>      m_bValidated = true;
> +#ifdef __FreeBSD__
> +    m_tid = pthread_self();
> +#endif
>      return true;
>    }
>    return false;
> @@ -716,6 +723,9 @@ unsigned int CLinuxRendererGL::PreInit()
>    CSingleLock lock(g_graphicsContext);
>    m_bConfigured = false;
>    m_bValidated = false;
> +#ifdef __FreeBSD__ // XXX Will this leak?  It's needed to avoid crashes... :(
> +  if (pthread_self() == m_tid)
> +#endif
>    UnInit();
>    m_resolution = g_guiSettings.m_LookAndFeelResolution;
>    if ( m_resolution == RES_WINDOW )
> 
>  i.e. I only called into CLinuxRendererGL::UnInit() (where the original
> crashes happened) if this was the same thread that created the textures
> that CLinuxRendererGL::UnInit() tried to delete.  I don't know if this
> will leak memory, textures, or something else so I'd prefer libGL
> to be fixed properly...  (And as you might have guessed, this code runs
> just fine unpatched on Linux...)

And now I tested this with libGL and friends from xorg-dev,

	http://wiki.freebsd.org/Xorg

and those no longer need this patch.  (I didn't update all of xorg,
just the stuff below graphics/ .)

 Just FYI, :)
	Juergen


More information about the freebsd-multimedia mailing list