前言
最近部署到linux的程序遇到段错误,网上查了一些原因,基本上看不出有用的东西出来,于是只能根据gdb进行排查。
寻找core文件
就是内存转储文件,程序崩溃时会自动提示:段错误(内核已转储),gdb调试的时候必须依赖转储文件才能调试。要进行调试还需要知道两个问题:core文件在哪以及为什么没有生成
- 文件位置
要查看文件在哪,可以直接执行
cat /proc/sys/kernel/core_pattern
根据输出内容进行判断,如果为core则代表在执行文件同目录生成,如果为/usr/lib/systemd/systemd-coredump %P %u %g %s %t %e 则代表着被coredumpctl接管了,下面说一下如何从coredumpctl提取core文件,其实很简单
#查看所有的内存转储文件
coredumpctl list
#默认会显示出所有的内存转储文件,我们大部分关心的应该是最后一项,拿到pid后
coredumpctl -o core dump pid
执行完之后就会在当前目录中生成core文件了,文件名可以自定义。
- 文件没有生成
默认系统是关闭core文件生成的,可以通过命令查看
ulimit -c
#或
ulimit -a
real-time non-blocking time (microseconds, -R) unlimited
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 62283
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 62283
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
如果输出为0或core file size为0则代表的允许的最大core文件大小为0,即禁止输出core文件,修改大小可以通过
#修改为1个G,文件单位为kbyte
ulimit -c 1024000
#或不限制
ulimit -c unlimited
当前限制仅针对当前shell,如果要持久化可以配置到/etc/sysctl.conf。另外core文件感觉通常都很大,如果core的实际大小超过了限制大小,则会覆盖,gdb也会提示错误,如果只是临时生成一下,可以设置成不限制。
GDB调试
由于是初次接触gdb调试,使用的方式是:gdb [执行文件] core文件,比如,执行文件为a.out,core文件为b.core
gdb a.out b.core
然后gdb会给出一段提示,直接按回车后,输入bt回车后,会打印出异常的地方。
结尾
通过这一次找问题,感觉还是需要掌握gdb调试的,哪怕是最基础的操作,至少在出现问题不会抓瞎。
不错不错,我喜欢看 https://www.ea55.com/