JVM remote debugging session terminating on uncaught exception

16,222

Solution 1

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".

Solution 2

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.

Share:
16,222
Michael
Author by

Michael

Updated on June 29, 2022

Comments

  • Michael
    Michael almost 2 years

    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)
    
  • Michael
    Michael almost 13 years
    I just ticked "Any Exception", "Notifications" -> "Uncaught Exception" and "Suspend Policty" -> "All", but it's still terminating. I've included a screenshot of my breakpoints window at cl.ly/2Q1p3C1d1k100J1e0y1j
  • Aaron Novstrup
    Aaron Novstrup almost 13 years
    The problem is that SBT is catching your exception, so it's not an "uncaught exception". Since SBT, by default, runs your program in the same VM, it catches any uncaught exceptions to prevent them from terminating the SBT process. Tick the "Caught exception" box, and you should be good to go.
  • Michael
    Michael almost 13 years
    I hate being difficult annoying guy with an overly specific problem, but I'm forking (there's no trace of SBT in the execution). The bottom level of the track trace is scala.tools.nsc.MainGenericRunner.main(). I've added my stack trace to the question.
  • Aaron Novstrup
    Aaron Novstrup almost 13 years
    Did you try suspending on "Caught exception"? It looks to me like the MainGenericRunner also catches exceptions.
  • Michael
    Michael almost 13 years
    Caught exception works technically, but it's like trying to find a needle in a haystack, when I don't know the needle yet (for testing). The MainGenericRunner only seems to be catching "ClassNotFound/NoSuchMethodException/InvocationTargetExcepti‌​on" from the 2.8.1 source (I've been through the entire stack trace and can't find anything that would swallow the exception) -> lampsvn.epfl.ch/svn-repos/scala/scala/tags/R_2_8_1_final/src‌​/…
  • Aaron Novstrup
    Aaron Novstrup almost 13 years
    MainGenericRunner invokes your main method via reflection, so InvocationTargetException will wrap any uncaught exception that occurs in your code. You could set up IntelliJ to break on InvocationTargetException and then examine the cause(s) to determine what type of exception is being thrown by your code. Then run again, with IntelliJ set up to break on that type of exception. You'll have to tick "Caught exception", though, because there won't be any uncaught exceptions.
  • Michael
    Michael almost 13 years
    Got it, thanks for bearing with me, I knew I was missing something. Will bounty in 8 hours when it's available.