vscode调试分布式elixir/erlang节点必须使用type: "erlang"而非"mix_task",因后者仅启动单节点隔离环境,node.self()返回:nonode@nohost导致node.connect/1静默失败;而erlang-ls的"erlang"类型通过erl启动带名节点并注入调试钩子,配合正确配置的node、setcookie、startfun等字段,才能可视化多节点通信与otp进程状态。

erlang-ls 的 launch.json 必须用 type: "erlang",不是 "mix_task"
VSCode 里调试分布式 Elixir/Erlang 节点,type: "mix_task" 是陷阱。它启动的是单节点、无名、Node.self() 返回 :nonode@nohost 的隔离环境,所有 Node.connect/1 静默失败,Node.list() 永远为空。
真正能看见多节点通信、进程消息队列、端口监听状态的,只有 erlang-ls 提供的 type: "erlang" 调试器。它底层调用 erl 启动带名节点,并注入调试钩子。
-
node字段必须是完整节点名,如"test@127.0.0.1"或远程主机可解析的域名(不能只写"test") -
setcookie值必须与目标节点完全一致,大小写敏感,且不能含空格或特殊字符 -
startFun推荐设为"application:start",startArgs传入应用名原子列表,如"[myapp]" - 若需手动触发分布式初始化,可在
startFun中写"rpc:call('other@host', application, start, [myapp])",但前提是两节点已连通
远程节点必须先手动启动并验证连通性
VSCode 不负责启动远程 Erlang 节点,只 attach 到已运行的节点。你得先在远程机器上跑通这行命令:
erl -name myapp@remote.host -setcookie abc -hidden -noshell -s application start myapp
然后本地验证是否能连上:
- 本地终端执行
erl -name test@127.0.0.1 -setcookie abc,进 shell 后运行net_adm:ping('myapp@remote.host').→ 返回pong才算通 - 检查远程防火墙:EPMD 端口(默认
4369)和 Erlang 分布式端口段(默认9000-9100)必须放行 - 确认远程主机的
/etc/hosts或 DNS 能反向解析myapp@remote.host的 IP,ping remote.host必须通 - 远程节点不能加
-hidden参数?那得去掉——-hidden节点不注册到 EPMD,本地根本发现不了它
vscode 集成终端里启动远程节点时,PATH 和 erl 版本容易错配
你在 VSCode 终端里 ssh 连远程并执行 erl -name ...,看似简单,实则常因环境变量失效而失败。常见现象是:crypto:start() 报错、ssl:start() 找不到模块、甚至 erl 命令本身不存在。
- 别依赖远程 shell 的
~/.zshrc—— ssh 非交互式登录不加载它;改用ssh user@host 'bash -l -c "erl -version"'强制加载 login shell - 远程
which erl返回的路径,要和本地erlang.erlPath配置一致;否则erlang-ls会尝试用本地erl去解析远程 BEAM 字节码,版本不兼容直接崩溃 - OTP 版本必须严格一致:远程是
26.3,本地erl也得是26.3;混用25.x和26.x会导致:beam_lib.chunks/2解析失败,调试器卡死在 “Connecting…” - Mac 上用 asdf?确保远程也装了 asdf,并执行
asdf reshim erlang,否则erl软链接可能指向旧版
调试器连上了,但 Processes 标签页空、Node.list() 不返回远程节点
这是最让人抓狂的假连通:VSCode 显示 “Debug session started”,断点也能命中,但看不到 OTP 进程树、收不到消息日志、Node.list() 只有本地节点——说明分布式上下文根本没激活。
- 检查
launch.json里是否漏了"node"字段;没有它,erlang-ls默认以nonode@nohost启动,和 mix_task 一样废 - 确认远程节点启动时用了
-name(非-sname),-sname节点无法跨网络通信,仅限 localhost - 本地节点和远程节点的
-setcookie值是否真的一致?复制粘贴时容易多一个不可见空格;建议用echo -n "abc" | md5sum两端比对哈希 -
erlang-ls的调试视图依赖:observer.start/0的底层接口;如果远程节点没启用inets或stdlib应用,进程树可能无法渲染——加个-eval "application:ensure_all_started(inets)."再试
分布式调试不是“配置完就能跑”,它要求每个环节的网络、命名、cookie、OTP 版本都咬合严丝合缝。少一个 @ 符号,或一次没清掉旧 EPMD 进程,就卡在无声失败里。











