我有一个指针可用于C / C ++变量。是否有可能准确地确定这个变量属于哪个内存段?如果有,怎么样?
注意:我只有这个变量的地址,如果变量是本地/全局等,则没有进一步的信息。
答案 0 :(得分:2)
确定您的体系结构是否包含指向堆或堆栈区域的指针。通常有一些stackpointers或framepointers ..
然后将您的实际地址与这些地址进行比较,并确定它们的所在位置。
答案 1 :(得分:2)
如果您使用的是Linux(不确定其他unices),您可以在文件/proc/<pid>/maps
答案 2 :(得分:1)
您可以首先确定可执行文件中不同部分的开头和结尾。为此,您需要最终在链接器脚本中围绕每个部分添加一些变量,如下所示:
SECTIONS {
[...]
.data : {
data_start = .;
*(.data)
data_end = .;
}
[...]
}
然后,您可以在C / C ++代码中将这些变量声明为外部变量,并直接使用它们来比较您要识别的地址。
调整链接描述文件可能并不容易。使用gcc,您可以使用以下命令转储它:
gcc -Wl,-verbose whatever.c
然后尝试查找已经在(杂乱)输出中定义的变量。
要获取堆栈的边界,可以在main()函数的开头实例化一个虚拟变量,并将其地址保存为堆栈的顶部,然后在当前位置实例化另一个,这将给出你到底了。但请注意,编译器的行为可能与此不完全相同(C中的变量的堆栈顺序无法保证,甚至不能使用堆栈),因此这应该可以工作但不可移植。
最后,对于堆,我没有技巧。我只是推断一个不在data / bss /派生而不在堆栈中的变量将在堆中(不包括寄存器,但是如果你能得到地址,我敢打赌编译器永远不会使用仅寄存器的存储)。
答案 3 :(得分:0)
我不确切知道它是否适合您的情况,但您可以尝试objdump -t
查看精灵文件的符号表。您只需要变量的地址即可。在那里你可以找到标志,显示每个变量的部分。有关详细信息,请参阅objdump
的手册页。
样本输出:
0804a020 g O .bss 00000004 var
它说var
是地址g
中的O
小叶0804a020
对象,.bss