ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

【Bug已解决】openclaw daemon crashed / SIGSEGV segfault — OpenClaw 守护进程崩溃解决方案:把 Codex auth.json 改到 TaoTok

【Bug已解决】openclaw daemon crashed / SIGSEGV segfault — OpenClaw 守护进程崩溃解决方案:把 Codex auth.json 改到 TaoTok 1. OpenClaw 守护进程 SIGSEGV 崩溃现场还原OpenClaw 守护进程崩溃、SIGSEGV segfault 这类问题本质是进程访问了非法内存地址操作系统直接发信号 11 把它干掉。你看到的daemon crashed、Process exited with signal 11、Segmentation fault at address 0x0000000000000000都是同一个根因的不同表现。它适合谁适合把 OpenClaw 当常驻服务跑、用 Codex 做代码补全或 Agent 任务、又不想每次崩溃都手动重启的开发者。我先把最典型的三种崩溃现场摆出来你可以对照自己的日志。第一种是启动即崩$ openclaw --daemon-start Error: daemon crashed Process exited with signal 11 (SIGSEGV) Segmentation fault at address 0x0000000000000000 Core dumped to: /var/core/openclaw.core.12345第二种是执行复杂任务时崩$ openclaw 执行复杂分析 Error: SIGSEGV segfault Invalid memory access PC: 0x00007fff12345678 SP: 0x00007ffee87654320 Fault address: 0x0000000000000010第三种是守护进程状态查询暴露的崩溃历史$ openclaw --daemon-status Error: daemon not running Last exit: SIGSEGV (signal 11) Restart count: 5 Uptime before crash: 3600s Crash log: .openclaw/logs/crash_20240707.log注意Fault address: 0x0000000000000010这个细节。地址接近 0 通常意味着空指针加偏移量解引用比如访问一个结构体成员时基址是 NULL。而heap corruption detected、malloc(): corrupted top size则指向堆内存被写坏常见于原生模块双重释放或越界写。为什么 JavaScript 代码不会直接段错误但 OpenClaw 会因为 JS 跑在 V8 沙箱里越界会被引擎拦住。真正捅娄子的是通过 N-API 调用的 C/C 原生模块它们直接操作内存一旦有 bug 就是 SIGSEGV。按经验分布原生模块 bug 约占三成内存泄漏累积到 OOM 再触发段错误约占四分之一剩下是空指针、数据竞争、栈溢出和库 ABI 不兼容。这里有个容易被忽略的点崩溃往往不是单一原因。长时间运行后内存碎片化加上某个原生模块的边界处理不严两者叠加才炸。所以排查时既要看崩溃瞬间的调用栈也要看崩溃前的内存曲线。我试过只盯着崩溃日志改代码结果忽略了内存增长趋势改完还是崩。后来把崩溃分析和内存监控一起做才定位到是某个.node模块在处理大输入时泄漏。下面几节我会把配置、验证、排障串成一条可跟做的路径并且把 Codex 的auth.json统一改到 TaoToken 通道减少因为多套 Key 配置混乱带来的额外变量。2. 把 Codex auth.json 统一到 TaoToken 通道在排查守护进程崩溃之前先把模型调用通道收敛掉。很多人的 OpenClaw 同时配了好几套 Key环境变量、auth.json、项目配置各写一份出问题时根本分不清是通道问题还是进程问题。把 Codex 的auth.json统一指向 TaoTokenBase URL、Key、Model ID 三件套只维护一份崩溃排查时就能排除掉鉴权层干扰。TaoToken 的 API 入口是https://taotoken.net/api官网在https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。你需要先去控制台生成一个 API Key地址是https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteKey 管理页在https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite。生成后复制出来下面配置要用。Codex 的auth.json一般放在~/.codex/auth.jsonWindows 在%USERPROFILE%\.codex\auth.json。先备份原文件cp ~/.codex/auth.json ~/.codex/auth.json.bak然后写入统一配置。注意base_url结尾不要多加/v1TaoToken 的兼容层会自己处理路径{ OPENAI_API_KEY: sk-你的TaoToken密钥, OPENAI_BASE_URL: https://taotoken.net/api, model: gpt-5-codex, provider: openai-compatible, timeout: 60000, max_retries: 3 }如果你用的是新版 Codex CLI配置可能拆在~/.codex/config.toml里那就写成 TOMLmodel gpt-5-codex model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chat对应地把 Key 放进环境变量避免明文散落export TAOTOKEN_API_KEYsk-你的TaoToken密钥如果你同时用 Claude Code它的配置在~/.claude/settings.json可以写成{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的TaoToken密钥, ANTHROPIC_MODEL: claude-sonnet-4-5 } }这里要强调三件套必须齐全Base URL 指向https://taotoken.net/apiKey 用刚生成的Model ID 写你实际要调的模型名。少任何一个OpenClaw 在调用时就会报鉴权或模型不存在日志里混进这些错误会干扰你对 SIGSEGV 的判断。配置改完先别急着起守护进程用一次前台请求验证通道通不通codex exec print(channel ok) --model gpt-5-codex返回正常输出说明通道没问题接下来崩溃就只可能是进程本身的事。这一步的价值在于把变量隔离不然你会在「到底是 Key 错了还是进程崩了」之间反复横跳。3. 可复制的守护进程配置与崩溃恢复通道确认后进入守护进程本身的配置。核心思路是三层防护进程管理器负责拉起OpenClaw 自身负责退避重启内存配置负责减少崩溃概率。先配 OpenClaw 的daemon段。路径是.openclaw/config.json用脚本改比手改安全python3 -c import json with open(.openclaw/config.json, r) as f: config json.load(f) config[daemon] { autoRestart: True, maxRestarts: 10, restartDelay: 5000, backoffMultiplier: 2, maxRestartDelay: 60000, resetCountAfter: 3600000, crashLog: True, crashLogDir: .openclaw/logs/crashes/, coreDump: True, coreDumpDir: /var/core/, gracefulShutdown: True, shutdownTimeout: 10000, healthCheck: { enabled: True, interval: 30000, timeout: 5000, unhealthyThreshold: 3 } } with open(.openclaw/config.json, w) as f: json.dump(config, f, indent2) print(daemon 配置写入完成) backoffMultiplier: 2配合maxRestartDelay: 60000意味着重启间隔从 5 秒开始翻倍最多到 60 秒。这样如果崩溃是持续性的不会疯狂重启把日志刷爆。接着配内存安全这是减少 SIGSEGV 的关键python3 -c import json with open(.openclaw/config.json, r) as f: config json.load(f) config[memory] { maxHeapSize: 4096, maxOldSpace: 2048, maxYoungSpace: 256, maxStackSize: 8, gcInterval: 30000, oomProtection: True, memoryLeakDetection: True, leakThreshold: 104857600, leakCheckInterval: 300000, autoRestartOnLeak: True, heapSnapshot: { enabled: True, onSignal: True, signal: SIGUSR2, snapshotDir: .openclaw/heapdump/ } } with open(.openclaw/config.json, w) as f: json.dump(config, f, indent2) print(memory 配置写入完成) leakThreshold设成 100MBleakCheckInterval是 5 分钟。意思是每 5 分钟对比一次堆增长超过 100MB 就判定泄漏并触发重启。这比等到 OOM 再崩要主动得多。然后用 systemd 兜底路径/etc/systemd/system/openclaw.service[Unit] DescriptionOpenClaw Daemon Afternetwork.target [Service] Typesimple ExecStart/usr/local/bin/openclaw --daemon Restartalways RestartSec5 RestartPreventExitStatus0 LimitCOREinfinity LimitNOFILE65536 WorkingDirectory/opt/openclaw Useropenclaw Groupopenclaw EnvironmentNODE_ENVproduction EnvironmentNODE_OPTIONS--max-old-space-size4096 TimeoutStopSec30 [Install] WantedBymulti-user.targetLimitCOREinfinity是让核心转储能写出来Restartalways保证任何退出都被拉起。加载并启动sudo systemctl daemon-reload sudo systemctl enable openclaw sudo systemctl start openclaw如果你更习惯 PM2ecosystem.config.js这样写module.exports { apps: [{ name: openclaw, script: /usr/local/bin/openclaw, args: --daemon, instances: 1, autorestart: true, max_restarts: 10, restart_delay: 5000, exp_backoff_restart_delay: 100, max_memory_restart: 4G, kill_timeout: 10000, error_file: .openclaw/logs/error.log, out_file: .openclaw/logs/output.log, merge_logs: true, env: { NODE_ENV: production, NODE_OPTIONS: --max-old-space-size4096 } }] };启动命令pm2 start ecosystem.config.js pm2 save pm2 startup。max_memory_restart: 4G和前面的堆上限对齐超过就重启避免走到段错误那一步。最后开核心转储Linux 下echo /var/core/core.%e.%p.%t | sudo tee /proc/sys/kernel/core_pattern sudo mkdir -p /var/core sudo chmod 1777 /var/core ulimit -c unlimitedmacOS 用sudo sysctl kern.corefile/var/core/core.%P。核心转储是后面用 GDB 分析调用栈的原料不开就只能看文本日志。4. 验证请求与崩溃日志确认配置写完必须验证否则你不知道是配置生效了还是进程压根没起来。分三步确认进程活着、发一次真实请求、检查崩溃日志目录。先看 systemd 状态sudo systemctl status openclaw正常输出里应该有Active: active (running)并且Restart计数没有异常增长。如果看到activating (auto-restart)反复出现说明进程在崩溃循环直接跳到第 5 节排障。再确认守护进程自身状态openclaw --daemon-status期望输出类似Daemon: running PID: 12345 Uptime: 120s Restart count: 0 Last exit: noneRestart count: 0和Last exit: none是关键说明这段时间没崩过。然后发一次真实请求验证通道和进程都正常openclaw 分析这段代码的时间复杂度 --timeout 60000返回结果正常说明从请求入口到模型通道整条链路通了。如果这里报鉴权错误回到第 2 节检查auth.json三件套如果报 SIGSEGV说明崩溃发生在处理阶段继续看日志。检查崩溃日志目录ls -lt .openclaw/logs/crashes/ | head -5如果目录为空说明配置生效后没再崩。如果有新文件打开看信号和调用栈cat .openclaw/logs/crashes/crash_*.log | head -50重点看三行signal:是几号信号fault address:是多少Backtrace:里第一个非系统帧是哪个模块。信号 11 是 SIGSEGV信号 6 是 SIGABRT 通常伴随堆损坏信号 9 是 SIGKILL 多半是 OOM。再验证内存监控是否工作。触发一次堆快照kill -USR2 $(cat .openclaw/daemon.pid) ls -lh .openclaw/heapdump/能看到.heapsnapshot文件生成说明heapSnapshot配置生效。这个文件可以用 Chrome DevTools 的 Memory 面板打开对比两次快照就能看出哪个对象在持续增长。最后跑一个持续负载观察一段时间内的稳定性for i in $(seq 1 20); do openclaw 任务 $i: 生成一个排序函数 --timeout 30000 sleep 3 done openclaw --daemon-status20 次请求后Restart count仍为 0Uptime持续增长基本可以认为守护进程稳定。如果中途崩了日志会告诉你崩在第几次、什么信号。5. 常见报错对照排查这一节按真实报错逐条对照你直接搜关键词就能定位。401 Unauthorized / invalid api key这不是崩溃是通道问题。检查~/.codex/auth.json里的OPENAI_API_KEY是否和 TaoToken 控制台生成的一致OPENAI_BASE_URL是否为https://taotoken.net/api。注意别把官网地址填进 Base URLAPI 入口不带路径后缀以外的内容。改完重启守护进程。local proxy failed / connection refused说明 OpenClaw 尝试连本地代理但没连上。检查是否有残留的代理环境变量env | grep -i proxy如果有HTTP_PROXY、HTTPS_PROXY指向一个已经关掉的本地端口unset 掉再重启。守护进程继承的环境变量和你的 shell 可能不一样systemd 里可以用Environment显式清空。Error reading choices / unexpected response format通常是 Base URL 写错导致返回了 HTML 而不是 JSON。用 curl 直接验证curl -s https://taotoken.net/api/models \ -H Authorization: Bearer sk-你的密钥 | head -20返回 JSON 说明通道对返回 HTML 说明路径错了。确认auth.json里没有多余的/v1或/chat/completions后缀。OAuth token expired / refresh failedCodex 某些模式会走 OAuth如果你混用了 OAuth 和 API Key 会冲突。统一用 API Key 模式删掉auth.json里的tokens字段只保留OPENAI_API_KEY和OPENAI_BASE_URL。SIGSEGV 反复出现且 Backtrace 指向 .node 文件这是原生模块 bug。先列出模块openclaw --list-native-modules找到可疑模块后单独测试node -e require(better-sqlite3); console.log(load ok)如果这行就崩模块本身有问题。尝试npm rebuild better-sqlite3重新编译或者换纯 JS 替代品比如better-sqlite3换sql.jssharp换jimp。heap corruption detected / malloc(): corrupted top size堆被写坏多半是双重释放或越界写。这种崩溃用核心转储分析最有效gdb -batch -ex bt -ex info registers \ $(which node) /var/core/core.openclaw.*看bt输出的前几帧定位到具体函数。如果是第三方模块升级到最新版如果是自己写的 N-API 代码检查napi_create_*和napi_delete_*是否配对。daemon not running 但 systemd 显示 activePID 文件不一致。删掉旧 PID 再重启rm -f .openclaw/daemon.pid sudo systemctl restart openclawRestart count 快速增长说明崩溃是持续性的不是偶发。先临时关掉自动重启让进程崩一次留下完整核心转储sudo systemctl stop openclaw ulimit -c unlimited openclaw --daemon崩了之后用 GDB 分析比在重启循环里抓日志有效得多。栈溢出 SIGSEGV如果 Backtrace 特别长且重复是无限递归。加大栈并加递归保护export NODE_OPTIONS--stack-size65536同时在配置里加maxCallDepth: 1000超过就中断。6. 稳定运行后的接入与监控守护进程稳定后把注意力放回日常使用。模型对话入口在https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite临时验证模型响应可以用它不用起完整守护进程。接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite里面列了各客户端的 Base URL 和参数写法配置对不上时先查这里。如果你长期跑编码任务或 AgentCoding Plan 页面在https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite里面有套餐和用量说明适合把 OpenClaw 当常驻服务的场景。Claude Code 用户看https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite里面有 Anthropic 兼容层的配置细节。监控方面加一个简单的健康检查脚本挂到 cron 里每 5 分钟跑一次#!/bin/bash STATUS$(openclaw --daemon-status 21) if echo $STATUS | grep -q not running; then echo $(date): daemon down, restarting .openclaw/logs/watchdog.log sudo systemctl restart openclaw fi日志轮转也要配不然崩溃日志会把磁盘写满cat /etc/logrotate.d/openclaw EOF /opt/openclaw/.openclaw/logs/*.log { daily rotate 7 compress missingok notifempty } EOF最后提醒一个实操细节改完auth.json或config.json后一定要sudo systemctl restart openclaw让配置重新加载。守护进程不会热读这些文件不重启等于没改。重启后用openclaw --daemon-status确认Restart count归零再发一次真实请求验证通道两步都过才算配置落地。
返回列表