【问题标题】:How to debug processes in Erlang如何在 Erlang 中调试进程
【发布时间】:2019-09-23 02:07:15
【问题描述】:

您好,我正在运行一个问题,我从一个链接的进程中得到一个错误。我不知道如何调试进程中出了什么问题。 我启用了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,[],[]}]}

如何读取错误?那么返回元组中的undef是什么,元组的第二个元素中的两个[]是什么? 我可以理解brother 方法中发生的一些事情,但我无法理解。

如何在 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.

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

后期编辑:
我还尝试将 PID 传递给 Shell 的 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

【问题讨论】:

    标签: debugging process erlang


    【解决方案1】:

    当您发布问题时,您需要显示您在 shell 中所做的一切,以获得您发布的结果。例如,您没有显示 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 未使用的警告意味着模块内没有定义函数调用该函数,并且因为 brother/0 没有导出,所以模块外定义的函数不能调用 brother/0,因此 brother/0 永远无法执行。

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

    【讨论】:

    • 我想如果它们在同一个模块中,我不需要公开函数,或者spawn 不在乎,我必须导出它?
    • spawnerlang 模块中,因此除非您导出它,否则它无法使用模块+函数+args 调用看到您的函数。但是,如果您不想导出它,则可以改为调用spawn/1 并传递一个乐趣,如spawn(fun brother/0)
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      1> c(test, [debug_info]).
      

      然后你需要运行调试:

      2> debug:start().
      

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

      【讨论】:

        猜你喜欢
        • 2020-12-22
        • 2010-11-19
        • 2021-12-03
        • 1970-01-01
        • 1970-01-01
        • 2022-01-15
        • 2012-05-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多