如何编译和调试自定义ejabberd模块的Erlang代码?
针对ejabberd 18.01自定义模块调试的优化方案
一、VSCode远程调试配置
- 安装VSCode的Erlang Language Support插件,替代erlide。
- 修改ejabberd启动脚本,添加调试参数:
在启动命令中加入+debugger +start_debugger,或追加-s debugger start,确保ejabberd节点开启调试端口。 - 配置VSCode的
launch.json(Ctrl+Shift+D打开调试面板,点击创建launch.json文件):
节点cookie可在ejabberd配置文件中查找(默认路径{ "version": "0.2.0", "configurations": [ { "name": "Attach to Ejabberd", "type": "erlang", "request": "attach", "node": "ejabberd@<你的服务器IP>", "cookie": "<ejabberd节点cookie>", "port": 10137 } ] }/etc/ejabberd/ejabberd.yml),节点名默认是ejabberd@localhost,调试端口默认10137,可按需修改。 - 在自定义模块源码中设置断点,启动调试会话后,VSCode会远程连接到ejabberd节点,触发断点时可查看变量、进程状态,无需重启服务器。
二、Erlang热加载替代全节点重启
利用Erlang的代码热加载特性,避免每次修改都重启ejabberd:
- 编译自定义模块后,通过ejabberd节点shell执行
l(<模块名>).直接加载新编译的.beam文件。 - 结合已有的inotify监控,编写简单shell脚本实现自动热加载:
执行该脚本后,每次编译生成新的# 监控编译目录的beam文件变化 inotifywait -m -e close_write /path/to/your/compiled/ebin | while read -r directory events filename; do if [[ $filename == *.beam ]]; then # 提取模块名(去掉.beam后缀) MODULE=${filename%.beam} # 远程调用ejabberd节点加载模块 erl -sname temp_loader -setcookie <你的节点cookie> -eval " rpc:call(ejabberd@<服务器IP>, code, load_file, ['$MODULE']), init:stop(). " fi done.beam文件,会自动触发热加载,无需手动复制和重启。
三、本地一致环境调试
搭建与生产完全一致的本地ejabberd环境,减少远程调试的延迟:
- 下载ejabberd 18.01源码,在本地Ubuntu 20.04环境(Erlang OTP 20.02)编译安装,确保依赖与生产一致。
- 将自定义模块源码放在单独目录,编译时指定ejabberd的头文件路径:
erlc -I /path/to/ejabberd/include -o /path/to/local/ebin your_module.erl - 启动本地ejabberd调试节点,直接通过
ejabberdctl debug进入节点shell,使用以下命令调试:i():查看所有进程信息process_info(<进程PID>):查看指定进程的状态、栈信息sys:get_status(<进程PID>):获取进程的状态详情
四、原生Erlang调试工具进阶用法
- dbg模块:在ejabberd shell中开启函数调用追踪,无需额外工具:
% 开启追踪器 dbg:tracer(). % 追踪所有进程的函数调用(含参数) dbg:p(all, c). % 仅追踪目标模块的指定函数 dbg:tpl(your_module, your_function, x). % 停止追踪 dbg:stop(). - redbug工具:如果不想引入rebar3,可单独编译redbug源码,它比dbg更易用:
编译redbug后,在ejabberd shell中执行:
实时查看函数的调用参数和返回值,调试完成后执行redbug:start("your_module:your_function -> return").redbug:stop()关闭。
内容的提问来源于stack exchange,提问作者Athena
相关产品推荐
相关产品推荐

