【发布时间】:2011-04-22 05:42:56
【问题描述】:
假设我有这个代码:
int main() {
int var1;
char *ptr = malloc(5 * sizeof(char));
//...........
do_something();
//...........
return 0;
}
我们知道实际的内存布局会被划分为:.text、.bss、.data、.heap、.stack。
我知道如何使用objdump、readelf 等。但是,我想更好地了解内存堆栈,在那里我可以看到如下内容:
.heap ptr
.stack do_something()
.text main()
.bss var1
重点是:objdump、readelf 等的输出中缺少实际的变量名称。
我正在用-g 编译这段代码,因此保留了符号表。
那么,为什么我看不到包含局部/全局变量名的内存布局?
objdump -x 显示变量的名称,如果类型是 static 否则不是。为什么?
【问题讨论】:
-
ptr是main的局部变量,就像var1一样。您希望在 .heap 中看到的对象是通过调用malloc分配的无名块,并且该块不知道其地址存储在名为ptr的变量中。这只是您不想看到这些细节的原因之一。 -
除非你告诉我们你使用的是哪个编译器,否则“-g”是没有意义的。对于每个项目将出现在哪个块中有一般原则(例如,.data 或 .bss 中的静态变量 - .bss 中的变量没有初始值),但除此之外的任何内容都将由平台和编译器定义。事实上,即使是上面的 .data 和 .bss 位也不能保证 - 这是基于相当可靠原则的假设,但在某些特殊情况下可能是错误的 - 例如过去有 C 解释器可用。
-
哦 - 你没有在目标文件/汇编器/任何东西中获得 .heap 或 .stack 部分。堆和堆栈是动态数据结构,堆栈由处理器管理(在某种程度上是 O/S),堆由运行时库管理(在某种程度上是 O/S)。所以编译器根本不能给你一个固定的布局——不存在固定的布局。对于堆栈,可以在特定函数中为局部变量生成布局,但对于现代编译器,它会比指导性更令人困惑 - 涉及范围和寄存器使用的复杂性。
-
感谢史蒂夫,是的,我们无法获得堆栈和堆部分的固定视图,但仍然可以获得即时视图。我在 GNU/Linux 平台上使用 gcc。
-
如果您想要在执行期间的某个时间点查看视图,您可能会从调试器中获得最好的结果——而且它们并不专注于提供内存布局可视化,所以不要指望一切立即变得清晰。无论如何,如果您使用的是 GCC,那基本上意味着 GDB,但这是一个命令行工具 - 不是很友好,而且您需要查看的信息似乎总是刚刚滚动到视野之外的信息 - 所以您可能想要众多基于 GDB 的 GUI 工具之一。抱歉,我没有真正的经验。
标签: c memory debug-symbols