Eper redbug, print line number in message

Here are some posts about using redbug in a shell:

% 02:49:02 <0.116.0>({cowboy_protocol,init,4})
% func1:start(<<"/second">>, [some])

% 02:49:02 <0.116.0>({cowboy_protocol,init,4})
% func1:looper(<<"/home/second">>, #{data => []}])

      

Is there a way to print line numbers in redbug posts?

redbug: help () shows this:

print_fun    ()            custom print handler, fun/1 or fun/2;
                             fun(TrcMsg) -> <ignored>
                             fun(TrcMsg,AccOld) -> AccNew

      

But there is no good explanation anywhere on how to use it, so I couldn't try to see if I can add line numbers to the post

+3


source to share


1 answer


You can't seem to do it in a straightforward way.

The easiest way to check this is to simply print out all the data you received in print_fun

1> PrintFun = fun (Msg) -> io:format( ">>> ~p~n" , [Msg]) end.
#Fun<erl_eval.6.90072148>
2> redbug:start("erlang" , [{print_fun, PrintFun}]).
{30,249}
>>> {call,{{erlang,demonitor,[#Ref<0.0.0.40>]},<<>>},
          {<0.33.0>,{erlang,apply,2}},
          {11,40,31,554200}}
>>> {call,{{erlang,atom_to_list,['PrintFun']},<<>>},
          {<0.33.0>,{erlang,apply,2}},
          {11,40,31,554210}}
>>> {call,{{erlang,group_leader,[]},<<>>},
          {<0.33.0>,{erlang,apply,2}},
          {11,40,31,554213}}
>>> {call,{{erlang,monitor,[process,<0.26.0>]},<<>>},
          {<0.33.0>,{erlang,apply,2}},
          {11,40,31,554215}}
>>> {call,{{erlang,port_control,[#Port<0.491>,101,[]]},<<>>},
          {<0.24.0>,user_drv},
          {11,40,31,554231}}
>>> {call,{{erlang,module_loaded,[calendar]},<<>>},
          {<0.20.0>,code_server},
          {11,40,31,554257}}
>>> {call,{{erlang,atom_to_list,[calendar]},<<>>},
          {<0.20.0>,code_server},
          {11,40,31,554263}}
>>> {call,{{erlang,'++',["calendar",".beam"]},<<>>},
          {<0.20.0>,code_server},
          {11,40,31,554265}}
>>> {call,{{erlang,'++',["ebin","/calendar.beam"]},<<>>},
          {<0.20.0>,code_server},
          {11,40,31,554268}}
>>> {call,{{erlang,whereis,[erl_prim_loader]},<<>>},
          {<0.20.0>,code_server},
          {11,40,31,554270}}
redbug done, msg_count - 10

      

As you can see, all you get is MFA ( {Module, Function, Arguments}

), a process call, and a timestamp.

To get the actual line of the function call, you will have to insert into the debug_info

attached ray (if any) with the module beam_lib

. I think the seampleas way of doing it would be using beam_lib:chunks( Module, [abstract_code]).

, exactly the same



{ok,{redbug,[{abstract_code,{raw_abstract_v1,[{attribute,1,
                                                         file,
                                                         {"src/redbug.erl",1}},
                                              {attribute,9,module,redbug},
                                              {attribute,11,export,[{help,0}]},
                                              {attribute,13,export,[{unix,1}]},
                                              {attribute,15,export,
                                                         [{start,1},{start,2},{start,3},{start,4},{start,5}]},
                                              {attribute,16,export,[{stop,0}]},
                                              {attribute,1,file,{"src/log.hrl",1}},
                                              {function,17,'?log',2,
                                                        [{clause,17,[{var,17,...},{var,...}],[[{...}]],[{...}]},
                                                         {clause,18,[{var,...},{...}],[],[...]}]},
                                              {attribute,19,file,{"src/redbug.erl",19}},
                                              {attribute,22,record,
                                                         {cnf,[{record_field,24,{...},...},
                                                               {record_field,25,...},
                                                               {record_field,...},
                                                               {...}|...]}},
                                              {function,57,help,0,[{clause,57,[],...}]},
                                              {function,123,unix,1,
                                                        [{clause,123,...},{clause,...},{...}|...]},
                                              {function,146,to_term,1,[{clause,...},{...}]},
                                              {function,154,maybe_halt,1,[{...}]},
                                              {function,160,is_in_shell,0,[...]},
                                              {function,167,stop,0,...},
                                              {function,174,start,...},
                                              {function,176,...},
                                              {function,...},
                                              {...}|...]}}]}}

      

You can find a list here where you might find tuples of type {function, LineNumber, FunctionName, Arity, FunctionCodeAsList }

. So by going through this list and the search function you are looking for you can retrieve LineNumber

.

However, there are a few things you need to take into account that might not work.

  • you are parsing the actual file from disk, so it should be in your current directory. It has nothing to do if and what is loaded on your virtual machine (which version of the code). So you might have to do a bit of work to find this.beam

  • files compiled without debug_info

    may not generate this abstract syntax tree. You need to decide if this can be your case and how you would like to handle it.
  • some beams

    may be encrypted, some may have other problems. You should read the beam_lib

    module documentation
    to understand what you are dealing with.

If you come up with something, divide. Happy hack!

+1


source







All Articles