How to use Infiltrator?

I have a startup.jl that looks like this:

try
  using Revise
catch e
  @warn "Error initializing Revise"
end
try
  using Infiltrator
catch e
  @warn "Error initializing Infiltrator"
end

I put @infiltrate in a function and got a compiler error. I then exited and restarted Julia and tried using Infiltrator,<my package>, with the same error. Searching the Web for the right way to do it, I found mention of LOAD_PATH and @v#.# (which is the second element of Base.LOAD_PATH) but no explanation I could understand of how to add Infiltrator to either of them. So how do I do it?

Hello,

If you want to use Infiltrator inside a module you are currently writing (or a module developed by a third party), use this syntax

Main.infiltrate(@__MODULE__, Base.@locals, @__FILE__, @__LINE__)

intead of @infiltrate

Otherwise, you need to include using Infiltrator within the module you want to infiltrate, which is not always convenient.

2 Likes

What about saying using Infiltrator and commenting it out when I don’t need it?

You can, but you would need to add Infiltrator in the project dependencies. Possible for your projects, less suitable I would say for third party projects. But you can :slight_smile:

It is also possible to import Infiltrator in the Base from startup.jl and then export it from it:

@eval Base begin
    import Infiltrator: @infiltrate
    export @infiltrate
end

The only issue I have found is that Julia does not pick this up when it compiles the project’s package images in its own process.

That didn’t work. Here’s my startup.jl:

try
  using Revise
catch e
  @warn "Error initializing Revise"
end
try
  using Infiltrator
  @eval Base begin
  import Infiltrator: @infiltrate
  export @infiltrate
end
catch e
  @warn "Error initializing Infiltrator"
end
try
  using Debugger
catch e
  @warn "Error initializing Debugger"
end

I put @infiltrate in my code, loaded it with using, and got an error “@infiltrate not defined”. I typed @infiltrate in the REPL and got an infil> prompt.

I think you have stumbled on the case where you try to precompile code with the @infiltrate statements which does not work as startup.jl is not loaded by precompilation pipeline. The workflow that I use is:

  1. Let the code to precompile without any @infiltrate statement in the code
  2. Then add @infiltrate statements in the code and let Revise to recompile the necessary methods.

The first step could be resolved if we had ability to set a custom startup.jl file that is passed to precompilation, which could be ignored when running tests.

1 Like

The documentation for usage is here.

  1. Activate default global environment: ]activate @1.11
  2. Load development packages: using Revise, Infiltrator
  3. Activate package environment: ]activate PackageName
  4. Load the unmodified package code: using PackageName
  5. Add Main.@infiltrate lines inside package function code as breakpoints.
  6. Call the package function from the REPL: f(x)
2 Likes

With loading the Infiltrator in the Base and exporting @infiltrate from there one has the same workflow regarding steps 4. - 6. The small advantage is that it is possible to use @infiltrate over Main.@infiltrate.

1 Like

That worked. Though I already found the bug with Debugger (the code doesn’t take long to run).