获得进程的内核转储core

预备

获得进程的内核转储core_第1张图片

main.cpp
#include 

using namespace std;

int main(int argc,char *argv[])
{
    int *a = NULL;
    *a = 0x1;

    return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

project(main)

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall")

INCLUDE_DIRECTORIES(./)

AUX_SOURCE_DIRECTORY(./ MAIN)

add_executable(main ${MAIN})

启用内核转储

大多数Linux发行版本默认关闭内核转储功能

(ulimit) 启用和设置转储大小

ulimit -a // 查看设置效果

获得进程的内核转储core_第2张图片

ulimit -c

-c 表示内核转储文件的大小限制, 限制为0, 内核转储无效

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ulimit -c unlimited // 不限制内核转储文件的大小,只是临时生效

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ulimit -c 1073741824 // 设置core上限大小

永久生效需要在shell的启动脚本/etc/bashrc、~/.bashrc或者/etc/profile等地方写入

echo “ulimit -c unlimited” >> /etc/profile

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

内核转储的位置

/proc/sys/kernel目录下看当前core的配置, /proc这个目录是一个虚拟文件系统,它放置的数据都是在内存中,本身不占有磁盘空间,vi不能直接修改

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

默认情况下是在程序当前目录

kernel.core_pattern需要没配置, 或者就是core
获得进程的内核转储core_第3张图片

kernel.core_uses_pid = 1
1:添加pid作为扩展名,生成的core文件名称为core.pid
0:不添加pid作为扩展名,生成的core文件名称为core

获得进程的内核转储core_第4张图片

自定义目录

修改/etc/sysctl.conf

kernel.core_pattern = /var/lib/systemd/coredump/%t-%e-%p-%c

kernel.core_uses_pid = 0 // 设置什么都不生效

获得进程的内核转储core_第5张图片

运行sysctl -p让新增设置生效, 再运行./main

获得进程的内核转储core_第6张图片

格式符
格式符 说明
%% %字符本身
%p 被转储进程的进程ID(PID)
%u 被转储进程的真实用户ID (real UID)
%g 被转储进程的真实组ID(real GID)
%s 引发转储的信号编号
%t 转储时刻(从1970年1月1日 0:00 开始的秒数)
%h 主机名
%e 可执行文件名
%c 转储文件的大小上限(内核版本2.6.24以后可以使用)

辅助程序自动压缩内核转储文件

在目录/usr/local/sbin下增加core_help脚本, 并增加权限
#!/bin/sh

exec gzip -> /var/lib/systemd/coredump/$1-$2-$3-$4.core.gz

获得进程的内核转储core_第7张图片

kernel.core_pattern可以加入管道符, 启动用户模式辅助程序

管道符(|) 后面可以写程序名

1. 修改/proc/sysctl.conf

kernel.core_pattern = |/usr/local/sbin/core_helper %t %e %p %c

获得进程的内核转储core_第8张图片

2. sysctl -p 新配置生效
3.转储文件被压缩

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你可能感兴趣的:(c++,linux)