[ANN] Rebugger: interactive debugging for Julia 0.7/1.0

Well, that was an embarrassing start. I think it’s fixed now if you do

pkg> up
# stuff...

pkg> add Rebugger
# should install correctly

Sorry for the inconvenience, and many thanks to @kristoffer.carlsson for all his help!

4 Likes

There’s also now a report that the default keybindings may not work for Mac users. Is anyone else experiencing this? If so, please comment at Bad keybindings for Macs? · Issue #28 · timholy/Rebugger.jl · GitHub with confirmation and hopefully a suggested replacement, and we’ll see if we can come up with some kind of consensus about a default that works.

I’ve now changed the key bindings 3 times hoping to find something that works for all platforms, and every choice has caused a problem for someone. We may be getting to the point of having different defaults for different platforms.

Any plans to incorporate this into Juno?

2 Likes

https://github.com/timholy/Rebugger.jl/issues/18

Help wanted!

5 Likes

Do I understand this right that Rebugger does not change the source files, only the code loaded in the julia session?

In R, I could put a browser() into any where I want. It gives me a REPL so that inspection, changing variable values, etc. are possible. It makes debugging very easy and convenient.

Ideally, if we could do it in Julia, it would be like:

function xxx()
    """
    codes that are 100% fine
    """

    browser() # REPL for inspection and making arbitrary adhoc changes

    """
    codes that may have problems
    """
end

Is it possible in Julia?

Right now I’m using ASTIntepreter2.@enter(), which allows me to step into a function. However, everytime I have to start at the beginning of the function rather in the middle, or being conditional

any suggestions? thanks.

Having to change the code by adding calls like browse() inside it doesn’t seem that convenient to me.

The ideal solution will be being able to set breakpoints. And I think that’s coming, with ASTInterpreter. It’s just not finished.

One cannot eval into a local scope in Julia, thus a REPL of a local scope is not possible.

1 Like

Right, no changes to the source file. Of course since you can fix a bug right there at the rebug> prompt, I’ve contemplated making Ctrl-s mean “save change to the source file.” It’s a little scary, though, it requires quite a lot of faith in making sure the line numbering is all working correctly. So for now you have to copy/paste any edits you want to keep back into the source file.

If you only “step in” (Meta-e), then it doesn’t even make changes to any of the methods in your running session. (It defines some hidden methods, but does not alter anything that’s already been compiled.) Capturing a stacktrace, however, does alter existing methods.

Editing source files this way really seems a little scary :slight_smile: , not only because of the line numbers, if someone doesn’t know about the short cut they might change their source files without realizing it. Ctrl-s is the standard short cut for saving in many text editors and I guess that it is part of the muscle memory of many people.

Maybe you could open a text editor with a buffer that contains the edited file or create a tempfile .filename.jlto make it easier to apply the changes.

Regarding editing files while rebugging: That seems like something an IDE integration could very naturally provide. :slight_smile:

Will take a look a the Juno integration once I find the time.

4 Likes

Actually, I’ve come to suspect that if you’re sufficiently devious it may not quite be true. I haven’t tested so I can’t promise this will work, but here’s a sketch of how I’ve imagined implementing breakpoints. For a “method” with 2 interior breakpoints, Rebugger would put code on your command-line that looks something like this (if you’ve not looked, the docs might help explain some of this):

rebug> @eval SomeModule let (vars..., label_at_exit) = getstored(uuid) begin
          @goto $(label_at_exit)
          # somecode
          setstored!(uuid, varnames, varvals, :label1)
          throw(StopException())
          @label label1
          # code just after the first breakpoint
          setstored!(uuid, varnames, varvals, :label2)
          throw(StopException())
          @label label2
          # code just after the second breakpoint
      end

So if you enter this at the top, it will store program state just above label1 and then exit. (The StopException would be caught by Rebugger…or maybe that should just be a return nothing? Not sure.) Because it stored the label at which it exited, and loads from that storage at the top, if you just re-run this same command it will begin at label1 and continue on to label2.

I’m sure this will need some modification, but this is the general gist.

3 Likes

Yes, I agree, this sounds safer if an editor knows what you’re up to.

seems like it’s inconsistent with:

which one is true?

setting breakpoints … how would it behave? when the program runs to a breakpoint, would it give a REPL? If so, what’s the difference with the “browser()” approach?

They’re both right, they just mean different things and have different implications. In particular, yes indeed you can just insert an error and do Meta-s. If that wasn’t obvious from Rebugger’s documentation, can I ask you to suggest a change that would make it so?

1 Like

A breakpoint isn’t really any different from throwing an error, since Rebugger can catch errors and give you something that simulates the local scope of the method.

Have you tried it in Rebugger? I think it will become pretty self-evident if you do. Just modify your function to throw an error and then use Meta-s.

thanks @tim.holy … but sadly I’m still waiting JuliaPro to release 0.7/1.0 … right now I’m using JuliaPro 0.6.3.1, which seems not able to use Rebugger?

Definitely not possible on 0.6. It doesn’t even fully work on 0.7, due to 0.7’s backwards-compatibility with deprecated functionality in 0.6. It works properly on 1.0, though (modulo bugs in Revise & Rebugger).

How it would work, is one thing. But my main concern is that I don’t want to insert debugging calls into the sourcecode.

2 Likes