我可以使用两个 Linux 发行版,都是定制的 Debian。
使用相同的测试程序,在一个程序中,生成的核心文件约为 35 MiB。在另一个程序中,生成的核心文件约为 290 MiB。该程序会生成一些线程,进行一些分配,然后永远处于忙循环状态。
使用 检查核心readelf
,我发现较大的核心包含如下部分:
LOAD 0x000000000815e6b8 0x00007f8594021000 0x0000000000000000
0x0000000003fdf000 0x0000000003fdf000 R 0x1
查看内存映射,它对应的是:
7f8594021000-7f8598000000 ---p 00000000 00:00 0
Size: 65404 kB
Rss: 0 kB
Pss: 0 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 0 kB
Anonymous: 0 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: mr mw me nr
我理解这个区域是专用于线程领域的未使用内存。在运行时,该区域存在于两个发行版中,但只写入其中一个发行版的核心文件。为什么会这样?
两者coredump_filter
(0x33) 相同,因此不是那样。
编辑:我进一步追踪发现,在gcore
进程上运行会改变内核中的虚拟内存区域,这是两者的区别之一。在内核较小的进程中,它不会将它们标记为“已写入”,但在内核较大的进程中,它会这样做。具体来说,它会创建一个anon_vma
结构。