core dumped#
什么是 Segmentation fault#
Segmentation fault 指程序访问了系统未分配给该程序的内存空间,这部分内存空间可能不可访问、不存在或受系统保护。
SIGSEGV 是操作系统在用户态程序错误访问内存时的处理机制:
当用户态程序访问不允许访问的内存时,产生 SIGSEGV
当用户态程序以错误方式访问允许访问的内存时,同样产生 SIGSEGV
什么是 core#
core 原指使用线圈制作的内存(core memory)。虽然现代已使用半导体内存,但核心转储文件仍沿用 “core” 这一名称。
什么是 core dump#
当程序异常终止时,操作系统将程序当时的内存内容转储到文件中(通常命名为 core),这个过程称为 core dump。
core 文件的存放路径#
发生 core dump 时,生成的文件名格式为 core.%e.%p.%t,存放路径由以下配置指定:
# 查看 core 文件存放路径
cat /proc/sys/kernel/core_pattern
# 临时修改存放路径
echo "/var/log/core.%e.%p.%t" > /proc/sys/kernel/core_pattern
# 永久修改存放路径
/sbin/sysctl -w kernel.core_pattern=/var/log/core.%e.%p.%t
文件名格式说明
%% 单个 % 字符
%p 所 dump 进程的进程 ID
%u 所 dump 进程的实际用户 ID
%g 所 dump 进程的实际组 ID
%s 导致本次 core dump 的信号
%t core dump 的时间 (由 1970 年 1 月 1 日计起的秒数)
%h 主机名
%e 程序文件名
core dump 配置检查#
检查系统是否启用 core dump:
ulimit -a
重点关注 core file size 参数:
如果值不为 0,表示已启用 core dump
如果值为 0,需要启用 core dump 功能:
ulimit -c unlimited
如何分析 core 文件#
基本分析方法#
# 进入 core 文件所在目录
cd /cache
# 将 core 文件与可执行程序关联
gdb /cache/gpsd.elf /cache/core.gpsd.7729.1764050460
关键调试命令#
在 gdb 环境中执行:
# 查看调用栈回溯
(gdb) bt
# 查看完整调用栈信息
(gdb) bt full
# 查看所有线程堆栈
(gdb) thread apply all bt
# 查看寄存器状态
(gdb) info registers
# 查看变量值
(gdb) print variable_name
# 反汇编当前执行代码
(gdb) disassemble
实际调试案例#
环境准备#
# 解除 SELinux 权限限制
setenforce 0
# 确认目标进程状态
ps | grep gpsd
# 实时跟踪系统调用
strace -p <PID>
core dump 配置#
# 启用 core dump
ulimit -c unlimited
# 设置 core 文件路径和命名格式
echo "/cache/core.%e.%p.%t" > /proc/sys/kernel/core_pattern
# 触发异常条件(可选)
ifconfig lo down
文件验证#
# 检查生成的 core 文件
ls /cache/core.*
产生段错误的常见原因#
缓冲区溢出(buffer overrun)
空悬指针 / 野指针
重复释放(double delete)
内存泄漏(memory leak)
不配对的
new[]/delete内存访问越界
多线程程序使用了线程不安全的函数
多线程读写的数据未加锁保护
内存碎片(memory fragmentation)
示例程序#
#include <stdio.h>
int main(void) {
int* ptr = NULL; // 创建空指针
printf("%d\n", *ptr); // 解引用空指针,导致段错误
return 0;
}
调试技巧总结#
权限准备:确保有足够的系统权限进行调试
符号匹配:使用与 core dump 完全一致的可执行文件版本
系统监控:结合 strace 实时监控系统调用
完整回溯:使用
bt full获取完整的调用栈信息多线程分析:检查所有线程状态以排除并发问题