scala JVM 远程调试会话因未捕获的异常而终止
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6027788/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JVM remote debugging session terminating on uncaught exception
提问by Michael
I'm attempting to debug a scala project remotely. Both the executing program (built and executed from SBT) and my debugger (Intellij) are local, but since I don't want to build using Intellij, using a remote debugging session seemed the easiest option for convenient debugging.
我正在尝试远程调试 Scala 项目。执行程序(从 SBT 构建和执行)和我的调试器 (Intellij) 都是本地的,但由于我不想使用 Intellij 构建,因此使用远程调试会话似乎是方便调试的最简单选择。
The program is started with the following options:
该程序以以下选项启动:
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
It's successfully suspending on launch, and I can successfully attach my debugger. I can set break points and step through the code, but the problem is that an uncaught exception terminates the debugging session and disconnects the debugger, defeating the purpose of debugging. This being the default behaviour would be asburd, so I have to be doing something wrong.
它在启动时成功挂起,我可以成功附加我的调试器。我可以设置断点并逐步执行代码,但问题是未捕获的异常会终止调试会话并断开调试器的连接,从而破坏了调试的目的。这是默认行为将是 asburd,所以我必须做错什么。
Intellij's Console reads:
Intellij 的控制台显示:
Connected to the target VM, address: 'localhost:5005', transport: 'socket'
Disconnected from the target VM, address: 'localhost:5005', transport: 'socket'
Is there something I'm missing on either the execution or debugging side of things?
我在执行或调试方面有什么遗漏吗?
Edit: adding a stack trace where I'm throwing new Exception("what") in the main of my class:
编辑:添加一个堆栈跟踪,我在我的类的主体中抛出新的异常(“什么”):
[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.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)
回答by Aaron Novstrup
If the exception is never caught, it will cause your application to close and the JVM to terminate, which obviously ends the debugging session.
如果异常从未被捕获,它将导致您的应用程序关闭并终止 JVM,这显然会结束调试会话。
You can add an exception breakpoint so that the debugger will suspend execution as soon as the exception is thrown. Click on the "View Breakpoints" button in the debug toolbar, then see the "Exception Breakpoints" tab. It helps to know what type of exception you're looking for so that you can set the exception breakpoint for that specific type; you should be able to find the appropriate type by examining your stacktrace. Otherwise, you'll end up suspending on lots of unrelated exceptions. If you know which thread the exception occurs on, it can also be helpful to limit the exception breakpoint to that thread.
您可以添加异常断点,以便调试器在抛出异常时立即挂起执行。单击调试工具栏中的“查看断点”按钮,然后查看“异常断点”选项卡。它有助于了解您正在寻找的异常类型,以便您可以为该特定类型设置异常断点;您应该能够通过检查堆栈跟踪找到合适的类型。否则,您最终会因许多不相关的异常而暂停。如果您知道异常发生在哪个线程上,将异常断点限制在该线程上也很有帮助。
Note that both SBT (if you're not forking a separate VM) and Scala's runner (if you areforking) catch all exceptions thrown in client code. Therefore, there will be no "uncaught exceptions", and you will need to suspend on "caught exceptions".
注意,这两个SBT(如果你不分叉独立的VM)和Scala的亚军(如果你是分叉)赶上客户端代码抛出的所有异常。因此,不会有“未捕获的异常”,您将需要暂停“捕获的异常”。
回答by Paul Whelan
Before I begin I have not coded any scala, but this may help you can catch uncaught exceptions in java see the method Thread.UncaughtExceptionHandler
在开始之前,我没有编写任何 Scala 代码,但这可能有助于您在 Java 中捕获未捕获的异常,请参阅方法Thread.UncaughtExceptionHandler
When a thread is about to terminate due to an uncaught exception the Java Virtual Machine will query the thread for its UncaughtExceptionHandler using Thread.getUncaughtExceptionHandler() and will invoke the handler's uncaughtException method, passing the thread and the exception as arguments. If a thread has not had its UncaughtExceptionHandler explicitly set, then its ThreadGroup object acts as its UncaughtExceptionHandler. If the ThreadGroup object has no special requirements for dealing with the exception, it can forward the invocation to the default uncaught exception handler.
当线程因未捕获的异常而即将终止时,Java 虚拟机将使用 Thread.getUncaughtExceptionHandler() 查询该线程的 UncaughtExceptionHandler,并将调用处理程序的 uncaughtException 方法,将线程和异常作为参数传递。如果一个线程没有显式设置它的 UncaughtExceptionHandler,那么它的 ThreadGroup 对象作为它的 UncaughtExceptionHandler。如果 ThreadGroup 对象对处理异常没有特殊要求,它可以将调用转发到默认的未捕获异常处理程序。
I guess you can log the Exception and it may give you an insight to the problem.
我想您可以记录异常,它可能会让您深入了解问题。
EDIT:This also assumes you can redeploy a new project which may not be the case.
编辑:这也假设您可以重新部署一个新项目,但情况可能并非如此。

