Reputation:
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
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