代码之家  ›  专栏  ›  技术社区  ›  Stefan Sveidqvist

流程执行跟踪工具

  •  2
  • Stefan Sveidqvist  · 技术社区  · 16 年前

    我目前正在调查我们实验室服务器上的一个非常特殊的问题。每当我们在一个机器上运行一个Java程序,它有一个用Citrix访问的64位SUSESLES11安装,它只是挂起。我有这台机器的最新更新,但没用。如果这些情况中的任何一个发生变化,它就会工作:32位操作系统、SLES10.2、通过cygwin/exceed访问以及其他X应用程序(如xclock)工作正常。

    到目前为止,这可能看起来像是一个服务器故障问题,但我实际上在寻找关于软件的建议,我可以使用这些建议来跟踪这个软件实际上在做什么。它挂在“futex_wait”上(通过使用 strace ):

    futex(0x7f4e3eaab9e0, FUTEX_WAIT, 19686, NULL
    

    光标仅在空值之后停止在跟踪中,并无限期地停留在跟踪中。我找到了以前的 bug report 这看起来有点类似于这个问题,但是情况是非常不同的。

    更新:显然,futex-wait问题是内核/libc锁定进程中异常竞争条件的信号。我将不得不尝试使用一个更新的内核/libc,看看这两者是否有任何区别。

    update2:内核/libc的更改没有区别。成功地启动了jvisualvm并用一个可预测的外部JMX端口挂起它,并从另一台机器连接到它,此时我在主线程跟踪中发现了这一点:

    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欧洲公司讨论这个问题,并向他们提供线索。如果问题得到解决,将更新此问题。

    更新3:此问题已跟踪到Citrix,并已与服务请求编号60235154一起提交。问题似乎是Java中的某个地方,或者是目前X11的Citrix实现。

    5 回复  |  直到 13 年前
        1
  •  2
  •   Peter Cordes    16 年前

    LTrace跟踪共享库函数调用。这可以给你一个更高层次的观点。但由于许多库函数(例如strcmp)不会导致系统调用,因此它的输出也比strace多。

    但是futex是用来锁定的,所以如果你在futex被卡住了,你可能会陷入死锁。或者你只是在看一个等待其他线程的线程。ltrace/strace-f跟随clone/fork跟踪所有线程/所有子进程。

    在GDB中,有时 thread apply all <command> 对于多线程进程很有用。例如 thread apply all bt

        2
  •  1
  •   Rob H    16 年前

    你有Java程序的源代码吗?如果是这样,你可以 remotely debug 它使用Eclipse或其他IDE。如果您没有源代码,您的选项就更为有限,但是您可以尝试通过 JConsole 了解正在发生的事情。Java剖析工具是另一种选择,但更难设置。

        3
  •  1
  •   mring    16 年前

    也许JSuvalvm,来自Sun的Java,有你需要的东西。您可以在程序运行时记录虚拟机的状态,还可以告诉它将任何堆栈转储保存到以后可以打开并查看的文件中。在JDK的bin目录中查找jvisualvm。 在这里您可以看到更多文档: http://java.sun.com/javase/6/docs/technotes/tools/share/jvisualvm.html

    祝你好运!

        4
  •  0
  •   Gunther Piez    16 年前

    使用gdb附加到进程。gdb并不完全是直观的,但是在网络上有很多howto和类似的东西。

    http://dirac.org/linux/gdb/06-Debugging_A_Running_Process.php

        5
  •  0
  •   TTT    13 年前

    this solution 我找到了。

    在这种情况下,挂起是由/dev/random缓慢生成随机字节引起的。

    Java应用程序等待很长时间才能获得随机字节。

    这不是真正的解决方案,而是一个解决方案,因为/dev/random将与/dev/urandom相同。