确定一个地址是否属于堆或堆栈或寄存器
问题描述:
我有一个指针可用于我的C/C++变量。是否有可能准确地确定这个变量属于哪一段内存?如果是,如何?确定一个地址是否属于堆或堆栈或寄存器
注:我只是有这个变量的地址,如果变量没有进一步的信息是局部/全局等
答
您可以首先确定可执行文件中不同部分的开始和结尾是什么。对于这一点,你需要最终在连接器脚本中添加一些变量围绕每一个部分是这样的:
SECTIONS {
[...]
.data : {
data_start = .;
*(.data)
data_end = .;
}
[...]
}
然后你可以在你的C/C++代码声明这些变量作为外部和直接使用它们来比较你的地址想识别。
调整链接器脚本可能并不容易。使用gcc,您可以将其转储为:
gcc -Wl,-verbose whatever.c
然后尝试查找已在(messy)输出中定义的变量。
为了得到堆栈的边界,你可以在main()函数的开头实例化一个虚拟变量,并将其地址保存为栈顶,然后在当前位置实例化另一个,给你的底部。但是请注意,编译器的行为可能与此不完全相同(C中变量的堆栈顺序不能保证,甚至不能使用堆栈),所以这应该可行,但不能移植。
最后,对于堆,我没有任何把戏。我只是推断一个不在data/bss /派生的变量,而不是堆栈中的变量将在堆中(不包括寄存器),但是如果你能得到地址,我敢打赌编译器永远不会使用寄存器存储)。
答
如果您使用的是Linux(不知道其他Unix系统),你也许可以找到该文件中的信息/proc/<pid>/maps
答
我完全不知道这是否符合你的情况,但你可以尝试objdump -t
查看elf文件的符号表。所有你需要的是你的变量的地址。在那里你可以找到显示每个变量部分的标志。有关更多详细信息,请参阅objdump
手册页。
输出示例:
0804a020 g O .bss 00000004 var
它说var
是g
叶形O
bject在地址0804a020
,部分.bss
不可能的,至少不是在一个可移植的方式。 – juanchopanza 2012-08-06 11:52:02
你想解决什么问题?你需要一个运行时还是编译时解决方案?寄存器没有地址。 – 2012-08-06 11:52:59
我们只是有一个参数,不管全局变量是属于堆栈还是堆,都想确认自己:P – 2012-08-06 11:58:23