Can Elixir Kernel functions be traced by :dbg?

I’m new to Elixir and playing around with tracing. Following an example, I successfully setup :dbg to trace Enum.map/2 when executed inside iex. The trace event is created.

iex(3)> :dbg.tp(Enum, :map, [])   
{:ok, [{:matched, :nonode@nohost, 1}]}
iex(4)> :dbg.p(:all, :c)
{:ok, [{:matched, :nonode@nohost, 61}]}
iex(5)> Enum.map()
** (UndefinedFunctionError) function Enum.map/0 is undefined or private. Did you mean one of:

      * map/2

    (elixir 1.12.1) Enum.map()
(<0.109.0>) call 'Elixir.Enum':map([{1.0,map,2}],#Fun<Elixir.UndefinedFunctionError.7.56279482>)
iex(5)> 

I then tried to trace Kernel.rem/2 . This doesn’t appear to work. I tried a couple of other Kernel functions and they all didn’t produce a trace event.

iex(6)> :dbg.tp(Kernel, :rem, [])      
{:ok, [{:matched, :nonode@nohost, 1}]}
iex(7)> rem(1,1)
0
iex(8)> Kernel.rem(1,1)
0

Why are they not traced? Thank you

That’s because Kernel.rem/2 is “inlined by the compiler”, as mentioned in the documentation for that function (guard). It basically gets translated to an Erlang operator, so no function invocation takes place.

This is something to keep in mind when using :dbg and other tools that use BEAM tracing: the code you see in the editor/IEx may get optimized by the various compiler stages and this may impact what you can trace.

5 Likes

Thank you for that explanation and that makes sense!