【问题标题】:Accessing the code section of a C++ program访问 C++ 程序的代码部分
【发布时间】:2013-11-08 05:51:53
【问题描述】:

根据我的理解,C/C++ 程序在内存中看起来是这样的:

我想知道以下内容:

  1. 我可以访问正在运行的程序的“文本部分”吗?通过访问我的意思是打印 开始和结束地址并检查内容。
  2. 我可以在运行时将“文本部分”重新定位到内存中的其他地址吗?

谢谢,

【问题讨论】:

  • 如果你想要一个特定的功能,你可以直接访问它的指针来读取和复制到另一个空间。请注意,将代码作为数据处理会对性能产生巨大影响。
  • 为什么你到底要问什么? 你想做什么,真的吗?
  • @BasileStarynkevitch 实际上,我想计算从节点访问代码的影响,而不是在 NUMA 机器上运行当前程序的节点。我知道还有其他选择,但很好奇是否可以访问文本部分并在运行时将其修改为指向其他地址。
  • 好吧,处理器有缓存,所以影响(对于经常使用的热代码)应该不会很大。即使没有 NUMA,缓存未命中也会产生巨大的成本(这对于很少使用的 cold 代码很重要)。 NUMA 系统有一个复杂的 MMU(代码在虚拟内存中!)。所以热代码总是“在当前节点上”。不要太在意代码,要在意数据!

标签: c++ c linux memory-management elf


【解决方案1】:

它是特定于操作系统的;我只回答 Linux。

首先,您的数字在实践中完全不正确,因为大多数程序都动态链接到多个共享对象库(包括libc6.so...)。另见ld.so(8)elf(5)execve(2)。没有single text 部分(但有许多“文本”之类的部分)。阅读pmapobjdump 命令。

那么,你就可以用cat /proc/1234/maps了解一个pid为1234的进程的地址空间了;阅读更多关于proc(5)... 从程序内部阅读/proc/self/maps;例如,在 shell 中尝试 cat /proc/$$/maps 以显示 shell 进程的地址空间,并在 cat /proc/self/maps 中尝试运行 cat 命令的进程的地址空间。另见mmap(2)

您不能真正“重新定位”(实际上是指“移动”)文本部分。一些地址是在代码中构建的。但是,请阅读gcc-fPIE option(对于位置无关的可执行文件 ....)。

当然,如果您将程序与-rdynamic 标志链接并使用dlopen(3)(和dlsym,甚至可能是dladdr...),您可以(从内部)访问程序的符号。 ) 使用 NULL 第一个 filename 参数。

另请参阅有关 address spacevirtual memoryASLRposition independent coderelocationABIJIT compilationname manglingx86-64 ABI spec340@ 的维基页面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    相关资源
    最近更新 更多