如何调试无法启动的erlang应用程序

Posted

技术标签:

【中文标题】如何调试无法启动的erlang应用程序【英文标题】:How to debug an erlang application that won't boot 【发布时间】:2013-01-08 21:32:49 【问题描述】:

如果我编写一些 erlang 代码来构建监督树,然后在启动时使用以下命令启动应用程序,可能很难找出它为什么不起作用:

erl -s myapp -pa ebin ... ...

(myapp 示例模块)

-module(myapp).
-export([start/0]).
start() -> application:start(myapp).

假设我的应用启动了主管 myapp_sup。 myapp_sup 轮流启动多个主管(比如说 server_sup、database_sup、another_sup)。

这些主管将启动一些 gen_servers。

在某些时候,如果我的代码有错误,我找不到它!

我在一些 gen_server 的 init 回调中写了一个对 somemodule:functionthatdoesntexists() 的调用。

所有 vm 都说“init terminating in do boot”,然后显示错误匹配的错误位置、精确文件和我的***模块 (myapp) 的行。

(不匹配,因为 ok = application:start(...) 将不匹配)。

我查看了 th erl_crash.dump 文件,没有关于这个未定义函数的信息(但我在原子列表中找到了它)。

所以,我写了一些日志来大致查看错误在哪里,但是我必须手动启动我的 gen_servers 以获取正确的错误信息。

我错过了什么,我怎样才能更快地弄清楚?

谢谢

【问题讨论】:

【参考方案1】:

如果您的应用程序调用未知模块,您的erl_crash.dump 文件将包含如下一行:

41DABB8:t4:A8:nonexistent_module,A7:unknown,N,N

行中的“unknown”表示找不到模块nonexistent_module。在这些情况下,在您的 erl_crash.dump 文件中搜索字符串“unknown”会有所帮助。

如果您怀疑某个模块调用了一个不存在的函数,您可以在交互式 erl shell 中使用the xref tool 找到它。确保使用调试信息(通常通过erlc +debug_info)编译模块,然后:

1> xref:m(my_module).
[deprecated,[],
 undefined,[my_module,init,1,another_module,unknown,0],
 unused,[]]

这里,xref 向我们展示了my_module:init/1 函数调用了another_module:unknown/0 函数,但unknown/0 函数未在another_module 中定义。

您也可以使用xref 来检查整个应用程序;详情见the documentation

【讨论】:

感谢您的回答。但我没有和你一样的输出。既不是不存在的模块,也不是实际模块中不存在的功能。我已将外部参照添加到我的生成文件中,使用钢筋很容易,谢谢。但是问题仍然存在,假设我拼错了数据库监听的端口......问题是你不知道大部分时间你正在寻找的错误是什么。 我上面显示的输出是使用 Erlang/OTP R15B03 (erts 5.9.3.1) 获得的;也许你的版本不同。 您还应该考虑为您的模块实施单元测试,因为它们可以很好地发现诸如拼写错误的原子或其他名称等问题。 相同的版本,不同的配置我想。你说得对,我真的应该去 TDD。我在 Erlang 中不习惯,我会尝试一下。 这几天我开发了一个小型应用程序,我从 eunit 开始。在测试期间,Eunit 不会因为晦涩的消息而失败,而是会为我提供发生错误的确切代码行。这是非常好的。再次感谢。【参考方案2】:

将 -init_debug 添加到您的 erl 命令中:)

【讨论】:

谢谢,但这并不能解决问题:来自用户代码的错误不会在引导顺序中发生。他们紧随其后。使用“-init_debug”没有关于我的 undef 函数的更多信息。

以上是关于如何调试无法启动的erlang应用程序的主要内容,如果未能解决你的问题,请参考以下文章

Erlang/Yaws:无法使用 .conf 文件在应用程序中启动 Web 服务器

Erlang:守护进程“init.d”脚本无法启动

RabbitMQ无法启动,TCP连接成功但Erlang分发失败

无法开始调试。启动项目无法启动

使用VS2013调试C语言时出错,连简单的Hello World都报错,调试时显示无法启动程序,无法访问

尝试启动“应用程序名称”时,无法在“D's iPhone”上启动调试服务器[关闭]