How to view/decode BEAM bytecode of a function?

I found beam_lib in stdlib and tried the following.
I want to see the bytecode of function main. There’s a chunk code, how to disassembly it? I can’t find related functions in beam_lib.

% foo.erl
-module(foo).
-record(person, {name, age}).

main()->
  Person=#person{name=yama, age=17},
  name=Person#person.name.
$ erl
> begin c("foo.erl"), beam_lib:info(foo) end.
[{file,"foo.beam"},
 {module,foo},
 {chunks,[{"AtU8",20,43},
          {"Code",72,56},
          {"StrT",136,0},
          {"ImpT",144,28},
          {"ExpT",180,28},
          {"Meta",216,45},
          {"LocT",272,4},
          {"Attr",284,39},
          {"CInf",332,80},
          {"Dbgi",420,46},
          {"Line",476,20},
          {"Type",504,10}]}]
> beam_lib:chunks(foo, ["Code"]).
{ok,{foo,[{"Code",
           <<0,0,0,16,0,0,0,0,0,0,0,171,0,0,0,5,0,0,0,2,1,16,...>>}]}}
1 Like

Assuming you are after beam asm, the simplest method is to use the -S flag with erlc (i.e., erlc -S foo.erl.

Of course, you can get the same result via the shell in a few ways, but here’s one :

1> c("foo.erl").
{ok,foo}
2> {foo, Bytes, _Path} = code:get_object_code(foo).
{foo,<<70,79,82,49,0,0,2,96,66,69,65,77,65,116,85,56,0,0,
       0,48,0,0,0,5,3,102,111,...>>,
     "/Users/starbelly/devel/erlang/otp/foo.beam"}
3> beam_disasm:file("foo.beam").
{beam_file,foo,
           [{main,0,2},{module_info,0,4},{module_info,1,6}],
           [{vsn,[220453479092905637972412714489452943650]}],
           [{version,"8.5.2"},
            {options,[]},
            {source,"/Users/starbelly/devel/erlang/otp/foo.erl"}],
           [{function,main,0,2,
                      [{label,1},
                       {line,1},
                       {func_info,{atom,foo},{atom,main},0},
                       {label,2},
                       {move,{literal,{{person,yama,17},yama}},{x,0}},
                       return]},
            {function,module_info,0,4,
                      [{line,0},
                       {label,3},
                       {func_info,{atom,foo},{atom,module_info},0},
                       {label,4},
                       {move,{atom,foo},{x,0}},
                       {call_ext_only,1,{extfunc,erlang,get_module_info,1}}]},
            {function,module_info,1,6,
                      [{line,0},
                       {label,5},
                       {func_info,{atom,foo},{atom,module_info},1},
                       {label,6},
                       {move,{x,0},{x,1}},
                       {move,{atom,foo},{x,0}},
                       {call_ext_only,2,{extfunc,erlang,get_module_info,2}}]}]}

That said, it should be considered a debug tool and one that is highly subject to change at that.

5 Likes