ferd / recon

Collection of functions and scripts to debug Erlang in production.
http://ferd.github.io/recon/
BSD 3-Clause "New" or "Revised" License
1.37k stars 278 forks source link

Elixir Kernel function cannot be traced but erlang kernel #93

Closed billtong closed 3 years ago

billtong commented 3 years ago

Hi, I'd like to use the recon_trace in the elixir application. It works well most of the time but has some problems with the elixir kernel function. When I try to trace a kernel function in elixir, it seems can't be traced but only from the erlang one. below is an example of Kernel.+/2 this also happens to all the other Kernal methods that I tested so far. I wonder if there is some syntax error about the matching here or it's some other issues.

iex(1)> :recon_trace.calls({Kernel, :+, 2}, 1)
1
iex(2)> Kernel.+(1,2)
3
iex(3)> :recon_trace.calls({:erlang, :+, 2}, 1)
1
iex(4)> Kernel.+(1,2)
3

5:54:07.460259 <0.190.0> erlang:'+'(1, 2)
Recon tracer rate limit tripped.
ferd commented 3 years ago

I have no idea. Specifically the library returns 1 matching call to trace even if I'd have expected to have to put in the full Elixir.whatever module path.

https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/kernel.ex#L1302-L1309 and https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/kernel.ex#L1342-L1347 do seem to say that to make it work in guards, the compiler inlines the calls. It's possible that this also takes place in the evaluator running iex and that for this reason the Kernel.+ call is actually never done. Nothing we can fix in recon.

gomoripeti commented 3 years ago

The Kernel docs says

Most of the inlined functions can be seen in effect when capturing the function:

And indeed

iex(1)> &Kernel.+/2
&:erlang.+/2

so it looks like also the iex shell inlines the Kernel functions

ferd commented 3 years ago

Nothing this library can do then, closing the issue, but feel free to keep discussing.

billtong commented 3 years ago

Thanks for the reply! I see, as inlined by the compiler these Kernel Functions didn't been called but the counterpart of Erlang BIFs. By coincidence, all the functions I tested are this type of scenario. Hence I tried Kernel.inspect/2 and others that not inlined and they work fine. I guess the solution is probably manually changed to :erlang module when it's an inlined one.

paulo-ferraz-oliveira commented 3 years ago

@g-andrade: hadn't we (you) tried recon with Elixir recently? Do you remember if there was a caveat to how the input had to be expressed (atoms and the like)?

g-andrade commented 3 years ago

No caveat that I remember, the hidden Elixir. namespace is handled seamlessly