如何在 Erlang 中调试进程

How to debug processes in Erlang

你好,我是 运行 一个问题,我从一个链接中得到一个错误 process.I 不知道如何调试进程中的错误。 我已经启用 process_flag(trap_exit,true) 但仍然无法弄清楚问题所在。

错误

30> conc2:initFam().                 
<0.170.0>
=ERROR REPORT==== 24-Aug-2019::07:55:03.403000 ===
Error in process <0.170.0> with exit value:
{undef,[{conc2,brother,[],[]}]}

How can the error be read?So what is undef in the return tuple,and what are the two [] in the second element of the tuple ? I can understand something happened in brother method but more i can't understand.

如何在 Erlang 中调试进程?

-module(conc2).
-compile([debug_info]).
-export([initFam/0]).


initFam()->
    Bid=spawn(?MODULE,brother,[]),
    Bid. 



brother()->

    Sid=spawn(?MODULE,sister,[self()]),
    link(Sid),
    brotherLoop(Sid).

brotherLoop(Sid)->
    receive   
        kill->Sid ! issue_kill;
        Msg->[Msg|brotherLoop(Sid)]
    end.

sister()->
    receive
        MSG ->
             exit(killed_by_bro)
    end.

基本上,我生成一个进程,该进程又生成另一个进程并链接到它,第一个进程被递归调用以侦听终止消息。

稍后编辑:
我还尝试将 Shell 的 PID 传递给 brother 进程,以便查看它在哪一行崩溃,但我仍然无法收到消息:

initFam()->
    Bid=spawn(?MODULE,brother,[self()]),
    Bid. 



brother(Shell)->
    Shell! i_m_here,
    Sid=spawn(?MODULE,sister,self()),
    link(Sid),
    brotherLoop(Sid).`

如您所见,我仍然无法从 brother 收到任何消息,我不应该在它崩溃之前收到消息吗?

41> conc2:initFam().                 
<0.203.0>
=ERROR REPORT==== 24-Aug-2019::08:13:31.662000 ===
Error in process <0.203.0> with exit value:
{undef,[{conc2,brother,[<0.196.0>],[]}]}
42> flush().
ok

当你 post 一个问题时,你需要展示你在 shell 中所做的一切才能得到你 post 编辑的结果。例如,您没有显示 shell 命令来编译您的模块。如果你有,它会显示这个输出:

1> c(conc2).
conc2.erl:12: Warning: function brother/0 is unused
conc2.erl:18: Warning: function brotherLoop/1 is unused
conc2.erl:24: Warning: function sister/0 is unused
conc2.erl:26: Warning: variable 'MSG' is unused

是什么让您认为这不重要?? brother/0 is unused 的警告意味着模块内没有定义的函数调用该函数,并且因为 brother/0 没有导出,所以模块外定义的函数都不能调用 brother/0,所以 brother/0永远无法执行。

当您 spawn() 函数时,必须导出该函数,因此出现 undef 错误消息。

您收到未定义的函数错误,很可能是因为如果函数未导出则无法生成进程。

要使用 spawn,您需要导出您尝试通过 spawn 调用的函数。但是如果你需要调试一个模块,你需要用标志 debug_info 编译模块,例如 test.erl:

1> c(test, [debug_info]).

然后你需要运行调试:

2> debug:start().

然后您可以选择您的模块进行调试。手册中的更多信息:http://erlang.org/doc/apps/debugger/debugger_chapter.html