# \[ANN\] Infiltrator.jl v1.0

**URL:** <https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500>\
**Category:** Package Announcements\
**Tags:** debug, debugging\
**Created:** [June 7, 2021, 8:13am UTC](https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500 "2021-06-07T08:13:54Z")\
**Posts on this page:** 11\
**Page:** 1

<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 7, 2021, 8:13am UTC](https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500/1 "2021-06-07T08:13:54Z")

</div>

Hey everyone,

[Infiltrator.jl](https://github.com/JuliaDebug/Infiltrator.jl) 1.0 is out now! There were a few substantial changes and a bunch of QOL improvements:

- Added an `@exfiltrate` macro to export all local variables into a global storage space (or `safehouse`). This is also available as a command from the `infil>` REPL.
- Switched from a `debug>` prompt to `infil>` to make it easier to distinguish from Debugger.jl.
- Assignment/function definitions in the `infil>` REPL now assign into the `safehouse` instead of doing nothing. It’s not possible to overwrite local variables though.
- The `safehouse` (or `Infiltrator.store`) can be used to access exfiltrated variables directly via `safehouse.yourvariable`.
- `Infiltrator.set_store!(Main)` (or any other module) allows you to exfiltrate variables directly to that module, but is discouraged because you might end up overwriting global variables.
- Added a `@withstore` macro that evaluates its argument with all variables in the safehouse defined so `@withstore yourvariable` will work appropriately. Note that this is for interactive use only.
- `@stop` in the `infil>` REPL is now called `@toggle` and, well, toggles the current infiltration point.
- Added a `@continue` command to continue to the next infiltration point or stop if there is none (same functionality as exiting the REPL mode with ^D).
- Added an `@exit` command to stop the current infiltration session, where a session lasts until the code invoked in the Julia REPL has finished running. This uses the REPL hooks introduced in Julia 1.5, so you’ll need to manually call `Infiltrator.end_session!()` on previous versions after using `@exit`.
- Error stack traces are now truncated properly.
- `@locals` outputs _much_ less (typically only one line per local variable).

Check the [readme](https://github.com/JuliaDebug/Infiltrator.jl#example-usage) for a usage example.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [June 7, 2021, 1:31pm UTC](https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500/2 "2021-06-07T13:31:21Z")

</div>

This is wonderful progress!

I am a long-time user of [Exfiltrator.jl](https://github.com/antoine-levitt/Exfiltrator.jl), and am pleased that Infiltrator.jl supersedes Exfiltrator.jl’s functionality. To emulate `Exfiltrator.@exfiltrate`, just do

```julia
Infiltrator.set_store!(Main) 

```

in the REPL before running your code, and `Infiltrator.@exfiltrate` will work the same.

---

<div class="post-metadata">

**Author:** ![jdad](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdad/32/4739_2.png) [@jdad](https://discourse.julialang.org/u/jdad)\
**Post date:** [June 7, 2021, 2:17pm UTC](https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500/3 "2021-06-07T14:17:38Z")

</div>

Wonderful work!

Seeing new functionalities, maybe I am too greedy, but two questions (possible enhancements?) came immediately to my mind:

- is there a way to list breakpoints, with their enabled/disabled status?
- is there a way to re-enable a previously disabled breakpoint other than the one in which the code is currently? (Or, better? toggle any other known breakpoint?)

Again, many thanks and bravos for the wonderful (and I am sure very useful) package !

---

<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 7, 2021, 2:37pm UTC](https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500/4 "2021-06-07T14:37:35Z")

</div>

Kinda.  
You can list all disabled infiltration points with `getfield(safehouse, :disabled)` and `pop!` them out of that `Set`. `Infiltrator.clear_disabled!()` just calls `empty!` on it.

There’s no list of non-disabled infiltration points anywhere though.

---

<div class="post-metadata">

**Author:** ![jdad](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdad/32/4739_2.png) [@jdad](https://discourse.julialang.org/u/jdad)\
**Post date:** [June 7, 2021, 4:15pm UTC](https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500/5 "2021-06-07T16:15:13Z")

</div>

Thanks for your answer!  
Do you think there would be an interest to implement the two proposed items above, for use in debugging workflow?

---

<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 7, 2021, 4:36pm UTC](https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500/6 "2021-06-07T16:36:44Z")

</div>

It’s not really feasible to discover which infiltration points exist/may be called by your code beforehand. So while there is interest (at least you asked for it 🙂 ) I don’t see a good way to implement that functionality. It would be possible to collect all infiltration points after running your code once, but that seems to be of dubious utility.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [June 7, 2021, 5:05pm UTC](https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500/7 "2021-06-07T17:05:34Z")

</div>

> [@pfitzseb](#):
>
> It’s not really feasible to discover which infiltration points exist/may be called by your code beforehand.

Couldn’t you just register a line number node during macroexpansion? E.g.

```julia
julia> const locs = LineNumberNode[]
LineNumberNode[]

julia> macro foo()
           push!(locs, __source__ )
           nothing
       end
@foo (macro with 1 method)

julia> function f(x)
           @foo
           x + 1
       end
f (generic function with 1 method)

julia> function bar()
           @foo
           f(1) * 2
       end
bar (generic function with 1 method)

```

Now we have

```julia
julia> locs
2-element Vector{LineNumberNode}:
 :(#= REPL[5]:2 =#)
 :(#= REPL[6]:2 =#)

```

---

<div class="post-metadata">

**Author:** ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)\
**Post date:** [June 7, 2021, 5:12pm UTC](https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500/8 "2021-06-07T17:12:05Z")

</div>

All great! Any hope for vscode integration in one form or another?

---

<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 7, 2021, 5:36pm UTC](https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500/9 "2021-06-07T17:36:46Z")

</div>

> [@Mason](#):
>
> Couldn’t you just register a line number node during macroexpansion? E.g.

Hah, true. I’ll think about adding that functionality then (not 100% convinced about it being useful though).

> [@jlperla](#):
>
> All great! Any hope for vscode integration in one form or another?

No progress on that front.

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [October 28, 2021, 8:15pm UTC](https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500/10 "2021-10-28T20:15:05Z")

</div>

Dang, I just started using Infiltrator, and it is a lifesaver! To be able to run fully compiled code so that MCMC is fast, but then break and see what the heck is going on! That’s fantastic. Thanks for this piece of code! Needs to be in a pinned “tips-and-tricks” post.

---

<div class="post-metadata">

**Author:** ![Rafael\_Brus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael_brus/32/23767_2.png) [@Rafael\_Brus](https://discourse.julialang.org/u/Rafael_Brus)\
**Post date:** [June 18, 2025, 10:29am UTC](https://discourse.julialang.org/t/ann-infiltrator-jl-v1-0/62500/11 "2025-06-18T10:29:02Z")

</div>

That’s fantastic.
