While we do need to get to the root cause, the extra sanity checking in here is good.
Reviewed-by: Jeremy Huddleston <jerem...@apple.com> On Oct 11, 2011, at 5:38 AM, Michal Suchanek wrote: >> 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 > <workaround-crash-on-close.patch>_______________________________________________ > 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 _______________________________________________ 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