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:
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!
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 )
4条答案
按热度按时间nue99wik1#
The basic steps of tracing for function calls are on a non-live node:
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 calltpl
. To remove functions, callctp
orctpl
in a similar manner. Some general tp calls are: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:
I guess you will never need to directly call
erlang:trace
, asdbg
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:
If you are looking for debugging on remote nodes (or multiple nodes), search for
pan
,eper
,inviso
oronviso
.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:
dbg:p(all,[call,timestamp,return_to]).
That said let's have a look at a basic tracing command sequence:
<1>
dbg:stop_clear().
<2>
dbg:tracer().
<3>
dbg:p(all,[call, timestamp]).
<4>
dbg:tp( ... ).
<5>
dbg:tpl( ... ).
<42>
dbg:stop_clear().
You can:
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 )
e5nszbig3#
“dbg”模块是相当低级的东西。有两个黑客,我经常使用的任务,我通常需要。
1.使用http://www.snookles.com/erlang/user_default.erl的Erlang CLI/shell扩展代码。据我所知,它最初是由Serge Aleynikov编写的,是一个有用的“所以这就是我如何向shell添加自定义函数”的例子。编译模块并编辑你的~/.erlang文件,指向它的路径(见文件顶部的注解)。
1.使用EPER实用程序集合中捆绑的“redbug“实用程序。使用”dbg“在几秒钟内创建数百万个跟踪事件是非常容易的。在生产环境中这样做可能是灾难性的。对于开发或生产使用,redbug使得几乎不可能通过跟踪引发的过载来杀死正在运行的系统。
xggvc2p64#
如果你更喜欢图形化的跟踪器,那么试试erlyberly。它允许你选择你想跟踪的函数(目前在所有进程上),并处理dbg API。
但是,它不能防止过载,因此不适用于生产系统。