讲师中心 微信公众号
AI工具推荐 视频效率加速

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

夏辰小哥_2809

夏辰小哥_2809

发布时间:2026-03-29 20:41:03

|

734人浏览过

|

来源于php中文网

原创

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

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,也可能误匹配。

立即学习“C++免费学习笔记(深入)”;

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

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

下载
  • 建议用完整文件名 + 路径分隔符边界判断,比如搜索 "/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 里结构一致。

但区别在于: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 <= addr && addr < end 的那一行
  • 注意:PIE 可执行文件的代码段基址每次运行都变,但 maps 总是反映真实运行时布局
  • 别忘了栈、堆、vvar/vdso 这些特殊区域也占地址空间,它们没有文件路径,但必须纳入遍历范围才能准确定位

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

相关文章

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

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

下载

相关标签:

c++

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

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

相关专题

更多
string转int
string转int

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

5739

2023.08.02

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

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

5187

2023.07.18

堆和栈区别
堆和栈区别

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

2288

2023.08.10

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

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

5187

2023.07.18

堆和栈区别
堆和栈区别

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

2288

2023.08.10

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

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

3838

2023.08.10

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

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

1069

2025.12.24

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

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

363

2026.01.21

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

100

2026.09.30

热门下载

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

精品课程

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

共0课时 | 0人学习

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

共0课时 | 0人学习

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

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn