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
- 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.
Infiltrator.store) can be used to access exfiltrated variables directly via
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
- Error stack traces are now truncated properly.
@locals outputs much less (typically only one line per local variable).
Check the readme for a usage example.
This is wonderful progress!
I am a long-time user of Exfiltrator.jl, and am pleased that Infiltrator.jl supersedes Exfiltrator.jl’s functionality. To emulate
Exfiltrator.@exfiltrate, just do
in the REPL before running your code, and
Infiltrator.@exfiltrate will work the same.
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 !
You can list all disabled infiltration points with
getfield(safehouse, :disabled) and
pop! them out of that
Infiltrator.clear_disabled!() just calls
empty! on it.
There’s no list of non-disabled infiltration points anywhere though.
Thanks for your answer!
Do you think there would be an interest to implement the two proposed items above, for use in debugging workflow?
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.
Couldn’t you just register a line number node during macroexpansion? E.g.
julia> const locs = LineNumberNode
julia> macro foo()
@foo (macro with 1 method)
julia> function f(x)
x + 1
f (generic function with 1 method)
julia> function bar()
f(1) * 2
bar (generic function with 1 method)
Now we have
:(#= REPL:2 =#)
:(#= REPL:2 =#)
All great! Any hope for vscode integration in one form or another?
Hah, true. I’ll think about adding that functionality then (not 100% convinced about it being useful though).
No progress on that front.
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.