DonJayamanne / javaVSCode

Extension for java development on VSCode (deprecated)
https://marketplace.visualstudio.com/items?itemName=donjayamanne.javaDebugger
MIT License
43 stars 29 forks source link

Debugger does not output exceptions #46

Open rianadon opened 7 years ago

rianadon commented 7 years ago

Whenever the Java code I'm debugging doesn't throw exceptions (which I wish were always), the debugger works great. However, if the code does throw an exception, the debugger will continue running and not output the exception.

For example, with the following code:

class Main {
    public static void main(String[] args) {
        System.out.println("Hello");
        throw new RuntimeException("Error!");
    }
}

Only the Hello will be printed, and the floating debugging toolbar will continue to be present, and the Java process will continue to be running until the stop button is pressed.

faustinoaq commented 7 years ago

If I use external console instead, exception is showed, however it's happening only after stop button.

screenshot_20170615_172821

rianadon commented 7 years ago

Yeah however for me that console closes as soon as I click the stop button so I only see the exception for a split second.

I decided to do a bit of digging into this by running the commands the extension does: java -agentlib:jdwp=transport=dt_socket,server=y,address=1234 Main and: jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=1234

The exception shows up only in the java process after I enter run and exit into jdb, which seems consistent with what happens in the external console.

However, in the jdb window, the exception shows up in jdb:

Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
>
VM Started: No frames on the current call stack

main[1] run
>
Exception occurred: java.lang.RuntimeException (uncaught)"thread=main", Main.main(), line=4 bci=17
4            throw new RuntimeException("Error!");

main[1] exit

Looking at the extension's code since the exception gets printed to jdb's stdout it gets passed to the onDataReceived function, which I don't think handles it.

Given that jdb's format doesn't contain a stacktrace it may be more easier to exit jdb when an error shows up in the stdout and send the error in the java process to the debug console.

I'm not sure if this would work for errors thrown in a second thread though.

rianadon commented 7 years ago

I now tried the following new code to see how this works with threads:

class Main {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("Hello");

        new Thread(() -> {
            throw new RuntimeException("Error from thread!");
        }).start();

        Thread.sleep(2000);
        System.out.println("Main thread still running...");
        throw new RuntimeException("Error from main!");
    }
}

When running jdb breaks on all of the exceptions, and continuously typing cont allows the code to continue running (see output below):

Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
>
VM Started: No frames on the current call stack

main[1] run
>
Exception occurred: java.lang.RuntimeException (uncaught)"thread=Thread-0", Main.lambda$main$0(), line=6 bci=9
6                throw new RuntimeException("Error from thread!");

Thread-0[1] cont
>
Exception occurred: java.lang.RuntimeException (uncaught)"thread=main", Main.main(), line=11 bci=46
11            throw new RuntimeException("Error from main!");

main[1] cont
>
The application exited

Probably either the debugger should

  1. For now continue past all exceptions so that they are outputted
  2. Recognized that jdb is paused and update the debugging ui accordingly

It's interesting that jdb prints Set uncaught java.lang.Throwable upon being run. Maybe there's some way to make it not break on Throwables, but I couldn't figure out how to do this.

Then maybe the debugger could have checkboxes for breaking on exceptions like other debuggers do: in the lower left-hand corner.

rianadon commented 7 years ago

Wow I can't believed I missed the command. Running ignore uncaught java.lang.Throwable before run stops jdb from breaking on extensions. Doing this as a temporary fix could work (but that wouldn't solve the issue of exceptions not showing up in the debug console - it would only make them immediately show in the external console).

As for allowing control of when exceptions are thrown, selectively running this command and detecting when jdb decides to pause on an exception would be great. Here's a screenshot I found online of how the Node.js debugger handles the UI for this:

Node.js debugger

However given this is different from the original issue should I create a new issue for enabling & disabling breaking on exceptions?

Sorry for all the comments 🙂.

rianadon commented 7 years ago

I was able to solve this in a very hacky way by replacing the "run" on this line with "ignore uncaught java.lang.Throwable\nrun". The exception (I experimented with the first example I posted) is then printed in the debug console. However this fix seems hacky in so many ways.

You would probably have a much better way of sending that command first.

faustinoaq commented 7 years ago

I think this issue is OK, we can fix this applying some launch setting like this or using Uncaught exceptions as you said above.

rianadon commented 7 years ago

Ideally something that would allow breaking on exceptions to be toggled in the middle of debugging would be nice. For example, the Node.js debugger does this:

It would be very cool if this debugger had this functionality, which would require sending something to jdb when the checkbox is ticked (so a launch setting wouldn't work here as that couldn't be updated in the middle of a debugging session).

Being able to match the full functionality of the Node.js debugger may be a lot of work though.

For now either:

  1. Stopping jdb from breaking on exceptions through sending a message or always applying a launch setting
  2. Detecting when jdb breaks on an exception and register the debugger state as paused

would make the error be printed in the debug console.

faustinoaq commented 7 years ago

Yes, something like Node.js exception handling is a good option.

Some help by @DonJayamanne could be needed to reach this enhancement.

On Thu, Jun 15, 2017 at 11:54 PM, rianadon notifications@github.com wrote:

Ideally something that would allow breaking on exceptions to be toggled in the middle of debugging would be nice. For example, the Node.js debugger does this:

https://camo.githubusercontent.com/c71b3a6313a57b4540e10bae31867812ce7a49ab/68747470733a2f2f676973742e6769746875622e636f6d2f7269616e61646f6e2f32323564373731353933393163323130383165346234356132653834386666662f7261772f326166383130613332303661626332613533623362343935313966663230316436633863353866302f323031372d30362d31355f32312d32312d31382e676966

Ideally it would be very cool if this debugger had this functionality, which would require sending something to jdb when the checkbox is ticked (so a launch setting wouldn't work here as that couldn't be updated in the middle of a debugging session).

Being able to match the full functionality of the Node.js debugger may be a lot of work though.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/DonJayamanne/javaVSCode/issues/46#issuecomment-308932911, or mute the thread https://github.com/notifications/unsubscribe-auth/AC7Nx_LpNmqv_ra64xifHPrjAi4S4r7Aks5sEgprgaJpZM4N7w23 .

DonJayamanne commented 7 years ago

@faustinoaq , will look into this soon, apologies for not paying attention to this.

faustinoaq commented 7 years ago

@DonJayamanne don't worry your were doing an excellent work in vscode-python, Thanks you! :sparkles:

faustinoaq commented 7 years ago

~~Hey @DonJayamanne any way to report this~ :point_right: https://marketplace.visualstudio.com/items?itemName=mrawdon.javadebugger ? Fixed, it was a misunderstanding

DonJayamanne commented 7 years ago

@faustinoaq, they are well within their rights to publish this, however I'd ask them to remove our names from the readme. As we are not maintaining that particular branch or extension.

@mrawdon please update the readme (to remove our names, mine and others) and the corresponding links on the extension (remove links that point to this repo), as we are not maintaining nor contributing to your extension. Apart from that feel free to keep your own repo and your own extension, though it does look weird.

mrawdon commented 7 years ago

Oh yeah I can remove it. I only put it out there so a coworker could install

DonJayamanne commented 7 years ago

@mrawdon If you want to create a package for locall installation you have a number of choices:

mrawdon commented 7 years ago

I unpublished it