{"id":5280,"date":"2016-04-07T14:33:20","date_gmt":"2016-04-07T17:33:20","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=5280"},"modified":"2016-04-08T08:18:42","modified_gmt":"2016-04-08T11:18:42","slug":"debugging-techniques-in-elixir-lang","status":"publish","type":"post","link":"https:\/\/blog.plataformatec.com.br\/2016\/04\/debugging-techniques-in-elixir-lang\/","title":{"rendered":"Debugging techniques in Elixir"},"content":{"rendered":"

It’s common that our first experience with debugging in a new language is by printing values to the terminal. Elixir isn’t different: we can use IO.puts\/2<\/code> and IO.inspect\/2<\/code>. However, Elixir also provides other approaches to debugging.<\/p>\n

In this blog post, we’ll show you other 2 options: IEx.pry\/0<\/code> and :debugger<\/code>.<\/p>\n

IEx.pry<\/h2>\n

The name “pry” is an old friend in the Ruby ecosystem but it has a different behavior in Elixir. Let’s create a new project with mix<\/code> to try it out:<\/p>\n

$ mix new example\n$ cd example\n<\/code><\/pre>\n

Now let’s write some sample code in lib\/example.ex<\/code>:<\/p>\n

require IEx;\n\ndefmodule Example do\n  def double_sum(x, y) do\n    IEx.pry\n    hard_work(x, y)\n  end\n\n  defp hard_work(x, y) do\n    2 * (x + y)\n  end\nend\n<\/code><\/pre>\n

Now start a new IEx session and invoke our new function:<\/p>\n

$ iex -S mix\nInteractive Elixir (1.2.4) - press Ctrl+C to exit (type h() ENTER for help)\niex(1)> Example.double_sum(1, 2)\n<\/code><\/pre>\n

IEx.pry\/0<\/code> is built on top of IEx. Although it isn’t a traditional debugger since you can’t step, add breakpoints and so forth, it’s a good tool for non-production debugging. It runs in the caller process, blocking the caller and allowing us to access its binding (variables), verify its lexical information and access the process information. You can finish your “pry” session by calling respawn<\/code>, which starts a new IEx shell.<\/p>\n

\"Starting<\/p>\n

You can find more information at IEx.pry doc<\/a>.<\/p>\n

Debugger<\/h2>\n

If you need a breakpoint feature, we can use the :debugger<\/code> module that ships with Erlang. Let’s make a change in our example to be more didactic:<\/p>\n

defmodule Example do\n  def double_sum(x, y) do\n    hard_work(x, y)\n  end\n\n  defp hard_work(x, y) do\n    x = 2 * x\n    y = 2 * y\n\n    x + y\n  end\nend\n<\/code><\/pre>\n

Now we can start our debugger:<\/p>\n

$ iex -S mix\nErlang\/OTP 18 [erts-7.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]\n\nCompiled lib\/example.ex\nInteractive Elixir (1.2.4) - press Ctrl+C to exit (type h() ENTER for help)\niex(1)> :debugger.start()\n{:ok, #PID<0.87.0>}\niex(2)> :int.ni(Example)\n{:module, Example}\niex(3)> :int.break(Example, 3)\n:ok\niex(4)> Example.double_sum(1,2)\n<\/code><\/pre>\n

When you started the debugger, a Graphical User Interface must have opened in your machine. We called :int.ni(Example)<\/code> to prepare our module for debugging and then added a breakpoint to line 3 with :int.break(Example, 3)<\/code>. After we call our function, we can see our process with break status in the debugger:<\/p>\n

\"Process<\/p>\n

The process is blocked as in IEx.pry\/0<\/code>. We can add a new breakpoint in the monitor window, inspect the code, see the variables and navigate it in steps.<\/p>\n

Debugger has more options and command instructions that you can use. Take a look at Debbuger doc<\/a> for more information.<\/p>\n

Troubleshooting<\/h3>\n

You may have some problems when executing :int.ni(Example)<\/code> in the example above:<\/p>\n

iex(2)> :int.ni(Example)\n** Invalid beam file or no abstract code: 'Elixir.Example'\n<\/code><\/pre>\n

Before the upcoming Erlang 19 version, the debugger did not have the heuristic that traverses the module source attribute<\/a> applied. If you are not on the latest Erlang version, you can update the debugger manually with the following steps:<\/p>\n

    \n
  1. Download the file int.erl<\/code> from the PR.<\/li>\n
  2. Compile it with erlc -o . int.erl<\/code>.<\/li>\n
  3. Overwrite lib\/debugger\/ebin\/int.beam<\/code> in your Erlang installation with the new compiled file.<\/li>\n<\/ol>\n

    In the next post, we will see a tracing technique that doesn’t block the caller process.<\/p>\n

    What about you? What are the tools that you are using to debug your Elixir applications?<\/p>\n


    \n\"Subscribe
    \n<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"

    It’s common that our first experience with debugging in a new language is by printing values to the terminal. Elixir isn’t different: we can use IO.puts\/2 and IO.inspect\/2. However, Elixir also provides other approaches to debugging. In this blog post, we’ll show you other 2 options: IEx.pry\/0 and :debugger. IEx.pry The name “pry” is an … \u00bb<\/a><\/p>\n","protected":false},"author":18,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1],"tags":[247,143],"aioseo_notices":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/5280"}],"collection":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/comments?post=5280"}],"version-history":[{"count":13,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/5280\/revisions"}],"predecessor-version":[{"id":5296,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/5280\/revisions\/5296"}],"wp:attachment":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/media?parent=5280"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/categories?post=5280"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/tags?post=5280"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}