dbg:tracer visualizing recursive functions e.g. by indenting

一曲冷凌霜 提交于 2019-12-05 02:00:12

问题


I have the problem debugging an complicated recursive function I'm using the idiom:

dbg:tracer(),dbg:p(all,c),dbg:tpl(Mod,Fun1,x),dbg:tpl(Mod,Fun2,x)...

This gives me a flat list of calls to all functions where it is very hard to find out which return belongs to which call.

Is there a easy way to make this more readable e.g. by indenting.

I could just post process the text produced and indent for each call, and outdent for each return, but this sounds not very elegant to me.


回答1:


In the meantime I figured it out how to do this, its actually not too hard. To have a process handling the trace message output you just have to use dbg:trace/2,3 and write one function that does the formatting.

We write a small module containing the function to pass to dbg:trace:

-module(trtool).
-export([nested/2]).

nested({trace, _Pid, call, {Mod, Fun, Param}}, Level) ->
    io:format("~s~p:~p ~p\n", 
              [lists:duplicate(Level, "|   "), Mod, Fun, Param]),
    Level + 1;
nested({trace, _Pid, return_from, {Mod, Fun, Arity}, Rval}, Level) ->
    L = Level - 1,
    io:format("~s~p:~p/~b -> ~p\n", 
              [lists:duplicate(L, "|   "), Mod, Fun, Arity, Rval]),
    L;
nested(Any, Level) ->
    io:format("trace_msg: ~p\n", [Any]),
    Level.

The function takes two arguments, in the first it gets passed the trace message which is a tuple with convenient fields. To find out how the messages you want to format are structured just start with a simple function that prints everything like the last clause of the example function.

The second format is a kind of state that could contain any data. We pass the initial value when calling dbg:trace and return the next value from our function.

In the nested example we just pass the indent level which will be incremented and decremented in the call and return_from clauses.

Now lets try this out, first calling dbg:tracer/2, first parameter must be the atom process, second parameter a tuple containing our newly written fun and the initial value for the state param.

1> dbg:tracer(process, {fun trtool:nested/2, 0}).                         
{ok,<0.70.0>}

Then we set up tracing as before:

2> dbg:p(all, c), dbg:tpl(user_default,hop,x),dbg:tpl(user_default,rec,x).
{ok,[{matched,nonode@nohost,2},{saved,x}]}

Then we start our function call to trace and the nesting can be easily followed:

3> rec(3).                                                                
user_default:rec [3]
|   user_default:rec [3,1,3]
|   |   user_default:rec [3,1,2]
|   |   |   user_default:rec [3,1,1]
|   |   |   |   user_default:rec [3,1,0]
|   |   |   |   |   user_default:hop [3,1,0]
|   |   |   |   |   user_default:hop/3 -> {3,21}
|   |   |   |   user_default:rec/3 -> {3,21,1}
|   |   |   |   user_default:rec [6,2,-1]
|   |   |   |   |   user_default:hop [6,2,1]
|   |   |   |   |   user_default:hop/3 -> {2,46}
|   |   |   |   user_default:rec/3 -> {2,46,1}
|   |   |   user_default:rec/3 -> {5,67,2}
|   |   |   user_default:rec [8,3,0]
|   |   |   |   user_default:hop [8,3,0]
|   |   |   |   user_default:hop/3 -> {3,144}
|   |   |   user_default:rec/3 -> {3,144,1}
|   |   user_default:rec/3 -> {8,211,3}
|   |   user_default:rec [11,4,1]
|   |   |   user_default:rec [11,4,0]
|   |   |   |   user_default:hop [11,4,0]
|   |   |   |   user_default:hop/3 -> {3,258}
|   |   |   user_default:rec/3 -> {3,258,1}
|   |   |   user_default:rec [14,5,-1]
|   |   |   |   user_default:hop [14,5,1]
|   |   |   |   user_default:hop/3 -> {2,260}
|   |   |   user_default:rec/3 -> {2,260,1}
|   |   user_default:rec/3 -> {5,518,2}
|   user_default:rec/3 -> {13,729,5}
user_default:rec/1 -> {15,729}
{15,729}
4>



回答2:


There is not way you can do that with the current dbg tracer process, you would have to write your own. If you start dbg:tracer/2 and use a process or port to capture the data and print it the way you want it to be.

It is probably faster and easier though to (as you say) parse the data post tracing and format it then.



来源:https://stackoverflow.com/questions/5126458/dbgtracer-visualizing-recursive-functions-e-g-by-indenting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!