> 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