user972946
user972946

Reputation:

Eclipse hangs forever, thread dump says Main thread is sleeping

I am running Eclipse 3.7.2 in Solaris 11 X86. It hangs randomly (every few hours or every few minutes). When it hangs, I do a thread dump and it suggests that Main thread is in timed wait state. Eclipse never wakes up from the sleep state and becomes unresponsive, I have to restart Eclipse to use it again.

Main thread is sleeping because of:

org.eclipse.swt.widgets.Control.dragDetect

Is there any known fix to this issue?

Edit:

OS

SunOS solaris 5.11 11.0 i86pc i386 i86pc Solaris

Full stack trace:

"main" prio=3 tid=0x080e8400 nid=0x1 waiting on condition [0x08045000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at org.eclipse.swt.widgets.Control.dragDetect(Control.java:2204)
    at org.eclipse.swt.widgets.Tree.dragDetect(Tree.java:1125)
    at org.eclipse.swt.widgets.Control.gtk_button_press_event(Control.java:2791)
    at org.eclipse.swt.widgets.Control.gtk_button_press_event(Control.java:2759)
    at org.eclipse.swt.widgets.Composite.gtk_button_press_event(Composite.java:681)
    at org.eclipse.swt.widgets.Tree.gtk_button_press_event(Tree.java:1871)
    at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1731)
    at org.eclipse.swt.widgets.Control.windowProc(Control.java:5016)
    at org.eclipse.swt.widgets.Tree.windowProc(Tree.java:3530)
    at org.eclipse.swt.widgets.Display.windowProc(Display.java:4408)
    at org.eclipse.swt.internal.gtk.OS._gtk_main_do_event(Native Method)
    at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(OS.java:8422)
    at org.eclipse.swt.widgets.Display.eventProc(Display.java:1245)
    at org.eclipse.swt.internal.gtk.OS._g_main_context_iteration(Native Method)
    at org.eclipse.swt.internal.gtk.OS.g_main_context_iteration(OS.java:2276)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3207)
    at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
    at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1410)

   Locked ownable synchronizers:
    - None

"VM Thread" prio=3 tid=0x08209c00 nid=0x2 runnable 

"VM Periodic Task Thread" prio=3 tid=0x0825d000 nid=0x8 waiting on condition 

JNI global references: 713

Upvotes: 5

Views: 1297

Answers (1)

Mikael Gueck
Mikael Gueck

Reputation: 5591

Is it possible that your system clock is jumping around?

Eclipse's event loop uses System.currentTimeMillis() to keep track of time, and currentTimeMillis isn't guaranteed to be monotonic (unlike System.nanoTime() would have been.)

long timeout = System.currentTimeMillis() + 500;
while (System.currentTimeMillis() < timeout) {
    eventPtr = OS.gdk_event_get ();
    if (eventPtr != 0) {
        break;
    } else {
        try {Thread.sleep(50);} catch (Exception ex) {}
    }
}

If so, as a workaround you requested at " Is there a way to interrupt a sleeping thread in a running JVM, without having access to the application's code? ", you can easily use JBoss Byteman to create a rule set, which bails from the sleep loop after a set number of sleeps.

Foo.java:

public class Foo {

    public void test1() {
        long timeout = System.currentTimeMillis() + 500;
        int i = 0;
        while (System.currentTimeMillis() < timeout) {
            System.out.println(i++);
            try {Thread.sleep(50);} catch (Exception ex) {}
        }
    }


    public static void main(final String ... args) throws Exception {
        new Foo().test1();
    }

}

sleeper.btm:

RULE counter
CLASS Foo
METHOD test1
AT ENTRY
IF TRUE
DO createCountDown($0, 5)
ENDRULE

RULE sleeper
CLASS Foo
METHOD test1
AT INVOKE Thread.sleep()
IF countDown($0)
DO RETURN
ENDRULE

Run with Byteman script:

$ ~/Downloads/byteman-download-2.1.0/bin/bmjava.sh -l ./sleeper.btm Foo
0
1
2
3
4
5

Run normally:

$ java Foo 
0
1
2
3
4
5
6
7
8
9

Upvotes: 1

Related Questions