我目前正在调查我们实验室服务器上一个非常特殊的问题。每当我们在使用Citrix访问的64位SUSE SLES11安装的计算机上运行java程序时,它就会挂起。我在机器上有最新的更新,但它没有帮助。如果这些情况发生任何变化,它就可以工作:32位操作系统,SLES10.2,通过Cygwin / Exceed访问,其他X应用程序如xclock工作正常。
到目前为止,这可能看起来像是一个ServerFault问题,但我实际上正在寻找的是关于我可以用来追踪这个软件实际上在做什么的软件的建议。它挂起的位置是“FUTEX_WAIT”(使用strace找到):
futex(0x7f4e3eaab9e0, FUTEX_WAIT, 19686, NULL
光标刚好在NULL之后的跟踪中停止,并且只是无限期地停留在那里。我发现之前的bug report看起来与此问题有点类似,但情况非常不同。
更新:显然,futex_wait问题是内核/ libc锁定进程中奇怪的竞争条件的标志。我将不得不尝试使用更新的内核/ libc,看看是否有任何不同。
UPDATE2:内核/ libc更改没有任何区别。设法启动jvisualvm并挂起一个可预测的外部JMX端口并连接到另一台机器的端口,此时我在main的线程跟踪中找到了这个:
Name: main
State: RUNNABLE
Total blocked: 0 Total waited: 0
Stack trace:
sun.awt.X11GraphicsDevice.getDoubleBufferVisuals(Native Method)
sun.awt.X11GraphicsDevice.makeDefaultConfiguration(X11GraphicsDevice.java:208)
sun.awt.X11GraphicsDevice.getDefaultConfiguration(X11GraphicsDevice.java:182)
- locked java.lang.Object@1c190c99
sun.awt.X11.XToolkit.<clinit>(XToolkit.java:92)
java.lang.Class.forName0(Native Method)
java.lang.Class.forName(Class.java:169)
java.awt.Toolkit$2.run(Toolkit.java:834)
java.security.AccessController.doPrivileged(Native Method)
java.awt.Toolkit.getDefaultToolkit(Toolkit.java:826)
- locked java.lang.Class@308a1f38
org.openide.util.ImageUtilities.ensureLoaded(ImageUtilities.java:519)
org.openide.util.ImageUtilities.access$200(ImageUtilities.java:80)
org.openide.util.ImageUtilities$ToolTipImage.createNew(ImageUtilities.java:699)
org.openide.util.ImageUtilities.getIcon(ImageUtilities.java:487)
- locked java.util.HashMap@3c07ae6d
org.openide.util.ImageUtilities.getIcon(ImageUtilities.java:361)
- locked java.util.HashMap@1c4c94e5
org.openide.util.ImageUtilities.loadImage(ImageUtilities.java:139)
org.netbeans.core.startup.Splash.loadContent(Splash.java:262)
org.netbeans.core.startup.Splash$SplashComponent.<init>(Splash.java:344)
org.netbeans.core.startup.Splash.<init>(Splash.java:170)
org.netbeans.core.startup.Splash.getInstance(Splash.java:102)
org.netbeans.core.startup.Main.start(Main.java:301)
org.netbeans.core.startup.TopThreadGroup.run(TopThreadGroup.java:110)
java.lang.Thread.run(Thread.java:619)
尝试了jvisualvm中的死锁检测按钮,但发现没有死锁。
目前正在与Citrix Europe讨论此问题并向他们提供跟踪信息。如果问题得到解决,将更新此问题。
更新3:此问题已追溯到Citrix,并且已提交服务请求号为60235154.此问题似乎是Java中的某个位置或目前在X11的Citrix实现中。
答案 0 :(得分:2)
ltrace跟踪共享库函数调用。这可以为您提供更高层次的事物视图。但它也可以比strace输出更多的输出,因为许多库函数(例如strcmp)不会导致系统调用。
但是futex用于锁定,所以如果你陷入futex,你可能会陷入僵局。或者你只是在看一个等待其他线程的线程。 ltrace / strace -f跟随clone / fork跟踪所有线程/所有子进程。
在gdb中,有时thread apply all <command>
对多线程进程很有用。例如thread apply all bt
答案 1 :(得分:1)
您是否拥有Java程序的源代码?如果是这样,您可以使用Eclipse或其他IDE remotely debug。如果您没有源代码,那么您的选项会受到更多限制,但您可以尝试通过JConsole连接到该流程,以便深入了解正在发生的事情。 Java分析工具是另一种选择,但设置起来比较困难。
答案 2 :(得分:1)
也许jvisualvm,它来自Sun的Java,有你需要的东西。您可以在程序运行时记录虚拟机的状态,并告诉它将任何堆栈转储保存到以后可以打开和查看的文件中。在jdk的bin目录中查找jvisualvm。 在这里您可以看到更多文档: http://java.sun.com/javase/6/docs/technotes/tools/share/jvisualvm.html
祝你好运!答案 3 :(得分:0)
使用gdb附加到进程。 gdb并不完全直观,但网上有很多howtos和类似的东西。
http://dirac.org/linux/gdb/06-Debugging_A_Running_Process.php
答案 4 :(得分:0)
请参阅this solution我找到了。
在这种情况下,挂起是由/ dev / random中的随机字节生成缓慢引起的。
Java应用程序需要很长时间才能获得随机字节。
这不是一个真正的解决方案,而是一个workarround,因为/ dev / random将与/ dev / urandom相同。