使用coredump定位Linux下程序崩溃问题

关注微信公众号塔容万物

https://zhuanlan.zhihu.com/p/638514345

在linux下,程序崩溃时,可以产生一个coredump文件,这个文件包含了程序崩溃时的内存信息,可以通过gdb工具来定位程序崩溃的原因。

配置启用coredump

# 配置coredump生成文件的大小限制
ulimit -c unlimited
# 配置coredump生成文件的路径以及文件名
sudo echo "/tmp/coredump/%e.%p.%t.coredump" > /proc/sys/kernel/core_pattern
# 配置coredump生成文件的权限
echo "1" > /proc/sys/fs/suid_dumpable

在linux下,可以通过ulimit命令来配置coredump的生成,通过ulimit -c可以查看coredump的配置,如果为0,则表示不生成coredump文件,如果为unlimited或者大于0,则表示生成coredump文件。

ulimit -c unlimited
# 或者设置具体的大小
ulimit -c 1024
ulimit -a
# -t: cpu time (seconds)              unlimited
# -f: file size (blocks)              unlimited
# -d: data seg size (kbytes)          unlimited
# -s: stack size (kbytes)             8192
# -c: core file size (blocks)         1024
# -m: resident set size (kbytes)      unlimited
# -u: processes                       31211
# -n: file descriptors                1048576
# -l: locked-in-memory size (kbytes)  65536
# -v: address space (kbytes)          unlimited
# -x: file locks                      unlimited
# -i: pending signals                 31211
# -q: bytes in POSIX msg queues       819200
# -e: max nice                        0
# -r: max rt priority                 0
# -N 15: rt cpu time (microseconds)   unlimited

/proc/sys/kernel/core_pattern文件用来配置coredump生成文件的路径以及文件名,可以通过echo命令来配置。

/proc/sys/fs/suid_dumpable文件用来配置coredump生成文件的权限,可以通过echo命令来配置。

测试程序

#include <stdio.h>
#include <stdlib.h>

struct abc {
  int a;
  int b;
};

int
f1()
{
  void* p = NULL;
  struct abc* abc = (struct abc*)p;
  abc->a = 1;
  printf("%d\n", abc->a);
  return 100;
}

int
main()
{
  f1();
}
# 编译
# -g: 生成调试信息所需要的符号表
gcc -g -o test test.c
# 运行
./test

运行程序,程序会崩溃,生成coredump文件。

crashdump
└── s.13232.1714269757.coredump

使用gdb定位程序崩溃原因

# 使用gdb打开coredump文件
gdb test ./coredump/s.13232.1714269757.coredump
# gdb会自动定位到崩溃的位置

gdb会自动定位到崩溃的位置,可以通过btinfo locals等命令查看崩溃的原因。

GNU gdb (Debian 13.1-3) 13.1
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./test...
[New LWP 21103]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000055b3495ad155 in f1 () at test.c:14
14        abc->a = 1;

一键配置脚本

复制自:https://zhuanlan.zhihu.com/p/638514345

#!/bin/bash

DUMP_PATH=`pwd`/crashdump

# 检查当前用户是否具有sudo权限
if [ "$(id -u)" != "0" ]; then
  echo "请使用sudo运行此脚本"
  exit 1
fi

# 配置Coredump
echo 2 > /proc/sys/fs/suid_dumpable
echo "$DUMP_PATH/%e.%p.%t.coredump" > /proc/sys/kernel/core_pattern

# 创建Coredump保存目录
mkdir -p $DUMP_PATH
chmod 777 $DUMP_PATH

# Coredump功能已开启 配置信息
cat /proc/sys/fs/suid_dumpable
cat /proc/sys/kernel/core_pattern