【问题标题】:JVM remote debugging session terminating on uncaught exceptionJVM 远程调试会话因未捕获的异常而终止
【发布时间】:2011-05-17 07:47:05
【问题描述】:

我正在尝试远程调试 Scala 项目。执行程序(从 SBT 构建和执行)和我的调试器 (Intellij) 都是本地的,但由于我不想使用 Intellij 构建,因此使用远程调试会话似乎是方便调试的最简单选择。

程序使用以下选项启动:

-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005

它在启动时成功挂起,我可以成功附加我的调试器。我可以设置断点并单步执行代码,但问题是未捕获的异常会终止调试会话并断开调试器,从而破坏了调试的目的。这是默认行为是不正确的,所以我必须做错事。

Intellij 的控制台显示:

Connected to the target VM, address: 'localhost:5005', transport: 'socket'
Disconnected from the target VM, address: 'localhost:5005', transport: 'socket'

在执行或调试方面我缺少什么吗?

编辑:添加一个堆栈跟踪,我在我的类主中抛出新异常(“what”):

[error] java.lang.Exception: what
[error]     at travellr.application.prophet.Prophet$.main(Prophet.scala:80)
[error]     at travellr.application.prophet.Prophet.main(Prophet.scala)
[error]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error]     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[error]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[error]     at java.lang.reflect.Method.invoke(Method.java:597)
[error]     at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:81)
[error]     at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
[error]     at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:86)
[error]     at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:81)
[error]     at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:86)
[error]     at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:83)
[error]     at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

【问题讨论】:

  • 供将来参考:由于这不是 scala 特定的,您可能会通过添加“java”标签获得更快的响应。
  • 我意识到,我只是将 scala 包括在内,因为它是一个非常直接的问题,我想也许与 Scala/SBT 相关的某些东西把我搞砸了。

标签: java debugging scala jvm intellij-idea


【解决方案1】:

如果从未捕获到异常,它将导致您的应用程序关闭并且 JVM 终止,这显然会结束调试会话。

您可以添加一个异常断点,以便调试器在抛出异常后立即暂停执行。单击调试工具栏中的“查看断点”按钮,然后查看“异常断点”选项卡。它有助于了解您正在寻找哪种类型的异常,以便您可以为该特定类型设置异常断点;您应该能够通过检查堆栈跟踪找到合适的类型。否则,您最终将暂停许多不相关的异常。如果您知道异常发生在哪个线程上,那么将异常断点限制在该线程上也会很有帮助。

请注意,SBT(如果您不分叉单独的 VM)和 Scala 的运行程序(如果您正在分叉)都会捕获客户端代码中引发的所有异常。因此,不会有“未捕获的异常”,您需要暂停“捕获的异常”。

【讨论】:

  • 我刚刚勾选了“任何异常”、“通知”->“未捕获异常”和“暂停策略”->“全部”,但它仍在终止。我在cl.ly/2Q1p3C1d1k100J1e0y1j 中包含了我的断点窗口的屏幕截图
  • 问题是 SBT 正在捕获您的异常,因此它不是“未捕获的异常”。由于 SBT 默认情况下在同一个 VM 中运行您的程序,因此它会捕获任何未捕获的异常以防止它们终止 SBT 进程。勾选“捕获异常”框,您应该一切顺利。
  • 我讨厌成为一个有过于具体问题的烦人的家伙,但我正在分叉(执行中没有 SBT 的痕迹)。跟踪跟踪的底层是 scala.tools.nsc.MainGenericRunner.main()。我已将堆栈跟踪添加到问题中。
  • 您是否尝试暂停“捕获异常”?在我看来,MainGenericRunner 也能捕获异常。
  • 捕获的异常在技术上是有效的,但这就像大海捞针,而我还不知道针(用于测试)。 MainGenericRunner 似乎只从 2.8.1 源中捕获“ClassNotFound/NoSuchMethodException/InvocationTargetException”(我已经浏览了整个堆栈跟踪,找不到任何会吞下异常的东西)-> lampsvn.epfl.ch/svn-repos/scala/scala/tags/R_2_8_1_final/src/…
【解决方案2】:

在我开始之前,我没有编写任何 scala,但这可能有助于您在 java 中捕获未捕获的异常,请参阅方法 Thread.UncaughtExceptionHandler

当一个线程即将终止时 由于未捕获的异常,Java 虚拟机将查询线程 为其 UncaughtExceptionHandler 使用 Thread.getUncaughtExceptionHandler() 并将调用处理程序的 uncaughtException 方法,传递 线程和异常作为参数。 如果一个线程还没有它的 UncaughtExceptionHandler 显式 设置,然后它的 ThreadGroup 对象动作 作为它的 UncaughtExceptionHandler。如果 ThreadGroup 对象没有特殊的 处理的要求 例外,它可以转发 调用默认未捕获 异常处理程序。

我想您可以记录异常,它可以让您深入了解问题。

编辑:这还假设您可以重新部署一个新项目,但情况可能并非如此。

【讨论】:

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