c++怎么通过读取/proc/self/maps获取内存映射文件的映射地址【底层】

夏辰小哥_2809

夏辰小哥_2809

2026-03-29

734人浏览

原创

/proc/self/maps 每行地址范围格式为“起始-结束”(左闭右开),需用 end - start 计算长度;解析时必须检查 sscanf 返回值是否为2,或改用 std::hex + std::istringstream 提高安全性;路径匹配应基于 realpath() 后的完整路径前缀,避免误匹配;变量地址需落入某行区间 [start, end) 才属该映射段。

c++怎么通过读取/proc/self/maps获取内存映射文件的映射地址【底层】

怎么解析 /proc/self/maps 每一行的地址范围

每一行开头是形如 7f8b2c000000-7f8b2c001000 的十六进制地址对,代表该映射区间的起始和结束(左闭右开)。注意:结束地址不包含在内,计算长度得用 end - start,不是 end - start + 1。

常见错误是直接用 sscanf(line.c_str(), "%lx-%lx", &start, &end) 却没检查返回值——如果某行格式异常(比如 kernel 映射带 [stack:1234] 后缀),sscanf 可能只成功读一个数,end 留垃圾值,后续地址运算就崩了。

  • 务必检查 sscanf 返回值是否为 2
  • 用 std::hex 配合 std::istringstream 更安全,能自动跳过空格并拒绝非法字符
  • 地址是虚拟内存地址,单位是字节;/proc/self/maps 中所有地址都是当前进程视角的 VA,无需转换

如何识别哪一行对应你的目标文件(比如 libfoo.so)

关键看每行末尾的路径字段。但要注意:它不一定是绝对路径,可能是相对路径、[heap]、[stack]、[vdso],甚至为空(匿名映射)。你得逐行扫描,匹配 std::string_view(line).substr(last_space_pos + 1) 这部分。

容易踩的坑是用 std::string::find("libfoo.so") —— 如果路径是 /usr/lib/x86_64-linux-gnu/libfoo.so.1,而你搜 "libfoo.so" 会命中,但若同时存在 libfoo.so.debug,也可能误匹配。

  • 建议用完整文件名 + 路径分隔符边界判断,比如搜索 "/libfoo.so" 或 " /libfoo.so"(前面带空格)
  • 更稳妥的是先 realpath() 你的目标文件,再比对 maps 行末路径是否以该 realpath 开头
  • 注意符号链接:maps 显示的是被映射的真实 inode 路径,不是你 dlopen() 时传的 symlink 路径

mmap() 映射的文件 vs dlopen() 加载的 so,maps 里表现一样吗

从 /proc/self/maps 角度看,只要底层调用了 mmap()(无论手动还是动态链接器触发),都会有一行记录,权限位(r-xp)、偏移、设备号、inode 都照实反映。所以 dlopen() 加载的 .so 和你自己 mmap(fd, ..., PROT_READ, MAP_PRIVATE, 0, 0) 映射的文件,在 maps 里结构一致。

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载

但区别在于:dlopen 的模块通常有多个映射段(.text 是 r-xp,.data/.bss 是 rw-p),且路径字段显示的是 so 文件路径;而手动 mmap 若映射普通文件,路径字段也是文件路径;若映射 /dev/zero 或匿名,则路径为空。

  • 不要依赖“有没有路径字段”来判断是否是 so —— 静态链接的可执行文件也可能有路径(即 exe 自身)
  • 想确认是不是动态库,可以结合 readelf -h 检查文件类型,或看 maps 中是否出现多个相邻段共享同一路径
  • 权限位 p(private)和 s(shared)影响写时复制行为,但不影响地址读取逻辑

为什么读到的地址和 &some_global_var 对不上

因为 /proc/self/maps 给的是整个映射区间的基址(比如 .text 段起始),而变量地址是相对于该段内偏移的。例如 maps 显示 7f8b2c000000-7f8b2c005000 r-xp ... libfoo.so,而 &some_func 是 7f8b2c001234,那它在 so 内部的偏移就是 0x1234。

有人试图用 dlsym(RTLD_DEFAULT, "some_func") 得到地址后反推 maps 行,结果失败——因为 RTLD_DEFAULT 查的是全局符号表,可能来自主程序或其他已加载 so,不一定落在你关心的那个映射区间里。

  • 要定位变量所属映射段,得遍历 maps 所有行,找到满足 start 的那一行
  • 注意:PIE 可执行文件的代码段基址每次运行都变,但 maps 总是反映真实运行时布局
  • 别忘了栈、堆、vvar/vdso 这些特殊区域也占地址空间,它们没有文件路径,但必须纳入遍历范围才能准确定位

真正麻烦的是多线程下 /proc/self/maps 读取本身是原子的,但如果你边读边触发 mmap/munmap,maps 内容可能中途变化;实际工程中建议一次读完再解析,别边读边处理。

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

相关文章

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

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

下载

相关标签:

c++

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

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

5759

3

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

5207

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2308

6

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

5207

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2308

6

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

2023.08.10

3858

6

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

2025.12.24

1069

20

java多线程相关教程合集
java多线程相关教程合集

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

2026.01.21

363

30

C++多线程相关合集
C++多线程相关合集

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

2026.01.21

539

24

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习