Linux日志里出现segfault怎么排查?段错误、core dump与进程崩溃分析指南

Linux日志出现segfault,先从journalctl定位进程和崩溃点,再确认core dump配置,用coredumpctl或GDB分析堆栈。本文梳理代码、依赖、容器与硬件常见原因。

Linux 日志里出现 segfault at ... error 4 in ...,说明进程收到了 SIGSEGV,访问了不该访问的内存地址。常见原因包括程序空指针、越界访问、并发破坏内存、依赖库版本不匹配、JIT 或 unsafe 代码错误,也可能确实是硬件或内存问题。只看一条 segfault 记录无法直接得到根因,需要把时间点、进程、信号、崩溃地址、映射文件和 core dump 串起来。

下面方法适用于常见 systemd Linux 服务器,示例命令需要 root 或相应日志读取权限。不同发行版对 core dump 的处理不同,Debian、Ubuntu、CentOS、Alpine 默认配置可能差异明显,排查时以实际系统为准。

Linux日志里出现segfault怎么排查?段错误、core dump与进程崩溃分析指南

一、先从journalctl锁定崩溃事件

如果是 systemd 服务,先按服务名和时间范围过滤:

journalctl -u example.service --since "1 hour ago" --no-pager
journalctl -b -p err --no-pager

一条典型的内核 segfault 日志类似这样:

kernel: example[12345]: segfault at 0 ip 00007f8f12345678 sp 00007ffd... error 4 in libexample.so[...]

这里有四个信息要记录:

  • example[12345]:进程名和触发崩溃的 PID;
  • segfault at 0:崩溃访问的地址,0 常见但不等于一定是空指针;
  • ip ...:崩溃时指令指针,通常落在某个共享库或可执行文件区间;
  • error 4:页错误标志,不能单独当作结论,需要结合映射和堆栈。

再确认系统里是否记录了 coredump:

journalctl -b --no-pager | grep -iE "segfault|coredump|dumped core"

如果同一服务在重启后反复出现 segfault,记录首次发生时间、频率和是否与发布、重启、流量峰值、内存压力同时出现。偶然一次和每分钟一次,处理优先级完全不同。

二、确认core dump有没有被保存

使用 systemd-coredump 的系统,先执行:

coredumpctl list --no-pager
coredumpctl info --no-pager
coredumpctl info PID --no-pager

list 查看已捕获的 core dump,info 显示 PID、UID、GID、信号、时间戳、可执行文件、命令行和控制组等元数据。能否读取完整信息取决于系统权限和日志保留策略。

再检查内核 core 文件配置:

sysctl kernel.core_pattern
cat /proc/sys/kernel/core_pattern
ulimit -c

kernel.core_pattern 决定 core 文件名或是否交给某个程序处理。以 | 开头时,内核会把 core dump 写入指定程序;systemd-coredump 通常使用这种方式。普通文件模式则会在进程工作目录或模板指定目录生成 corecore.PID 一类文件。

ulimit -c 显示当前 shell 的 core 文件大小限制,0 表示不生成普通 core 文件。systemd 服务还应查看其资源限制:

systemctl show example.service -p LimitCORE

如果 coredumpctl list 为空,常见原因包括 systemd-coredump 未启用或被禁用、core 大小被 ProcessSizeMax 拦截、进程设置了 PR_SET_DUMPABLE 或 seccomp 限制、容器共享了宿主机内核但看不到宿主机 journal。容器内没有记录,并不代表宿主机日志里没有。

三、用coredumpctl或GDB拿到堆栈

找到目标 core dump 后,优先使用:

coredumpctl debug PID

默认会调用 GDB。进入 GDB 后先看崩溃线程和调用栈:

bt
thread apply all bt full
info registers
info sharedlibrary
x/16i $pc

如果系统没有 systemd-coredump,但拿到了 core 文件,可以用类似方式打开:

gdb /path/to/example /path/to/core

GDB 需要同时匹配可执行文件、共享库和调试符号。堆栈里只有地址或问号时,不要直接判断为“内存坏了”,先检查以下条件:

  • 可执行文件是否已被重新覆盖;
  • 依赖库版本是否与崩溃时一致;
  • 是否安装对应 debuginfo 或 DWARF 符号;
  • 容器崩溃是否需要在相同镜像环境中解析;
  • 是否剥离了符号表。

生产服务经常按版本发布,崩溃后保留当次版本的二进制、镜像 tag、构建 ID 和依赖库,比事后找相近版本可靠得多。

四、按崩溃地址和映射文件缩小范围

如果日志里有 error N in libxxx.so,先确认这个库属于哪个软件包:

ldd /path/to/example
dpkg -S /path/to/libxxx.so
rpm -qf /path/to/libxxx.so

Debian 系用 dpkg -S,RPM 系用 rpm -qf。如果路径来自容器内进程,命令要在同一容器命名空间里执行,宿主机路径未必相同。

再看崩溃前是否有相关异常:

journalctl -u example.service --since "30 min before crash" --no-pager
dmesg -T --time-format iso | less

重点找 OOM kill、内存不足、库加载失败、版本警告、磁盘写入失败、容器被重启、同时间其他进程崩溃。OOM 和 segfault 可能先后出现,但根因不同,不能把时间相邻当作因果。

五、区分代码、依赖、运行环境与硬件问题

以下线索更偏向应用代码或依赖:

  • 崩溃点稳定落在同一个函数;
  • 升级某个应用或依赖库后开始出现;
  • 特定请求、输入或并发量触发;
  • GDB 堆栈显示越界、释放后使用、非法指针;
  • 换用旧版本后停止,换回新版本又复现。

以下线索需要检查运行环境:

  • 只在容器、特定节点或特定镜像出现;
  • 动态链接器提示库版本不匹配;
  • cgroup 内存限制先触发;
  • 文件系统只读导致依赖加载失败;
  • glibc、OpenSSL、语言运行时与二进制编译环境不一致。

多进程同时崩溃、随机地址、内存测试报错、同一机器多个不相关服务异常时,才有必要进入硬件排查。不要因为单条 segfault 就直接换内存。

六、安全地调整core dump配置

如果没有 core dump,且业务允许,可以在维护窗口临时调整。systemd-coredump 的配置通常在:

/etc/systemd/coredump.conf

常见配置包括 Storage=Compress=ProcessSizeMax=ExternalSizeMax=。修改后重载并重启相关服务:

sudo systemctl daemon-reload
sudo systemctl restart systemd-coredump.socket

配置项和默认值随 systemd 版本变化,修改前先阅读当前系统手册:

man systemd-coredump
man coredump.conf

core dump 会包含进程内存,可能有请求参数、Token、证书私钥或用户数据。不要把生产 core 文件长期留在 Web 目录或无关人员可读的位置;收集完堆栈后按安全要求归档、加密或删除,并限制能读取的账号范围。

七、修复后的验证和留存

修复或回滚后,至少验证三点:服务能稳定运行;原触发路径不再崩溃;core dump 记录不再持续增加。

systemctl status example.service
journalctl -u example.service --since "1 hour ago" --no-pager
coredumpctl list --no-pager

建议保留一份简短记录:崩溃时间、PID、可执行文件版本、镜像 tag、依赖库版本、GDB 堆栈、触发条件、处理方式。下次出现同类日志时,这份记录比临时搜索更容易判断是否为回归。

参考资料

  1. core(5) – Linux man-pages
  2. systemd-coredump(8) – Linux man-pages
  3. coredumpctl(1) – Linux man-pages
  4. journalctl(1) – Linux man-pages
Linux运维知识库

服务器重启后服务没有自动启动怎么办?systemd开机自启与依赖顺序排查指南

2026-9-11 17:09:23

知识库

如何选择单域名、多域名、通配符SSL证书?

2024-11-6 16:01:56