调试Segmentation fault的利器:手把手教你开启和使用Core Dump

# 调试Segmentation fault的利器:手把手教你开启和使用Core Dump


在Linux环境下开发程序,遇到“Segmentation fault (core dumped)”可能是最令人头疼的错误之一。程序突然崩溃,没有任何堆栈信息,只留下这一行提示。面对这种情况,Core Dump文件就是解决问题的关键线索。本文将手把手教你如何开启Core Dump功能,并使用它精确定位段错误的原因。


## 一、什么是Core Dump?


Core Dump(核心转储)是操作系统在程序崩溃时,将进程当时的内存内容保存下来的文件。这个文件包含了程序崩溃瞬间的堆栈信息、寄存器状态、变量值等关键数据,相当于事故现场的“黑匣子”。


当程序收到特定的信号(如SIGSEGV表示段错误)而异常终止时,系统会生成这个文件,为后续的调试提供依据。


## 二、为什么有时没有Core文件生成?


很多开发者遇到“Segmentation fault”时,却发现没有生成core文件。这通常是因为系统默认关闭了core文件生成功能。可以通过以下命令查看当前设置:


```bash

ulimit -c

```


如果输出为`0`,表示core文件被禁止生成。


## 三、开启Core Dump的完整指南


### 3.1 临时开启(当前会话有效)


```bash

# 设置core文件大小为无限

ulimit -c unlimited

```


这个设置只在当前终端会话中有效,退出后失效。


### 3.2 永 久开启配置


将配置写入用户配置文件:


```bash

# 编辑bash配置文件

echo "ulimit -c unlimited" >> ~/.bashrc

# 或者写入/etc/profile(全局生效)

sudo echo "ulimit -c unlimited" >> /etc/profile

source ~/.bashrc  # 使配置生效

```


### 3.3 systemd系统的配置


对于使用systemd的现代Linux发行版,还需要配置systemd以允许core dump:


```bash

# 创建配置文件

sudo cat > /etc/systemd/system.conf.d/10-enable-coredumps.conf << EOF

[Manager]

DumpCore=yes

DefaultLimitCORE=infinity

EOF


# 重新加载systemd配置

sudo systemctl daemon-reload

```


## 四、配置Core文件的命名和存储位置


通过修改`/proc/sys/kernel/core_pattern`可以控制core文件的命名规则和存储位置:


```bash

# 临时修改

echo "/tmp/core-%e-%p-%t" > /proc/sys/kernel/core_pattern


# 永 久修改

echo "kernel.core_pattern = /tmp/core-%e-%p-%t" >> /etc/sysctl.conf

sysctl -p  # 使配置生效

```


常用格式符说明:

- `%e`:可执行文件名

- `%p`:进程PID

- `%t`:崩溃时间戳

- `%u`:用户UID


## 五、实战:使用Core Dump定位段错误


### 5.1 制造一个段错误程序


创建一个简单的测试程序`test.c`:


```c

#include

<"o5.s6k3.org.cn"><"l1.s6k3.org.cn"><"c8.s6k3.org.cn">

int main() {

    int *p = NULL;

    *p = 100;  // 对空指针赋值,触发段错误

    return 0;

}

```


编译时需要加上`-g`选项保留调试信息:


```bash

gcc -g test.c -o test

```


### 5.2 运行并生成Core文件


```bash

./test

Segmentation fault (core dumped)

```


查看生成的core文件:


```bash

ls -l /tmp/core-test-*

```


### 5.3 使用GDB分析Core文件


```bash

gdb test /tmp/core-test-12345-67890

```


在GDB提示符下,使用`bt`(backtrace)命令查看堆栈信息:


```

(gdb) bt

#0  0x00000000004004f6 in main () at test.c:5

5           *p = 100;

```


GDB直接指出了第5行代码出错,问题一目了然。


### 5.4 更详细的调试


还可以查看特定变量的值:


```

(gdb) info locals

p = 0x0

(gdb) p p

$1 = (int *) 0x0

```


## 六、使用coredumpctl管理Core文件(systemd系统)


在采用systemd的系统中,core dump默认由`systemd-coredump`管理,存储在`/var/lib/systemd/coredump/`。


### 6.1 查看所有core dump


```bash

coredumpctl list

```


输出示例:

```

TIME                        PID  UID  GID SIG PRESENT EXE

Wed 2026-02-14 10:23:45 CST 1234 1000 100 11  *       /home/user/test

```

<"y0.s6k3.org.cn"><"e4.s6k3.org.cn"><"u6.s6k3.org.cn">

### 6.2 查看特定core dump详情


```bash

coredumpctl info 1234  # 使用PID过滤

```


### 6.3 用GDB调试


```bash

coredumpctl gdb 1234

```


### 6.4 导出core文件


```bash

coredumpctl -o test.core dump 1234

```


## 七、Core文件分析的进阶技巧


### 7.1 查看线程信息


```bash

(gdb) info threads

(gdb) thread apply all bt  # 所有线程的堆栈

```


### 7.2 查看汇编代码


```bash

(gdb) disas

```


### 7.3 查看寄存器和内存


```bash

(gdb) info registers

(gdb) x/10x $rsp  # 查看栈内存

```


## 八、常见问题与解决方案


### 8.1 磁盘空间不足


Core文件可能很大,需要确保目标目录有足够空间。可以通过`ulimit -c 102400`限制大小。


### 8.2 程序被剥离了调试符号


如果编译时没有加`-g`选项,core文件中的信息会不完整。确保生产环境程序也保留调试符号,或单独保存符号表。


### 8.3 权限问题


确保运行程序的用户对core文件目标目录有写入权限。


### 8.4 在容器中使用


容器内启用core dump需要额外的权限和配置,可能需要以特权模式运行或调整AppArmor/SELinux设置。


## 九、总结


Core Dump是调试段错误最有力的工具。通过本文的步骤,你可以:


1. **开启core dump**:`ulimit -c unlimited`

2. **配置存储位置**:修改`/proc/sys/kernel/core_pattern`

3. **分析问题**:`gdb program core` + `bt`命令


掌握这一工具,面对程序崩溃时就不再是无头苍蝇。下次遇到“Segmentation fault”,记得找找有没有core文件生成——它可能是解决问题最快的那条路。


请使用浏览器的分享功能分享到微信等