如果我编写一些 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() 的调用。
所有虚拟机都说“init terminate in do boot”,然后显示错误匹配的错误位置、精确文件和我的顶级模块(myapp)的行。
(不匹配,因为 ok = application:start(...) 不匹配)。
我查看了 erl_crash.dump 文件,没有关于这个未定义函数的信息(但我在原子列表中找到了它)。
因此,我写了一些日志来大致了解错误在哪里,但随后我必须手动启动我的 gen_servers 才能获取正确的错误信息。
我错过了什么,我怎样才能更快地找到它?
谢谢
最佳答案
如果您的应用程序调用未知模块,您的 erl_crash.dump
文件将包含如下一行:
41DABB8:t4:A8:nonexistent_module,A7:unknown,N,N
行中的“unknown”表示找不到模块nonexistent_module
。在这些情况下,在 erl_crash.dump
文件中搜索字符串“unknown”会有所帮助。
如果您怀疑某个模块调用了不存在的函数,您可以使用 the xref tool 找到它在交互式 erl shell 中。确保使用调试信息编译模块(通常通过 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
中定义。
您还可以使用外部参照
来检查整个应用程序;请参阅the documentation了解详情
关于debugging - 如何调试无法启动的 erlang 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14513012/