journalctl -o verbose 不直接显示 Signal 代码,需结合其高精度时间戳与 CODE/SIGNAL 字段,通过识别 CODE=128+N 或 32768+N 反推信号编号(如 CODE=139→SIGSEGV=11),并在 systemd≥v240 时优先查 SIGNAL=N 字段。

journalctl -o verbose 本身并不直接显示 Linux Signal 代码(如 SIGSEGV=11、SIGKILL=9),它只输出日志条目的完整元数据(如 _PID、_UID、_COMM、MESSAGE、_SOURCE_REALTIME_TIMESTAMP 等),但不解析或反向映射进程终止原因中的信号编号。要**深度提取服务崩溃瞬间的精确 Signal 代码**,需结合 -o verbose 的高精度时间戳与上下文字段,再辅以其他内核/用户态线索交叉验证。核心思路是:**定位崩溃时刻 → 锁定目标进程 → 关联内核日志或 systemd 状态变更 → 提取 signal 编号**。
1. 用 -o verbose 锁定崩溃发生的毫秒级时间点
systemd-journald 在进程异常退出时,常记录两条关键日志:一条是服务自身输出(可能含 segfault 提示),另一条是 systemd 发出的“exited with code”通知。-o verbose 可暴露真实时间戳和进程标识,避免日志乱序干扰:
- 运行:
journalctl -u your-service.service -o verbose | grep -A2 -B2 "exited with code" - 重点关注字段:
_SOURCE_REALTIME_TIMESTAMP(纳秒级时间)、_PID(崩溃进程 PID)、CODE(exit code)和SIGNAL(若 systemd 已识别信号,此处会直接显示数字,如SIGNAL=11) - 注意:SIGNAL 字段仅在 systemd ≥ v240 且内核支持 prctl(PR_SET_CHILD_SUBREAPER) 等机制时稳定出现;旧版本通常只写
CODE=32768 + 11形式(即 32768 是 signal 基准偏移)
2. 从 CODE 值反推 Signal 编号(最常用可靠方法)
当日志中出现 CODE=32768 + N 或 CODE=N(N > 128)时,大概率是信号终止。systemd 将信号编码为 128 + signum(POSIX 标准),但某些内核/发行版使用 32768 + signum(尤其在 cgroup v1 下):
- 查常见映射:
SIGSEGV=11 → CODE=139(128+11)或CODE=32779(32768+11) - 命令快速判断:
journalctl -u your-service.service --no-pager | awk '/exited with code/ {for(i=1;i,再用 <code>kill -l 139查对应信号名 - 若输出 139 →
kill -l 139返回SEGV;若输出 32779 → 减去 32768 得 11 → 同样是SEGV
3. 关联 kernel log(dmesg)获取原始 signal 触发证据
用户态服务崩溃前,内核通常已记录 fault 信息(尤其 segfault、bus error)。利用 -o verbose 中的 _SOURCE_REALTIME_TIMESTAMP 与 dmesg 时间对齐:
- 提取崩溃时间(纳秒):
journalctl -u your-service.service -o verbose | grep "exited with code" | head -1 | grep -oP '_SOURCE_REALTIME_TIMESTAMP=\K\d+' - 转换为秒级近似值:
echo "scale=6; 1712345678123456 / 1000000" | bc(取前13位) - 查对应时段 dmesg:
dmesg -T | sed -n '/'$(date -d @$(echo "scale=0; 1712345678123456/1000000000" | bc) '+%b %d %H:%M')'/,/^$/p' | grep -i -E "(segv|trap|signal|error)" - 典型输出:
[Wed Apr 3 14:22:15 2024] traps: myapp[12345] general protection ip:7f8a1b2c3d45 sp:7fffabcd1234 error:0 in libxyz.so[7f8a1b2c0000+4000]—— 此处虽无 signal 编号,但general protection对应SIGSEGV(11)或SIGBUS(7)
4. 检查 coredump(如有)直接读取 signal 字段
若系统启用了 coredumpctl,崩溃瞬间生成的 core 文件头包含原始 signal 编号:
- 查最近 core:
coredumpctl list your-service | head -3 - 查看 signal:
coredumpctl info your-service | grep -i signal(输出类似Signal: 11 (SEGV)) - 或用 gdb 直接读:
coredumpctl debug your-service -o /tmp/core && gdb -q /usr/bin/your-service /tmp/core -ex "info registers" -ex "quit" 2>/dev/null | grep -i "signal\|sig"
真正有效的 Signal 提取不是单靠 -o verbose,而是把它当作高精度时间锚点和上下文索引器,再联动 CODE 解码、dmesg 分析、coredump 验证三路证据。只要时间戳对齐、CODE 偏移理解正确、内核日志未被轮转,就能 100% 定位到崩溃那一刻触发的是哪个 signal。











