JDK-6326131 : REG: App freezes when moving a window from one screen to another on virtual screen config, WinXP
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 5.0,5.0u16,6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2005-09-20
  • Updated: 2011-01-19
  • Resolved: 2005-10-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other Other Other JDK 6
5.0u16-crevFixed 5.0u17-crevFixed 5.0u29Fixed 6 b58Fixed
Related Reports
Duplicate :  
Relates :  
Description
Test background:
----------------
I am running an application that opens up a Frame/Dialog/Window in which a volatile image is rendered. I am running this app on a multi-monitor (2 monitors) virtual screen WinXP configuration. This frame is initially created on one of the screens and then moved to another screen after it is made visible. Actually this test expects the volatile image to get invalidated and re-created (IMAGE_INCOMPATIBLE) when it is moved from one GD to the other. 

Behavior Seen:
--------------
Application is moved by calling setLocation() repeatedly with increasing or decreasing x,y value depending on the virtual config being horizontal or vertical. On Mustang-b51+, the frame stays in-between the two screens and it freezes. I don't see any IMAGE_INCOMPATIBLE being returned when the VImage is validated. 

This is noticed only on Mustang-b51 and I am not able to reproduce it on b50. This is seen only on WinXP (Platform Info is given under Comments section) and passes on Linux + Xinerama. Hence looks like this is a regression introduced in b51.

I have attached a sample test and couple of other supporting files, images. Please run the test on the primary screen as follows:
java MoveWindowVirtualScreenTest

This will show an undecorated frame on the sec screen and will move it to the primary. Check the renderings are proper. If you see frame getting stuck in-between the 2 monitors, the bug is reproduced. Also check whether 'IMAGE_INCOMPATIBLE' message is shown on the console.
(This test will loop through all the GCs for each GD, all the GDs, Window, Frame (decorated/undecorated) and Dialog top levels). This occurs intermittently. I reproduced it 7 times out of 10 trials. So run the app a few times if you don't see it the first time.
Here is the thread dump at the time of hang:
--------------------------------------------

Full thread dump Java HotSpot(TM) Client VM (1.6.0-ea-b52 mixed mode):

"AWT-EventQueue-0" prio=7 tid=0x0ad29500 nid=0xe10 waiting for monitor entry [0x0be8f000..0x0be8fd14]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at java.awt.Component.setGCFromPeer(Component.java:948)
        - waiting to lock <0x02e3cbc0> (a java.awt.Component$AWTTreeLock)
        at java.awt.Window.resetGC(Window.java:2532)
        at sun.awt.windows.WWindowPeer.resetTargetGC(Native Method)
        at sun.awt.windows.WCanvasPeer.displayChanged(WCanvasPeer.java:48)
        at sun.awt.windows.WPanelPeer.displayChanged(WPanelPeer.java:142)
        at sun.awt.windows.WWindowPeer.displayChanged(WWindowPeer.java:292)
        at sun.awt.windows.WWindowPeer$1.run(WWindowPeer.java:235)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

"AWT-Shutdown" prio=5 tid=0x0adcad00 nid=0xba0 in Object.wait() [0x0bd1f000..0x0bd1fd94]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x02e385e8> (a java.lang.Object)
        at java.lang.Object.wait(Object.java:484)
        at sun.awt.AWTAutoShutdown.run(AWTAutoShutdown.java:259)
        - locked <0x02e385e8> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:611)

"AWT-Windows" daemon prio=7 tid=0x0ad29900 nid=0xa3c runnable [0x0bb1f000..0x0bb1fa94]
   java.lang.Thread.State: RUNNABLE
        at sun.awt.windows.WToolkit.eventLoop(Native Method)
        at sun.awt.windows.WToolkit.run(WToolkit.java:290)
        at java.lang.Thread.run(Thread.java:611)

"Java2D Disposer" daemon prio=10 tid=0x0ad22800 nid=0x33c in Object.wait() [0x0ba9f000..0x0ba9fb94]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x02e38678> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
        - locked <0x02e38678> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
        at sun.java2d.Disposer.run(Disposer.java:123)
        at java.lang.Thread.run(Thread.java:611)

"Low Memory Detector" daemon prio=5 tid=0x0aac9300 nid=0xc64 runnable [0x00000000..0x00000000]
   java.lang.Thread.State: RUNNABLE

"CompilerThread0" daemon prio=10 tid=0x0aac6d00 nid=0x814 waiting on condition [0x00000000..0x0ac4f740]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" daemon prio=10 tid=0x0aac5e00 nid=0x228 runnable [0x00000000..0x00000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x0aac5300 nid=0x2c8 waiting on condition [0x00000000..0x00000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=9 tid=0x0aab9000 nid=0xbf4 in Object.wait() [0x0ab8f000..0x0ab8fa94]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x02e388a8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
        - locked <0x02e388a8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=10 tid=0x0aab4f00 nid=0xd20 in Object.wait() [0x0ab4f000..0x0ab4fb14]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x02e38930> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:484)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
        - locked <0x02e38930> (a java.lang.ref.Reference$Lock)

"main" prio=5 tid=0x00036f00 nid=0x7f0 runnable [0x0007f000..0x0007fc34]
   java.lang.Thread.State: RUNNABLE
        at sun.awt.windows.WComponentPeer.reshape(Native Method)
        - locked <0x02fc1920> (a sun.awt.windows.WFramePeer)
        at sun.awt.windows.WFramePeer.reshape(WFramePeer.java:51)
        at sun.awt.windows.WComponentPeer.setBounds(WComponentPeer.java:129)
        at java.awt.Component.reshapeNativePeer(Component.java:2042)
        at java.awt.Component.reshape(Component.java:1990)
        - locked <0x02e3cbc0> (a java.awt.Component$AWTTreeLock)
        at java.awt.Window.reshape(Window.java:657)
        at java.awt.Component.setBounds(Component.java:1956)
        at java.awt.Window.setBounds(Window.java:2821)
        - locked <0x02e3cbc0> (a java.awt.Component$AWTTreeLock)
        at java.awt.Component.move(Component.java:1825)
        - locked <0x02e3cbc0> (a java.awt.Component$AWTTreeLock)
        at java.awt.Component.setLocation(Component.java:1814)
        at MoveWindowVirtualScreenTest.moveWindow(MoveWindowVirtualScreenTest.java:207)
        at MoveWindowVirtualScreenTest.createWindow(MoveWindowVirtualScreenTest.java:145)
        at MoveWindowVirtualScreenTest.<init>(MoveWindowVirtualScreenTest.java:50)
        at MoveWindowVirtualScreenTest.main(MoveWindowVirtualScreenTest.java:68)

"VM Thread" prio=10 tid=0x0aab0900 nid=0xb1c runnable

"VM Periodic Task Thread" prio=10 tid=0x0aaca600 nid=0x900 waiting on condition

JNI global references: 799

Comments
EVALUATION After the fix for 6480378 integrated into JDK 5u13, the fix for this issue should be also backported to 5.0 update release.
04-07-2007

SUGGESTED FIX The fix above really fixes the problem but it can be improved much. In fact, there is no need in native method at all, and the native critical section can be eliminated.
23-09-2005

EVALUATION The deadlock is really between two threads: EDT and main. One lock is AWT TreeLock, another one is native critical section used to synchronize all the calls to native objects from Java. In more detail: when the window is moved to another screen, WWindowPeer.displayChanged() is called on EDT. Then it resets its target's GC by calling to native method resetTargetGC. This native method enters the critical section and then calls to Component.setGCFromPeer which requires treeLock. Another thread, main thread, in the same time moves the window by Component.setLocation() which acquires treeLock and calls to WComponentPeer.reshape(). That methos is also native and it tries to enter the critical section and hangs. As all the GC changes in AWT shared code is done under the treeLock, we should add the same synchronization to the peer code that deals with GC. See suggested fix for details.
23-09-2005

SUGGESTED FIX --- WCanvasPeer.java Fri Sep 23 13:37:17 2005 *************** *** 44,51 **** * Up-called for other windows peer instances (WPanelPeer, WWindowPeer). */ public void displayChanged() { ! clearLocalGC(); ! resetTargetGC(); super.displayChanged(); } --- 44,53 ---- * Up-called for other windows peer instances (WPanelPeer, WWindowPeer). */ public void displayChanged() { ! synchronized (((Component)target).getTreeLock()) { ! clearLocalGC(); ! resetTargetGC(); ! } super.displayChanged(); }
23-09-2005

EVALUATION I've updated the test, and reassigned the bug to awt folks.
22-09-2005

EVALUATION After I've stripped the test from 2D-related code I was able to determine that this is not a regression since b51, since I can reproduce it on b50 and earlier builds, but the hang is with a little different stack trace, when a new window is about to be created: "main" prio=5 tid=0x00037200 nid=0x1e0 runnable [0x0007f000..0x0007fc24] java.lang.Thread.State: RUNNABLE at sun.awt.windows.WComponentPeer.endValidate(Native Method) at java.awt.Container.validate(Container.java:1445) - locked <0x02e51348> (a java.awt.Component$AWTTreeLock) at MoveWindowVirtualScreenTest.createWindow(MoveWindowVirtualScreenTest.java:102) at MoveWindowVirtualScreenTest.<init>(MoveWindowVirtualScreenTest.java:40) at MoveWindowVirtualScreenTest.main(MoveWindowVirtualScreenTest.java:46) "AWT-EventQueue-0" prio=7 tid=0x0aa67900 nid=0x698 waiting for monitor entry [0x0cd0f000..0x0cd0fb94] java.lang.Thread.State: BLOCKED (on object monitor) at java.awt.Component.setGCFromPeer(Component.java:948) - waiting to lock <0x02e51348> (a java.awt.Component$AWTTreeLock) at java.awt.Window.resetGC(Window.java:2421) at sun.awt.windows.WWindowPeer.resetTargetGC(Native Method) at sun.awt.windows.WCanvasPeer.displayChanged(WCanvasPeer.java:48) at sun.awt.windows.WPanelPeer.displayChanged(WPanelPeer.java:142) at sun.awt.windows.WWindowPeer.displayChanged(WWindowPeer.java:273) at sun.awt.windows.WWindowPeer$1.run(WWindowPeer.java:216) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) After the awt integration on 09/07/05 the test hangs more readily with the window spanning across the screens. This hang originally reported by this bug is likely to be caused by this fix in awt integration: 5025858: Resizing a decorated frame triggers componentResized event twice Webrev : http://sa.sfbay.sun.com/projects/awt_data/mustang/5025858/ It appears that the main thread attempts to execute stuff on EDT (which is waiting for the treelock) while holding a treelock itself, thus a deadlock. Prior to the fix for 5025858 we only attempted to do this if the window was resized. But now we do this even if he size didn't change - thus the chances for the deadlock are increased, which is the reason the test runs into this deadlock more easily now.
22-09-2005

EVALUATION After I modified the test to remove all of the 2d-related stuff I was able to reproduce the deadlock easily. I'll polish the test a bit more and attach it to the bugreport.
22-09-2005

EVALUATION I've tried the test on two different systems (with two nvidia boards, and another with nvidia and ati rage 128 pro), but I can't reproduce the bug. Could the submitter please try to reproduce it on any other system? (or ask sqe folks here in SCA to do it) Looking at the stack trace it appears to be a deadlock between the EventDispatchThread (which is waiting for the treelock) and the main thread. So it may explain why I can't easily reproduce it. This seems to be AWT problem. The test could probably be minimized not to have any 2D-related things, just move the window back and forth. Since the bug is not readily reproducible I'm changing the priority to P3.
21-09-2005

EVALUATION Please provide a stack trace of the hang if possible (Ctrl+Break).
20-09-2005