United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6326131 REG: App freezes when moving a window from one screen to another on virtual screen config, WinXP
JDK-6326131 : REG: App freezes when moving a window from one screen to another on virtual screen config, WinXP

Details
Type:
Bug
Submit Date:
2005-09-20
Status:
Closed
Updated Date:
2011-01-19
Project Name:
JDK
Resolved Date:
2005-10-22
Component:
client-libs
OS:
windows_xp
Sub-Component:
java.awt
CPU:
x86
Priority:
P2
Resolution:
Fixed
Affected Versions:
5.0,5.0u16,6
Fixed Versions:

Related Reports
Backport:
Backport:
Backport:
Duplicate:
Relates:

Sub Tasks

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

Please provide a stack trace of the hang if possible (Ctrl+Break).
                                     
2005-09-20
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.
                                     
2005-09-21
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.
                                     
2005-09-22
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.
                                     
2005-09-22
EVALUATION

I've updated the test, and reassigned the bug to awt folks.
                                     
2005-09-22
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();
      }
                                     
2005-09-23
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.
                                     
2005-09-23
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.
                                     
2005-09-23
EVALUATION

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



Hardware and Software, Engineered to Work Together