【问题标题】:Java Debugger: Is it possible selectively suspend threads?Java 调试器:是否可以选择性地挂起线程?
【发布时间】:2014-10-01 08:35:36
【问题描述】:

在我过去作为 C/C++ 程序员的生活中,可以在某些平台和调试器组合上选择性地挂起线程。在遇到断点后,可以发出命令(或单击 GUI 中的内容)来对线程进行冰/除冰(挂起/唤醒)。在进一步的 step/next/run/continue 命令中,挂起的线程不会执行任何指令。

现在任何 JVM 或 Java IDE 都可以做到这一点吗?我使用 IntelliJ,但没有看到该功能,也无法通过 Google 找到任何信息。

澄清一下:

  1. 我不是在询问断点的线程策略,例如,暂停当前线程或所有线程。我知道 JVM 调试器功能。
  2. 开发环境很普通:我使用 IntelliJ Java IDE,并且可以访问相关源代码。

最后,我意识到“Java 调试器”是一个有点模糊的术语。 AFAIK,Sun 发布了调试器用来与 JVM 通信的在线调试格式。也许每个 JVM(IBM vs Sun vs IcedTea vs ???)都支持不同的调试功能,但我只熟悉 Sun/Oracle JVM。

【问题讨论】:

  • 嗨,kevin,您是否可以控制正在运行的代码,这只是一个特定点吗?因为如果您准备修改代码,您可以使用boolean threadSuspendedif (!threadSuspended) 模式,并在调试器中手动设置该布尔值。抱歉,我找不到更好的答案。
  • 关于弃用程序化挂起/恢复的一些相关讨论在这里:docs.oracle.com/javase/8/docs/technotes/guides/concurrency/…
  • Eclipse 有一个称为条件断点的功能,其中一些任意 java 代码在到达断点时和挂起当前线程之前被评估。所以你可以在那里执行一些额外挂起其他线程的代码。不知道 IntelliJ 有没有类似的功能。
  • 也许这是不可能的。我假设 JVM 在所有支持它的平台上都使用 pthread。如果是这样,请参阅:stackoverflow.com/a/9408451/257299
  • @vikingsteve:这是一个很好的解决方法。我建议你添加一个单独的答案。

标签: java debugging intellij-idea jvm


【解决方案1】:

您绝对可以在 jdb 中挂起单个线程(见下文)。我喜欢 IntelliJ 作为 Java 编辑器。另一方面,它的调试器并不糟糕,但很接近。

Initializing jdb ...
> run
Nothing suspended.
> threads
Group system:
  (java.lang.ref.Reference$ReferenceHandler)0x141 Reference Handler cond. waiting
  (java.lang.ref.Finalizer$FinalizerThread)0x140  Finalizer         cond. waiting
  (java.lang.Thread)0x13f                         Signal Dispatcher running
  (java.lang.Thread)0x401                         Java2D Disposer   cond. waiting
  (java.lang.Thread)0x804                         TimerQueue        cond. waiting
Group main:
  (java.lang.Thread)0x322                         AWT-AppKit        running
  (java.lang.Thread)0x323                         AWT-Shutdown      cond. waiting
  (java.awt.EventDispatchThread)0x5ec             AWT-EventQueue-0  cond. waiting
  (java.util.TimerThread)0x750                    Timer-0           cond. waiting
  (java.lang.Thread)0x7fd                         DestroyJavaVM     running
> suspend 0x5ec             
> threads
Group system:
  (java.lang.ref.Reference$ReferenceHandler)0x141 Reference Handler cond. waiting
  (java.lang.ref.Finalizer$FinalizerThread)0x140  Finalizer         cond. waiting
  (java.lang.Thread)0x13f                         Signal Dispatcher running
  (java.lang.Thread)0x401                         Java2D Disposer   cond. waiting
  (java.lang.Thread)0x804                         TimerQueue        cond. waiting
Group main:
  (java.lang.Thread)0x322                         AWT-AppKit        running
  (java.lang.Thread)0x323                         AWT-Shutdown      cond. waiting
  (java.awt.EventDispatchThread)0x5ec             AWT-EventQueue-0  waiting in a monitor
  (java.util.TimerThread)0x750                    Timer-0           cond. waiting
  (java.lang.Thread)0x7fd                         DestroyJavaVM     running
> where 0x5ec
  [1] java.lang.Object.wait (native method)
  [2] java.lang.Object.wait (Object.java:485)
  [3] java.awt.EventQueue.getNextEvent (EventQueue.java:558)
  [4] java.awt.EventDispatchThread.pumpOneEventForFilters (EventDispatchThread.java:263)
  [5] java.awt.EventDispatchThread.pumpEventsForFilter (EventDispatchThread.java:211)
  [6] java.awt.EventDispatchThread.pumpEventsForHierarchy (EventDispatchThread.java:201)
  [7] java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:196)
  [8] java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:188)
  [9] java.awt.EventDispatchThread.run (EventDispatchThread.java:122)
AWT-EventQueue-0[1] where 0x322
Current thread isn't suspended.
AWT-AppKit[1] resume 0x5ec
AWT-AppKit[1] where 0x5ec
Current thread isn't suspended.
AWT-EventQueue-0[1]

【讨论】:

  • 我的脑袋几乎要爆炸了。绝妙资料!这个答案的关键:它证明了 JVM 调试线协议支持这个特性。现在向 JetBrains 提交请求...
  • 读者:请在此处支持 IntelliJ 功能请求:youtrack.jetbrains.com/issue/IDEA-79921
【解决方案2】:

IntelliJ IDEA 现在拥有它(我正在查看 v15)。 Debug 窗口有一个 Threads 面板,允许暂停和恢复任何线程。

https://www.jetbrains.com/idea/help/debug-tool-window-threads.html

【讨论】:

    【解决方案3】:

    Eclipse 至少可以在 Oracle VM 上做到这一点,但我想这对所有这些都是可能的。尝试在调试器中选择一个线程(应该有一个包含所有正在运行的线程的视图)。那么挂起按钮应该只挂起这个线程而不是所有线程。

    【讨论】:

      【解决方案4】:

      您是否可以控制正在运行的代码,这只是一个特定点吗?

      如果您准备修改代码,您可以使用布尔值 threadSuspendedif (!threadSuspended) 模式,并在调试器中手动设置该布尔值。

      这是一个实用的解决方法 - 不完全是您所追求的功能,但它可能会完成这项工作;)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-19
        • 1970-01-01
        • 2011-04-05
        相关资源
        最近更新 更多