在Erlang中使用trace和dbg

Gor*_*rie 66 debugging erlang trace

我试图开始使用erlang:trace/3和dbg模块来跟踪实时生产系统的行为,而无需关闭服务器.

文件不透明的(说得客气一点),而且不会出现任何有用的在线教程.

我花了一整天努力做的是通过尝试将跟踪应用于模块来捕获特定函数中发生的事情:使用dbg:c和dbg:p的函数但是根本没有成功...

有没有人对如何在实时Erlang系统中使用跟踪有简洁的解释?

Zed*_*Zed 92

跟踪函数调用的基本步骤是在非活动节点上:

> 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.
Run Code Online (Sandbox Code Playgroud)

您可以同时跟踪多个功能.通过调用tp每个函数来添加函数.如果要跟踪未导出的函数,则需要调用tpl.要删除功能,请致电ctpctpl以类似方式.一些通用的tp调用是:

> 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.
Run Code Online (Sandbox Code Playgroud)

最后一个参数是匹配规范.你可以通过使用来解决这个问题dbg:fun2ms.

您可以通过调用p()来选择要跟踪的进程.这些项目在erlang:trace下描述.有些电话是:

> 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
Run Code Online (Sandbox Code Playgroud)

我猜你永远不需要直接打电话erlang:trace,dbg几乎所有东西都适合你.

实时节点的黄金法则是仅生成一定量的跟踪输出到shell,这样您就可以输入dbg:stop_clear()..:)

我经常使用一个跟踪器,它会在一些事件后自动停止.例如:

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

如果您正在寻找在远程节点(或多个节点)调试,搜索pan,eper,invisoonviso.

  • 到目前为止,我还无法跟踪将任何信息发送到外壳:( (2认同)
  • 跟踪需要系统提供一些资源。如果您跟踪频繁的事件,您的性能可能会受到影响。在最坏的情况下,您将失去联系,并且会发生“轰隆”。 (2认同)
  • 实际上,您可以使用dbg进行集群/远程节点调试.`dbg:n(Node)`设置`Node`用于跟你所在节点相同的跟踪. (2认同)

cdl*_*dlf 22

在实时系统上,我们很少追溯到shell.如果系统配置良好,那么它已经收集了打印到shell的Erlang日志.我不必强调为什么这在任何实时节点中都至关重要......

让我详细说明跟踪文件:

可以跟踪到文件,这将生成可以在以后转换和解析的二进制输出.(用于进一步分析或自动控制系统等)

一个例子可能是:

  • 跟踪包装的多个文件(12x50 MB).在使用这么大的跟踪之前,请务必检查可用的磁盘空间!

    dbg:tracer(port,dbg:trace_port(file,{"/log/trace",wrap,atom_to_list(node()),50000000,12})).
    
    Run Code Online (Sandbox Code Playgroud)

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

    • 在向活动节点的shell输入任何内容之前,始终在测试节点上进行测试!
    • 建议首先使用测试节点或副本节点来尝试脚本.

那就说让我们看一下基本的跟踪命令序列:

<1> dbg:stop_clear().

  • 始终首先刷新跟踪端口并确保先前的跟踪不会干扰当前跟踪.

<2> dbg:tracer().

  • 启动跟踪器进程.

<3> dbg:p(all,[call, timestamp]).

  • 在这种情况下,我们将跟踪所有进程和函数调用.

<4> dbg:tp( ... ).

  • 正如Zed的回答所示.

<5> dbg:tpl( ... ).

  • 正如Zed的回答所示.

<42> dbg:stop_clear().

  • 同样,它要确保所有迹线都写入输出并避免任何后来的不便.

您可以:

  • 通过在shell中定义一些fun() - s来添加触发器,以在给定时间或事件处停止跟踪.递归fun() - s是最好的实现这一点,但在应用它们时要非常小心.

  • 应用各种各样的模式匹配,以确保您只使用特定类型的参数跟踪具体函数调用的特定进程...

我有一个问题,当我们不得不检查ETS表的内容和某个条目的外观时,我们必须在2-3分钟内停止跟踪.

我还建议由Francesco Cesarini编写的Erlang Programming一书.(Erlang编程@亚马逊)


Sco*_*hie 9

'dbg'模块是非常低级的东西.我经常使用两种黑客来完成我经常需要的任务.

  1. http://www.snookles.com/erlang/user_default.erl上使用Erlang CLI/shell扩展代码.它最初由Serge Aleynikov编写(据我所知)并且是一个有用的"这就是我如何向shell添加自定义函数"的例子.编译模块并编辑〜/ .erlang文件以指向其路径(请参阅文件顶部的注释).

  2. 使用EPER实用程序集合中捆绑的" redbug "实用程序.使用'dbg'可以在几秒钟内创建数百万个跟踪事件.在生产环境中这样做可能是灾难性的.对于开发或生产用途,redbug几乎不可能杀死具有迹线引起的过载的运行系统.


And*_*ill 7

如果您更喜欢图形跟踪器,那么请仔细尝试.它允许您选择要跟踪的函数(目前在所有进程上)并处理dbg API.

但是它不能防止过载,因此不适用于生产系统.

在此输入图像描述