Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pretty-print Elixir source code from Dbgi chunk

Tags:

elixir

If I have a beam file compiled from Erlang code with debug_info, printing the corresponding source code is fairly easy:

{ok, {_, [{debug_info, {debug_info_v1, erl_abstract_code, AbstractCode}}]}} =
    beam_lib:chunks("my_module.beam", [debug_info]).
{ok, Forms} = erl_abstract_code:debug_info(erlang_v1, module_name, AbstractCode, []).
io:format("~s~n", [erl_prettypr:format(erl_syntax:form_list(Forms))]).

But what about Elixir? I can do the first two steps like this:

{ok, {_, [{debug_info, {debug_info_v1, elixir_erl, AbstractCode}}]}} = 
    beam_lib:chunks("Elixir.MyModule.beam", [debug_info]).
{ok, Forms} = elixir_erl:debug_info(elixir_v1, module_name, AbstractCode).

This gives a map of this form:

#{attributes => ...,
  compile_opts => [],
  definitions => ...,
  deprecated => [],
  file => <<"my_module.ex">>,
  line => 95,
  module => 'Elixir.MyModule',
  unreachable => []}

How do I print that as human-readable Elixir code?

like image 568
legoscia Avatar asked Apr 03 '19 15:04

legoscia


1 Answers

There is a Visual Studio extension that can de-code the BEAM file into Elixir Source Code:

To activate the extension select "Disassemble BEAM" from the context menu for a .beam file in the Explorer View:

enter image description here

Following Refs:

1) https://elixirforum.com/t/visual-studio-code-extension-to-view-beam-files/13373/4

2) http://beam-wisdoms.clau.se/en/latest/indepth-beam-file.html

Edit 1:---

ElixirLS is another tool for debugging Elixir or Erlang code.

Your compiled .beam modules don’t have the necessary function calls to send these messages. In other languages, you might compile two versions of your binaries, one with the debug calls and one without, but in Elixir, it works a bit differently.

When you compile Erlang or Elixir modules with the :debug_info option set, the resulting .beam files include a chunk with the Erlang Abstract Format representation of your code. Before you can debug a module, you have to “interpret” it by calling :int.ni/1, which reads this chunk and then purges the module. After that, any future calls to the module are handled by evaluating the Erlang abstract forms and making the necessary calls to the meta process after each evaluation.

Calling :int.ni/1 on each module in your project manually is a pain, so when you run a Mix task in the ElixirLS debugger, it automatically interprets all the modules in your project and its dependencies. This is a good default for most projects, though it can cause a noticeable lag in starting the task. Future versions of ElixirLS will likely include more configuration options to specify which modules to interpret.

Note: As a consequence of having to interpret modules prior to debugging, you can’t debug any code that lives outside of a module definition.

Important Links:

1) https://medium.com/@JakeBeckerCode/debugging-elixir-in-vs-code-400e21814614

2) http://blog.plataformatec.com.br/2016/04/debugging-techniques-in-elixir-lang/

3) https://zorbash.com/post/debugging-elixir-applications/#otp-behaviour-tracing

like image 89
youpilat13 Avatar answered Oct 19 '22 09:10

youpilat13