Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JVM remote debugging session terminating on uncaught exception

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.

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.

Intellij's Console reads:

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$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)
like image 205
Michael Avatar asked May 17 '11 07:05

Michael


2 Answers

If the exception is never caught, it will cause your application to close and the JVM to terminate, which obviously ends the debugging session.

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 are forking) catch all exceptions thrown in client code. Therefore, there will be no "uncaught exceptions", and you will need to suspend on "caught exceptions".

like image 123
Aaron Novstrup Avatar answered Oct 12 '22 22:10

Aaron Novstrup


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

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.

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.

like image 36
Paul Whelan Avatar answered Oct 12 '22 22:10

Paul Whelan