# One-line debugging

**URL:** <https://discourse.julialang.org/t/one-line-debugging/62612>\
**Category:** New to Julia\
**Tags:** debug, debugging\
**Created:** [June 9, 2021, 8:23am UTC](https://discourse.julialang.org/t/one-line-debugging/62612 "2021-06-09T08:23:28Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![sapo](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sapo](https://discourse.julialang.org/u/sapo)\
**Post date:** [June 9, 2021, 8:23am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/1 "2021-06-09T08:23:28Z")

</div>

Hello,  
I’d just like to have a way to easily debug code for terminal-centric people. For instance, right now I have the following situation (which is rather common, though):

- a test/example script which is added by calling `include("script.jl)`
- a function `main` inside the script which is called by the user
- a package which is still being tested

In python, I could just use the one-line ` __import__ ("ipdb").set_trace()` to debug any line in `script.jl` or in the package.

In Julia, instead, I have to:

- add `using Debugger` at the top of the corresponding file
- add `@bp` at the line I want to debug
- add `@run` at the line where the function is called

Obviously, when I finish debugging (or decide to debug at another point) there’s the risk to leave some unneeded line (while in python I can just remove-copy my line).

So, workflow suggestions are welcome!

---

<div class="post-metadata">

**Author:** ![sapo](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sapo](https://discourse.julialang.org/u/sapo)\
**Post date:** [June 9, 2021, 8:35am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/2 "2021-06-09T08:35:28Z")

</div>

Example: a `@debug <line-number>` macro at the beginning of the function definition which automatically makes it be called with `using Debugger`, `@run` and break-point setup or something like that.

---

<div class="post-metadata">

**Author:** ![sapo](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sapo](https://discourse.julialang.org/u/sapo)\
**Post date:** [June 9, 2021, 8:42am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/3 "2021-06-09T08:42:33Z")

</div>

Other example: a macro which outputs the output of each instruction in the function (similarly to python’s `@snoop`).

---

<div class="post-metadata">

**Author:** ![ettersi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ettersi/32/6829_2.png) [@ettersi](https://discourse.julialang.org/u/ettersi)\
**Post date:** [June 9, 2021, 9:18am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/4 "2021-06-09T09:18:35Z")

</div>

Doesn’t quite satisfy your requirement of being “terminal-centric”, but I’ve really come to appreciate the debugger in VS code and would highly recommend to at least give it a try.

---

<div class="post-metadata">

**Author:** ![sapo](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sapo](https://discourse.julialang.org/u/sapo)\
**Post date:** [June 9, 2021, 9:26am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/5 "2021-06-09T09:26:48Z")

</div>

I already tried VSCode tons of times and despite it’s probably the second best editor in the world, It’s miles away from (neo)vim for me. It’s a shame that Julia decided to support only one editor. Supporting terminal workflows would be much more general and would work in almost any higher-level platform

---

<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:** [June 9, 2021, 9:49am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/6 "2021-06-09T09:49:47Z")

</div>

The VSCode debugger is basically just a convenient UI.  
You can add breakpoints with Debugger.jl without modifying your source code with e.g. `debug> bp add file:line`. So yes, you need `using Debugger; @enter main()`, but that really doesn’t seem too bad to me.  
[Infiltrator.jl](https://github.com/JuliaDebug/Infiltrator.jl) might also be of interest to you.

---

<div class="post-metadata">

**Author:** ![sapo](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sapo](https://discourse.julialang.org/u/sapo)\
**Post date:** [June 9, 2021, 10:14am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/7 "2021-06-09T10:14:15Z")

</div>

It’s not just `@enter main()`, it’s `@enter a_deeper_function()`. It’s very unpractical when you have to debug a function that is a few calls down in the stack.

I know about Infiltrator, and aside from the fact that it still needs `using Infiltrator`, it’s almost what I need, if we could also step around…

---

<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:** [June 9, 2021, 10:23am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/8 "2021-06-09T10:23:34Z")

</div>

Well, in theory you can just `@run main()` and the program will stop at the first breakpoint, no? Although you might run into performance issues, I suppose.

I also don’t quite see the issue with needing a `using` statement, considering you need to do that only once per session?

---

<div class="post-metadata">

**Author:** ![sapo](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sapo](https://discourse.julialang.org/u/sapo)\
**Post date:** [June 9, 2021, 10:31am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/9 "2021-06-09T10:31:40Z")

</div>

The problem is that using statements must be inside the module in which the function is defined, otherwise `@bp` is not recognized… so if I put `@bp` in the `MySeconfdModule`, I need to:

- put `using Debugger` in `MySecondModule`
- executes `@enter MyFirstModule.main()`
- press `C` to toggle compiled mode
- press `c` to continue until breakpoint
- press `C` again to start debugging

6 steps for debugging, while in Python it’s just a one line (that with snippets becomes a few characters written in the editor). Do that a few times and find the difference 🙂

---

<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:** [June 9, 2021, 10:40am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/10 "2021-06-09T10:40:36Z")

</div>

Well, you can always use `Main.@bp` in a nested module. But as I said before, if you don’t want to put anything into your file. Just set the breakpoints programatically.

Toggling compiled mode like you’re doing also doesn’t work, because breakpoints won’t work in compiled mode. So it comes down to

- `using Debugger` at the top level
- inserting breakpoints, either via `breakpoint(...)`, in the `debug>` REPL, or with `Main.@bp`
- `@run main()`

---

<div class="post-metadata">

**Author:** ![sapo](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sapo](https://discourse.julialang.org/u/sapo)\
**Post date:** [June 9, 2021, 10:51am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/11 "2021-06-09T10:51:23Z")

</div>

yeah, inserting them programatically is a way indeed. But `Main.@bp` is the way to go! Does `@run` start in compiled mode?

---

<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:** [June 9, 2021, 10:52am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/12 "2021-06-09T10:52:37Z")

</div>

No. `@run` in compiled mode is basically equivalent to running your code without a debugger (except for maybe the toplevel frame).

---

<div class="post-metadata">

**Author:** ![sapo](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sapo](https://discourse.julialang.org/u/sapo)\
**Post date:** [June 9, 2021, 10:58am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/13 "2021-06-09T10:58:31Z")

</div>

So there’s no way to automatically turn on compiled mode when using `@run`?

---

<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:** [June 9, 2021, 10:59am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/14 "2021-06-09T10:59:27Z")

</div>

Why do you want to do that? How do you plan on actually debugging anything, considering that breakpoints don’t work in compiled mode?

---

<div class="post-metadata">

**Author:** ![sapo](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sapo](https://discourse.julialang.org/u/sapo)\
**Post date:** [June 9, 2021, 11:02am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/15 "2021-06-09T11:02:23Z")

</div>

Most of the code I develop in my research leads me to computational problems and takes a long time to run in interpreted mode… I usually run a little example to make the code compile first and then run the real instance problem that I want to debug

---

<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:** [June 9, 2021, 11:08am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/16 "2021-06-09T11:08:24Z")

</div>

Yes, sure, but the point of `@run` is to run until we hit a breakpoint or your program finishes. Automatically switching to compiled mode in `@run` will therefore always run until your program finishes, because breakpoints are (almost) never hit in compiled mode. The one exception to that are breakpoints in the current frame. See e.g.

```julia
julia> using Debugger

julia> foo(x) = begin
         y = 2x
         @bp
         z = x*y
         return x+y+z
       end
foo (generic function with 1 method)

julia> bar(x) = begin
         y = 5x
         @bp
         z = 2*foo(y)
         @bp 
         return 2*z
       end
bar (generic function with 1 method)

julia> @run bar(3)
Hit breakpoint:
In bar(x) at REPL[11]:1
 1 bar(x) = begin
 2 y = 5x
●3 @bp
>4 z = 2*foo(y)
●5 @bp 
 6 return 2*z
 7 end

About to run: (foo)(15)
# enter compiled mode here with `C`
1|debug> c 
Hit breakpoint:
In bar(x) at REPL[11]:1
 2 y = 5x
●3 @bp
 4 z = 2*foo(y)
●5 @bp 
>6 return 2*z
 7 end

About to run: (*)(2, 990)
1|debug> c
1980

julia> # the breakpoint in foo never got hit

```

---

<div class="post-metadata">

**Author:** ![sapo](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sapo](https://discourse.julialang.org/u/sapo)\
**Post date:** [June 9, 2021, 11:19am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/17 "2021-06-09T11:19:38Z")

</div>

Oh, that’s a shame… I need to look into MagneticReadHead again, then

---

<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:** [June 9, 2021, 11:30am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/18 "2021-06-09T11:30:38Z")

</div>

> [@sapo](#):
>
> It’s a shame that Julia decided to support only one editor.

I’m not aware of any such decision. When did this happen?

I didn’t think “Julia” supported any editors at all. But I do know that VS Code supports Julia, and that some people have made Julia plugins in other editors as well. It’s up to whomsoever wants to use a particular editor to help push Julia support further.

---

<div class="post-metadata">

**Author:** ![jlchan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlchan/32/10958_2.png) [@jlchan](https://discourse.julialang.org/u/jlchan)\
**Post date:** [June 9, 2021, 11:49am UTC](https://discourse.julialang.org/t/one-line-debugging/62612/20 "2021-06-09T11:49:21Z")

</div>

To add to @DNF’s answer, I don’t think JuliaLang itself decided anything. VSCode is _the_ preferred IDE for most because Microsoft shifted resources away from Atom to VSCode and developers followed.

---

<div class="post-metadata">

**Author:** ![sapo](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sapo](https://discourse.julialang.org/u/sapo)\
**Post date:** [June 9, 2021, 12:58pm UTC](https://discourse.julialang.org/t/one-line-debugging/62612/21 "2021-06-09T12:58:34Z")

</div>

Yep, let’s say that Julia support in editor other than VSCode/Juno is not encomiable.

For instance, I use Vim and the syntax file breaks with other plugins. The language provider is a pain and autoformatting too, because they need to have plugins installed in the current environment but no “develop” section exists in the Project.toml.

But this should be another thread…
