> Looks like Xorg crashes on exit after 463dd87
>
> To reproduce:
>
> export DISPLAY=:1 ; X :1 & sleep 2 ; dwm &  sleep 1 ; xrandr --output DVI-0
> --off ; xrandr --output HDMI-0 --auto --rotate left ; xrandr --output DVI-0
> --auto --left-of HDMI-0 ; sleep 3 ; kill %1
>
> (gdb) bt full
> #0  DamageUnregister (pDrawable=0x0, pDamage=0x22da320) at
> ../../../miext/damage/damage.c:1923
>        pScreen = <value optimized out>
>        pScrPriv = 0x0
> #1  0x00000000004b04cb in xf86RotateDestroy (crtc=0x2036890) at
> ../../../../hw/xfree86/modes/xf86Rotate.c:308
>        pScrn = <value optimized out>
>        pScreen = 0x2040c80
>        xf86_config = 0x2036700
>        c = <value optimized out>
> #2  0x00000000004b05d5 in xf86RotateCloseScreen (screen=<value optimized out>)
>    at ../../../../hw/xfree86/modes/xf86Rotate.c:344
>        scrn = <value optimized out>
>        xf86_config = 0x2036700
>        c = <value optimized out>
> #3  0x00000000004a2182 in xf86CrtcCloseScreen (index=0, screen=0x2040c80) at
> ../../../../hw/xfree86/modes/xf86Crtc.c:745
>        scrn = <value optimized out>
>        config = 0x2036700
>        o = <value optimized out>
>        c = <value optimized out>
> #4  0x00000000004c07fb in CursorCloseScreen (index=0, pScreen=0x2040c80) at
> ../../xfixes/cursor.c:207
>        ret = <value optimized out>
>        close_proc = <value optimized out>
>        display_proc = <value optimized out>
>        constrain_proc = <value optimized out>
> #5  0x00000000004f498c in AnimCurCloseScreen (index=<value optimized out>,
> pScreen=<value optimized out>)
>    at ../../render/animcur.c:106
>        as = 0x2070d60
>        ret = <value optimized out>
> #6  0x000000000042719f in main (argc=2, argv=<value optimized out>, 
> envp=<value
> optimized out>) at ../../dix/main.c:327
>        i = 0
>        alwaysCheckForInput = {0, 1}
>

I worked around the crash by not calling DamageUnregister if drawable is 0.

        /* Free damage structure */
        if (xf86_config->rotation_damage_registered)
        {
            DrawablePtr screenDrawable = &pScreen->root->drawable;
            if (screenDrawable) DamageUnregister (screenDrawable,
                              xf86_config->rotation_damage);


This causes a double-free of the damage, likely on the next line.
  DamageDestroy (xf86_config->rotation_damage);


I suspect the issue is that  (xf86_config->rotation_damage_registered)
is independent of the damage being actually valid.

In FreeAllResources it is already destroyed by the point X gets to
CursorCloseScreen.


==7817== Invalid read of size 8
==7817==    at 0x4F74F0: DamageDestroy (damage.c:1962)
==7817==    by 0x4B065E: xf86RotateDestroy (xf86Rotate.c:314)
==7817==    by 0x4B0774: xf86RotateCloseScreen (xf86Rotate.c:345)
==7817==    by 0x4A2311: xf86CrtcCloseScreen (xf86Crtc.c:745)
==7817==    by 0x4C093A: CursorCloseScreen (cursor.c:207)
==7817==    by 0x4F483B: AnimCurCloseScreen (animcur.c:106)
==7817==    by 0x4272EE: main (main.c:327)
==7817==  Address 0xb666e28 is 136 bytes inside a block of size 152 free'd
==7817==    at 0x4C268FE: free (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7817==    by 0x4F7655: damageDestroyWindow (damage.c:1741)
==7817==    by 0x7CB43D9: XvDestroyWindow (xvmain.c:439)
==7817==    by 0x489F32: xf86XVDestroyWindow (xf86xv.c:1153)
==7817==    by 0x45D5E3: FreeWindowResources (window.c:941)
==7817==    by 0x460347: DeleteWindow (window.c:1019)
==7817==    by 0x456F41: doFreeResource (resource.c:571)
==7817==    by 0x457C79: FreeClientResources (resource.c:853)
==7817==    by 0x457D26: FreeAllResources (resource.c:869)
==7817==    by 0x42726D: main (main.c:308)
==7817==
==7817== Invalid read of size 8
==7817==    at 0x4F7520: DamageDestroy (damage.c:1965)
==7817==    by 0x4B065E: xf86RotateDestroy (xf86Rotate.c:314)
==7817==    by 0x4B0774: xf86RotateCloseScreen (xf86Rotate.c:345)
==7817==    by 0x4A2311: xf86CrtcCloseScreen (xf86Crtc.c:745)
==7817==    by 0x4C093A: CursorCloseScreen (cursor.c:207)
==7817==    by 0x4F483B: AnimCurCloseScreen (animcur.c:106)
==7817==    by 0x4272EE: main (main.c:327)
==7817==  Address 0xb666df0 is 80 bytes inside a block of size 152 free'd
==7817==    at 0x4C268FE: free (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7817==    by 0x4F7655: damageDestroyWindow (damage.c:1741)
==7817==    by 0x7CB43D9: XvDestroyWindow (xvmain.c:439)
==7817==    by 0x489F32: xf86XVDestroyWindow (xf86xv.c:1153)
==7817==    by 0x45D5E3: FreeWindowResources (window.c:941)
==7817==    by 0x460347: DeleteWindow (window.c:1019)
==7817==    by 0x456F41: doFreeResource (resource.c:571)
==7817==    by 0x457C79: FreeClientResources (resource.c:853)
==7817==    by 0x457D26: FreeAllResources (resource.c:869)
==7817==    by 0x42726D: main (main.c:308)
==7817==

Doing the check around the whole damage handling workarounds both the
crash and the double free.

I ma not sure this is a very robust solution, though. I wonder if the
damage could be unregistered from the screen when it is destroyed.

Thanks

Michal
Index: xserver/hw/xfree86/modes/xf86Rotate.c
===================================================================
--- xserver.orig/hw/xfree86/modes/xf86Rotate.c	2011-10-11 13:24:11.000000000 +0200
+++ xserver/hw/xfree86/modes/xf86Rotate.c	2011-10-11 14:31:32.000000000 +0200
@@ -283,6 +283,7 @@
     ScrnInfoPtr		pScrn = crtc->scrn;
     ScreenPtr		pScreen = pScrn->pScreen;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    DrawablePtr screenDrawable = &pScreen->root->drawable;
     int			c;
     
     /* Free memory from rotation */
@@ -300,12 +301,12 @@
     /*
      * Clean up damage structures when no crtcs are rotated
      */
-    if (xf86_config->rotation_damage)
+    if (screenDrawable && xf86_config->rotation_damage)
     {
 	/* Free damage structure */
 	if (xf86_config->rotation_damage_registered)
 	{
-	    DamageUnregister (&pScreen->root->drawable,
+	    DamageUnregister (screenDrawable,
 			      xf86_config->rotation_damage);
 	    xf86_config->rotation_damage_registered = FALSE;
 	    DisableLimitedSchedulingLatency();
_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to