c++如何读取和处理系统内核转储文件Dump【深度】

陌涛大大_6019

陌涛大大_6019

2026-04-12

648人浏览

原创

/proc/kcore 是受权限和配置限制的虚拟文件,不可直接用 fread 读取;真正的内核转储是 kdump 生成的 vmlinux+vmcore 或 qemu 的 dump,需用 libdw/libelf 解析符号,vmcore 中指针为物理地址,须结合 vmcoreinfo 校准映射。

c++如何读取和处理系统内核转储文件dump【深度】

Linux 下的 /proc/kcore 不是真正的内核转储,别直接用 fread 读它

很多人看到 /proc/kcore 就以为是内核内存镜像,试图用 C++ std::ifstream 或 fopen + fread 直接加载——结果要么失败(Operation not permitted),要么读出全是零。这是因为 /proc/kcore 是一个虚拟文件,内核只在 read() 时按需生成内容,且受 ptrace 权限和 kernel.kptr_restrict 控制。普通用户进程默认无权访问,即使 root 运行,也常因 CONFIG_PROC_KCORE 未启用或 vm.panic_on_oom=2 等配置导致不可读。

真正可分析的内核转储,是 crash 工具(如 kdump)生成的 vmlinux + vmcore 配对文件,或 qemu 的 -dump-guest-core 输出。C++ 程序要处理它们,必须依赖外部解析逻辑,不能靠裸 I/O。

用 libdw + libelf 解析 vmlinux 符号表,否则地址无法映射

vmlinux 是带调试信息的内核镜像(ELF 格式),没有它,你连 sys_call_table 在哪都不知道。C++ 里不能只用 std::ifstream 读二进制头,得用 ELF 解析库定位 .symtab、.strtab 和 .debug_* 段。

  • 必须链接 -ldw -lelf,用 elf_begin() 打开 vmlinux,再调 dwarf_begin_elf()
  • dwarf_getfuncs() 可遍历所有函数符号,但注意:内联函数、编译器优化掉的符号不会出现
  • 获取 sys_open 地址示例:dwarf_offdie(dwarfd, offset, &die) → dwarf_attr(&die, DW_AT_low_pc, &attr) → dwarf_formudata(&attr, &addr)
  • 若 vmlinux 被 strip 过(常见于发行版),.symtab 为空,此时必须配合 System.map 文本文件做地址查表

vmcore 是 ELF core dump,但节区布局和用户态不同,libelf 会误判

vmcore 看似是 ELF 文件(魔数 7f 45 4c 46),但它的 PT_LOAD 段描述的是物理内存页帧,不是虚拟地址;且包含专有节区如 .mem、.note.linux。直接用 elf_getphdrnum() 遍历程序头可能跳过关键内存块。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

正确做法是先识别 vmcore 类型:

  • 检查 elf_getehdr() 后的 e_ident[EI_OSABI]:若为 ELFOSABI_LINUX 且存在 NT_PRSTATUS note,则可能是传统 kdump 格式
  • 更可靠的是读取开头 8 字节 magic:0x45 0x4c 0x46 0x02 0x01 0x01 0x00 0x00(64 位小端)后,跳过 ELF header,解析 struct vmcoreinfo_data(位于 .note.vmcoreinfo)获取页大小、架构偏移等元信息
  • 内存数据实际存储在 PT_LOAD 段的 p_offset 处,但 p_vaddr 是物理地址,需结合 vmcoreinfo 中的 phys_base 做校准

不要手写内存遍历逻辑,用 crash 的 Python API 或 gcore 做预处理

C++ 直接解析 vmcore 容易踩坑:页对齐错误导致读越界、压缩格式(gzip/lzma)未解包、稀疏内存块跳过逻辑写错。生产环境建议绕过裸解析:

  • 用 crash -s vmlinux vmcore --minimal -i 'rd /v sys_call_table' 抽取关键结构体地址,输出为 JSON,C++ 程序只负责读这个 JSON
  • 若需完整内存视图,先用 cp /proc/kcore /tmp/kcore.raw(root 权限下)+ gcore -o /tmp/kernel.gcore $(pidof systemd) 生成标准 core,再用 libbfd 解析(比 libelf 更兼容 core 格式)
  • 对实时性要求高的场景(如 eBPF 辅助分析),改用 libkdumpfile(kdump 官方库),它封装了 vmcore 的所有变种解析逻辑,C++ 只需调 kdump_file_open() + kdump_read_mem()

最常被忽略的一点:vmcore 中的指针全是物理地址,而 vmlinux 符号表给的是编译时的虚拟地址。两者之间差一个 phys_to_virt 映射,这个偏移不在 ELF 里,得从 vmcoreinfo 的 phys_base 和内核启动日志里的 Memory: ...K/...K available 推算——没这步,所有结构体字段访问都是错的。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2023.08.07

2355

5

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.23

3882

1

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

2023.10.13

1296

3

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

2025.09.10

4519

7

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

2025.06.09

5494

18

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

2025.07.04

5671

25

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

2026.04.23

399

31

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

2025.09.05

750

5

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.16

343

7

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习