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

**URL:** <https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843>\
**Category:** Community\
**Tags:** announcement\
**Created:** [August 21, 2018, 5:51pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843 "2018-08-21T17:51:08Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [August 21, 2018, 5:51pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/1 "2018-08-21T17:51:08Z")

</div>

After several weeks of development, I’m pleased to officially announce [Rebugger](https://github.com/timholy/Rebugger.jl). While the package is still young and has obvious bugs, it’s already become an essential part of my Julia experience. So I decided it’s time to share.

Rebugger’s paradigm evolved considerably while I was developing it, and the “end result” (hah!) is interesting and feels different from anything I’ve encountered previously. With usage I’ve personally come to think that the differences are mostly improvements. To paraphrase from Rebugger’s [fairly extensive documentation](https://timholy.github.io/Rebugger.jl/stable/):

> With most debuggers, you enter some special mode that lets the user “dive into the code,” but what you are allowed to do while in this special mode may be limited. In contrast, Rebugger brings the code along with its input arguments to the user, presenting them both for inspection, analysis, and editing in the (mostly) normal Julia interactive command line.
> 
> As a consequence, you can:
> 
> - test different modifications to the code or arguments as many times as you want; you are never forced to exit “debug mode” and save your file
> - run the same chosen block of code repeatedly (perhaps trying out different ways of fixing a bug) without needing to repeat any of the “setup” work that might have been necessary to get to some deeply nested method in the original call stack. In other words, Rebugger brings “internal” methods to the surface.
> - run any desired command that helps you understand the nature of a bug.
> 
> For example, if you’ve already loaded `MyFavoritePlottingPackage` in your session, then when debugging you can (transiently) add `Main.MyFavoritePlottingPackage.plot(x, y)` as a line of the method-body you are currently analyzing, and you should see a plot of the requested variables.
> 
> Rebugger exploits the Julia REPL’s history capabilities to simulate the stacktrace-navigation features of graphical debuggers. Thus Rebugger offers a command-line experience that is more closely aligned with graphical debuggers than the traditional `s`, `n`, `up`, `c` commands of a console debugger.

Internally, Rebugger is a “low tech” debugger that is essentially orthogonal to more ambitious strategies like [ASTInterpreter2](https://github.com/Keno/ASTInterpreter2.jl). Indeed, once that package comes to full fruition Rebugger may switch to using it for its internal operations. In my estimation, the possibly-enduring contribution of Rebugger is the workflow and user interface, not its [debugging internals](https://timholy.github.io/Rebugger.jl/stable/internals.html). One of my personal hopes is that Rebugger will make it easier for Keno to continue work on ASTInterpreter2; it’s very hard to write a debugger, and doubly-hard to write one that can debug itself. To me, having Rebugger available to help fix and improve ASTInterpreter2 seems like it could be a good thing.

That said, because Rebugger’s debugging strategy is relatively simple, it’s fairly easy to extend. It already supports capturing stacktraces from calls that throw an error, and breakpoints would presumably be relatively straightforward. Somewhat to my own surprise, I’ve not yet started serious work on breakpoints because I’ve not yet found a real need to have them—the fact that you interact with “living code” means that breakpoints are basically something you do while you’re playing with the method. That said, if users find compelling examples that illustrate how useful they might be and offer a path towards figuring out what the interface should look like, please file a detailed description [as an issue](https://github.com/timholy/Rebugger.jl/issues).

Enjoy! And as always, please report any problems. I expect quite a few, and I will try to fix them as time permits.

---

<div class="post-metadata">

**Author:** ![NiclasMattsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/niclasmattsson/32/21988_2.png) [@NiclasMattsson](https://discourse.julialang.org/u/NiclasMattsson)\
**Post date:** [August 21, 2018, 6:59pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/2 "2018-08-21T18:59:35Z")

</div>

Just want to compliment you on the brilliant wordplay in the name (not to mention the package itself, which appears to be yet another can’t-live-without-it contribution). There is also a fourth meaning to the name though: rebugging is the process of creating new bugs for every old one you fix. I’m somewhat of an expert at this - it’s been an integrated part of my development workflow for as long as I can remember.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [August 21, 2018, 7:32pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/3 "2018-08-21T19:32:09Z")

</div>

Looks fantastic! I’m very excited to try it out!

Note that currently when I do `dev https://github.com/timholy/Rebugger.jl` I always get

```nohighlight
ERROR: Unsatisfiable requirements detected for package HeaderREPLs [0c95fe84]:
 HeaderREPLs [0c95fe84] log:
 ├─HeaderREPLs [0c95fe84] has no known versions!
 └─restricted to versions 0.2.0-0.2 by Rebugger [6bca5d8e] — no versions left
   └─Rebugger [6bca5d8e] log:
     ├─possible versions are: 0.0.0 or uninstalled
     └─Rebugger [6bca5d8e] is fixed to version 0.0.0

```

whether or not I have `HeaderREPLs` installed (at version 0.2.0).

Is this a bug with the package manager? I’ve seen this happen before and I wasn’t able to resolve without deleting `JULIA_HOME`.

(Can work around only by doing `dev HeaderREPLs`.)

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [August 21, 2018, 7:35pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/4 "2018-08-21T19:35:06Z")

</div>

Yes, I’ve become aware it’s currently uninstallable. Oops. I’m working on seeing if I can fix it. The most puzzling aspect is that despite having been registered in METADATA.jl it’s not in JuliaRegistries/General. But the problems seem to go deeper than that. Clearly I’m a Pkg noob.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [August 21, 2018, 7:37pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/5 "2018-08-21T19:37:11Z")

</div>

> [@tim.holy](#):
>
> The most puzzling aspect is that despite having been registered in METADATA.jl it’s not in JuliaRegistries/General

[HeaderREPLs](https://github.com/JuliaRegistries/General/tree/master/H/HeaderREPLs) is, but Rebugger probably hasn’t made it through yet. That shouldn’t matter, however, since you should still be able to install it with `dev`.

I’m increasingly suspicious that the error I showed is a `Pkg` bug. (Like I said, I’ve had this problem before.)

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [August 21, 2018, 7:43pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/6 "2018-08-21T19:43:45Z")

</div>

OK, I can now verify that the following works:

```julia
pkg> dev https://github.com/timholy/HeaderREPLs.jl.git https://github.com/timholy/Rebugger.jl.git

```

It does _not_ yet work with `add`. I will see what I can do to fix that, but for now hopefully this gets people going.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [August 21, 2018, 9:49pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/7 "2018-08-21T21:49:32Z")

</div>

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

```julia
pkg> up
# stuff...

pkg> add Rebugger
# should install correctly

```

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

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [August 21, 2018, 10:56pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/8 "2018-08-21T22:56:58Z")

</div>

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](https://github.com/timholy/Rebugger.jl/issues/28) 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.

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [August 23, 2018, 6:47am UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/9 "2018-08-23T06:47:52Z")

</div>

Any plans to incorporate this into Juno?

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [August 23, 2018, 10:16am UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/10 "2018-08-23T10:16:29Z")

</div>

[https://github.com/timholy/Rebugger.jl/issues/18](https://github.com/timholy/Rebugger.jl/issues/18)

Help wanted!

---

<div class="post-metadata">

**Author:** ![gdkrmr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdkrmr/32/2791_2.png) [@gdkrmr](https://discourse.julialang.org/u/gdkrmr)\
**Post date:** [August 23, 2018, 1:18pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/11 "2018-08-23T13:18:33Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [August 23, 2018, 1:24pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/12 "2018-08-23T13:24:50Z")

</div>

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:

```julia
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.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 23, 2018, 2:51pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/13 "2018-08-23T14:51:46Z")

</div>

> [@tomtom](#):
>
> Ideally, if we could do it in Julia, it would be like:

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.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [August 23, 2018, 2:54pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/14 "2018-08-23T14:54:57Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [August 23, 2018, 3:10pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/15 "2018-08-23T15:10:43Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![gdkrmr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdkrmr/32/2791_2.png) [@gdkrmr](https://discourse.julialang.org/u/gdkrmr)\
**Post date:** [August 23, 2018, 3:19pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/16 "2018-08-23T15:19:01Z")

</div>

Editing source files this way really seems a little scary 🙂 , 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.jl`to make it easier to apply the changes.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [August 23, 2018, 3:22pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/17 "2018-08-23T15:22:43Z")

</div>

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

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

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [August 23, 2018, 3:22pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/18 "2018-08-23T15:22:43Z")

</div>

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](https://timholy.github.io/Rebugger.jl/latest/internals.html) might help explain some of this):

```julia
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.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [August 23, 2018, 3:24pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/19 "2018-08-23T15:24:20Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [August 24, 2018, 1:53pm UTC](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843/20 "2018-08-24T13:53:47Z")

</div>

> [@mauro3](#):
>
> One cannot eval into a local scope in Julia, thus a REPL of a local scope is not possible.

seems like it’s inconsistent with:

> [@Debugging like R's browser() possible?](https://discourse.julialang.org/t/debugging-like-rs-browser-possible/13925/10):
>
> For the question of usage like R’s browser(), you can use error() in the code and get to it using Meta-s (Alt-s) when calling the top-level function.

which one is true?

[Next page](https://discourse.julialang.org/t/ann-rebugger-interactive-debugging-for-julia-0-7-1-0/13843.md?page=2)
