-
Notifications
You must be signed in to change notification settings - Fork 0
dbg module Elixir
Serge edited this page Oct 11, 2021
·
3 revisions
The module AnApp.ex accepts and makes calls and receives and sends messages:
defmodule AnApp do
def start do
spawn(&loop/0)
end
def loop do
receive do
{From, x} -> send(From, __MODULE__.f1(x))
_ -> :ok
end
__MODULE__.loop()
end
def f1(x) do
f2(x)
end
defp f2(x) do
sin(x)
end
defp sin(x) do
:math.sin(x)
end
endLet us ompile it first with elixirc AnApp.ex.
Now we can trace it.
In Elixir shell:
Erlang/OTP 24 [erts-12.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]
Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> cd "d:/src/my_working_folder"
d:/src/my_working_folder
iex(3)> require AnApp
AnApp
iex(5)> s = AnApp.start
#PID<0.111.0>Now prep the :dbg facility:
iex(11)> :dbg.tracer()
{:ok, #PID<0.119.0>}
iex(13)> :dbg.tpl(AnApp,:'_',:x) # trace all functions of an_app, with return_value
{:ok, [{:matched, :nonode@nohost, 10}, {:saved, :x}]}
iex(15)> :dbg.p(:all, :c) # trace all processes, calls with the local trace pattern above
{:ok, [{:matched, :nonode@nohost, 60}]}
iex(17)> :dbg.p(s) # trace all messages sent and received by the process s
{:ok, [{:matched, :nonode@nohost, 1}]}
We are all set.
Let us give it a shot:
iex(19)> AnApp.f1 1.57
(<0.105.0>) call 'Elixir.AnApp':'__info__'(macros)
(<0.105.0>) returned from 'Elixir.AnApp':'__info__'/1 -> []
(<0.105.0>) call 'Elixir.AnApp':'__info__'(deprecated)
(<0.105.0>) returned from 'Elixir.AnApp':'__info__'/1 -> []
(<0.105.0>) call 'Elixir.AnApp':f1(1.57)
(<0.105.0>) call 'Elixir.AnApp':f2(1.57)
(<0.105.0>) call 'Elixir.AnApp':sin(1.57)
(<0.105.0>) returned from 'Elixir.AnApp':sin/1 -> 0.9999996829318346
(<0.105.0>) returned from 'Elixir.AnApp':f2/1 -> 0.9999996829318346
(<0.105.0>) returned from 'Elixir.AnApp':f1/1 -> 0.9999996829318346
0.9999996829318346... it worked!
how about messages?
iex(21)> send(s , {self, 1.57})
(<0.111.0>) << {<0.116.0>,1.57}
0.9999996829318346
(<0.111.0>) call 'Elixir.AnApp':f1(1.57)
{#PID<0.116.0>, 1.57}
(<0.111.0>) call 'Elixir.AnApp':f2(1.57)
(<0.111.0>) call 'Elixir.AnApp':sin(1.57)
(<0.111.0>) returned from 'Elixir.AnApp':sin/1 -> 0.9999996829318346
(<0.111.0>) returned from 'Elixir.AnApp':f2/1 -> 0.9999996829318346
(<0.111.0>) returned from 'Elixir.AnApp':f1/1 -> 0.9999996829318346
(<0.111.0>) <0.105.0> ! 0.9999996829318346
iex(23)> (<0.111.0>) call 'Elixir.AnApp':loop()
iex(24)> flush
0.9999996829318346
:oknice!
the original study:
Prepare the Echo server to study
defmodule Echo do
def start do
spawn(&loop/0)
end
defp loop do
receive do
m -> IO.inspect(m)
loop()
end
end
end
echo = Echo.start()
#PID<0.218.0> :dbg.tracer() # :dbg module has its own tracer
:dbg.p(echo, :all)
send(echo, :hi) # a slew of tracing data:
:hi
:hi
(<0.218.0>) in {'Elixir.Echo',loop,0} (Timestamp: {1633,194976,262121})
iex(46)> (<0.218.0>) << hi (Timestamp: {1633,194976,262122})
(<0.218.0>) gc_minor_start [{wordsize,11}, ... skipped
(<0.218.0>) gc_minor_end ... skipped ...
(<0.218.0>) <0.65.0> ! {io_request,<0.218.0>,
#Ref<0.3176856020.1409548295.192147>,
{put_chars,unicode,<<":hi\n">>}} (Timestamp: {1633,
194976,
262127})
(<0.218.0>) out {io,execute_request,2} (Timestamp: {1633,194976,262128})
(<0.218.0>) in {io,execute_request,2} (Timestamp: {1633,194976,262129})
(<0.218.0>) << {io_reply,#Ref<0.3176856020.1409548295.192147>,ok} (Timestamp: {1633,
194976,
262130})
(<0.218.0>) out {'Elixir.Echo',loop,0} (Timestamp: {1633,194976,262131})
:dbg.stop_clear() # let us stop tracing
:ok
iex(48)> send(echo,:hi) # no more tracing:
:hi
:hi :dbg.tracer()
:dbg.p(:all,:c)
:dbg.tpl(:math, :sin, 1, :x)
:math.sin(1)
(<0.105.0>) call math:sin(1)
(<0.105.0>) returned from math:sin/1 -> 0.8414709848078965
0.8414709848078965
:dbg.stop_clear() [{x,z,[y]}] = :dbg.fun2ms(fn([x]) when x == 3.14 -> :return_trace end)
ms = [{x,z,[{y}]}] # now we have a match spec
[{[:"$1"], [{:==, :"$1", 3.14}], [{:return_trace}]}]
:dbg.tracer()
:dbg.p(:all,:c)
:dbg.tpl(:math, :sin, 1, ms)
:math.sin(1) # no trace as expected:
0.8414709848078965
:math.sin(3.14) # now the call and the return values as expected:
(<0.105.0>) call math:sin(3.14)
(<0.105.0>) returned from math:sin/1 -> 0.0015926529164868282
0.0015926529164868282[2] dbg docs