一、进程的内存结构
一个进程的内存包含以下的部分:
text(代码段 ,可执行)
data (只读数据段)
bss(读写数据段(静态 或 全局变量))
以上从可执行文件中映射过来,分段映射
so(共享库的映射,和可执行文件一样,分段映射)
文件映射/匿名文件映射
heap
stack
结构如下:
地址从0x400000开始,不大于0xC0000000。
二、coredump
1、设定coredump
ulimit -S -c unlimited(unlimited or core文件大小,单位为block(KB))
- -H 设置硬件资源限制.
- -S 设置软件资源限制.
sudo sh -c "echo '1' > /proc/sys/kernel/core_uses_pid"
sudo sh -c "echo '/home/wangxiumin/test/core-%e-%p-%t' > /proc/sys/kernel/core_pattern"
使用ulimit -a可以查看所有资源限制的设定值
也可以在 /etc/security/limits.conf 和环境变量中设定限制,这里不详述。
2、内核转储掩码:
程序崩溃 或 使用gcore工具 生成进程的core文件时,可以通过设定内核转储掩码来筛选需要dump的部分内存。
支持以下7种内存:
- (bit 0) anonymous private memory(匿名私有内存段)
- (bit 1) anonymous shared memory(匿名共享内存段)
- (bit 2) file-backed private memory(file-backed 私有内存段):文件映射的内存
- (bit 3) file-backed shared memory(file-bakced 共享内存段)
- (bit 4) ELF header pages in file-backed private memory areas (it is
effective only if the bit 2 is cleared)(ELF 文件映射,只有在bit 2 复位的时候才起作用)
- (bit 5) hugetlb private memory(大页面私有内存) :mmap 映射的MAP_HUGETLB类型数据
- (bit 6) hugetlb shared memory(大页面共享内存)
可以通过修改文件/proc/<pid>/coredump_filter来筛选需要dump的内存段。
/proc/<pid>/coredump_filter中的值为16进制,默认值为0x23,转化为二进制:00100011,从右向左看,bit 0、bit 1、bit 5 被置位,也就是说会转储所有的匿名内存段和大页面私有内存段。
三、例子分析
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/shm.h