如何在Erlang中使用trace和dbg来调试和跟踪我的程序?

aydmsdu9  于 2022-12-08  发布在  Erlang
关注(0)|答案(4)|浏览(287)

我尝试开始使用erlang:trace/3dbg模块来跟踪实际生产系统的行为,而不需要关闭服务器。
文档是不透明的(委婉地说),似乎没有任何有用的在线教程。
我花了一整天的时间试图捕获特定函数中发生的情况,方法是尝试使用dbg:cdbg:pModule:Function应用跟踪,但根本没有成功。
有没有人对如何在实时Erlang系统中使用trace有一个简洁的解释?

nue99wik

nue99wik1#

The basic steps of tracing for function calls are on a non-live node:

> dbg:start().   % start dbg
> dbg:tracer().  % start a simple tracer process
> dbg:tp(Module, Function, Arity, []).   % specify MFA you are interested in
> dbg:p(all, c).   % trace calls (c) of that MFA for all processes.

... trace here

> dbg:stop_clear().   % stop tracer and clear effect of tp and p calls.

You can trace for multiple functions at the same time. Add functions by calling tp for each function. If you want to trace for non-exported functions, you need to call tpl . To remove functions, call ctp or ctpl in a similar manner. Some general tp calls are:

> dbg:tpl(Module, '_', []).  % all calls in Module
> dbg:tpl(Module, Function, '_', []).   % all calls to Module:Function with any arity.
> dbg:tpl(Module, Function, Arity, []). % all calls to Module:Function/Arity.
> dbg:tpl(M, F, A, [{'_', [], [{return_trace}]}]).   % same as before, but also show return value.

The last argument is a match specification. You can play around with that by using dbg:fun2ms .
You can select the processes to trace on with the call to p(). The items are described under erlang:trace. Some calls are:

> dbg:p(all, c).   % trace calls to selected functions by all functions
> dbg:p(new, c).   % trace calls by processes spawned from now on
> dbg:p(Pid, c).   % trace calls by given process
> dbg:p(Pid, [c, m]).  % trace calls and messages of a given process

I guess you will never need to directly call erlang:trace , as dbg does pretty much everything for you.
A golden rule for a live node is to generate only an amount of trace output to the shell, which lets you to type in dbg:stop_clear(). . :)
I often use a tracer that will auto-stop itself after a number of events. For example:

dbg:tracer(process, {fun (_,100) -> dbg:stop_clear();
                        (Msg, N) -> io:format("~p~n", [Msg]), N+1 end, 0
                    }).

If you are looking for debugging on remote nodes (or multiple nodes), search for pan , eper , inviso or onviso .

rdlzhqv9

rdlzhqv92#

On live systems we rarely trace to shell. If the system is well configured then it is already collecting your Erlang logs that were printed to the shell. I need not emphasize why this is crucial in any live node...

Let me elaborate on tracing to files:

It is possible to trace to file, which will produce a binary output that can be converted and parsed later. (for further analysis or automated controlling system, etc.)
An example could be:

  • Trace to multiple files wrapped (12x50 Mbytes).Please always check the available disk space before using such a big trace!
dbg:tracer(port,dbg:trace_port(file,{"/log/trace",wrap,atom_to_list(node()),50000000,12})).

dbg:p(all,[call,timestamp,return_to]).

  • Always test on a test node before entering anything to a live node's shell!
  • It is most advised to have a test node or replica node to try the scripts first.
    That said let's have a look at a basic tracing command sequence:
    <1>dbg:stop_clear().
  • Always start by flushing trace ports and ensuring that no previous tracing interferes with the current trace.
    <2>dbg:tracer().
  • Start the tracer process.
    <3>dbg:p(all,[call, timestamp]).
  • In this case we are tracing for all processes and for function calls.
    <4>dbg:tp( ... ).
  • As seen in Zed's answer.
    <5>dbg:tpl( ... ).
  • As seen in Zed's answer.
    <42>dbg:stop_clear().
  • Again it is to ensure that all traces were written to the output and to evade any later inconvenience.
    You can:
  • add triggers by defining some fun()-s in the shell to stop the trace at a given time or event. Recursive fun()-s are the best to achieve this, but be very careful when applying those.
  • apply a vast variety of pattern matching to ensure that you only trace for the specific process with the specific function call with the specific type of arguments...

I had an issue a while back, when we had to check the content of an ETS table and on appearance of a certain entry we had to stop the trace within 2-3 minutes.
I also suggest the book Erlang Programming written by Francesco Cesarini. ( Erlang Programming @ Amazon )

e5nszbig

e5nszbig3#

“dbg”模块是相当低级的东西。有两个黑客,我经常使用的任务,我通常需要。
1.使用http://www.snookles.com/erlang/user_default.erl的Erlang CLI/shell扩展代码。据我所知,它最初是由Serge Aleynikov编写的,是一个有用的“所以这就是我如何向shell添加自定义函数”的例子。编译模块并编辑你的~/.erlang文件,指向它的路径(见文件顶部的注解)。
1.使用EPER实用程序集合中捆绑的“redbug“实用程序。使用”dbg“在几秒钟内创建数百万个跟踪事件是非常容易的。在生产环境中这样做可能是灾难性的。对于开发或生产使用,redbug使得几乎不可能通过跟踪引发的过载来杀死正在运行的系统。

xggvc2p6

xggvc2p64#

如果你更喜欢图形化的跟踪器,那么试试erlyberly。它允许你选择你想跟踪的函数(目前在所有进程上),并处理dbg API。
但是,它不能防止过载,因此不适用于生产系统。

相关问题