如何查找给定地址是堆还是堆栈

joe*_*joe 7 c unix linux gcc

我需要查找给定地址是堆还是堆栈.在Linux中有可靠的方法吗?

我已经考虑过以下方法,假设堆栈将向下增长,堆将向堆栈方向增长.这个解决方案有多可靠?我们不使用gcc split-stack.

is_stack (void *addr) {
   int a;
   if( &a < addr) return stack;
   else return heap
}
Run Code Online (Sandbox Code Playgroud)

[编辑 - 我看到了类似的问题,但这更像是一种理论性质]

Bas*_*tch 5

首先,您的进程中可能有多个堆栈,特别是如果它是多线程的(并且某些库可以在没有您要求的情况下启动线程)。并且您的进程的虚拟地址空间可能有更多的段,而不仅仅是heap & stack

您可能会解析/proc/self/maps伪文件。见proc(5)。请注意,由于它是由内核生成的伪文件,因此不涉及物理 IO,读取和解析该/proc/self/maps文件应该非常快。

你的进程的地址映射可以通过调用改变的mmap(2) ,,,和其他一些系统调用(请参阅系统调用(2) ,让他们的名单); 使用strace(1)了解完成了哪些系统调用。任何对(由许多函数内部调用,包括...)或对(以及对等等...)的任何调用都可以(但并不总是)使用它们,因此缓存解析结果不是一个可靠的选择。munmapexecvemprotectmallocfopenfreedlopen/proc/self/maps

首先cat /proc/$$/maps在终端中尝试该命令(向您显示 shell 虚拟地址空间的描述)。

正如许多人评论的那样,由于ASLR,即使只有一个堆栈,您也不知道堆栈和堆的相对位置。一个可能的技巧可能是main将某些局部变量(或什至main的第argc一个参数或 of argv[0]void*stackbottom;的地址放在某个全局变量中,然后像您一样比较地址,即 test if( &a < addr && &a > stackbottom)。请注意Boehm 的垃圾收集器也在做类似的事情。

但最可靠的方法是读取和解析/proc/self/maps,这应该相当快,而且肯定是一个程序化的解决方案(内核动态地提供有关其状态和进程状态的信息,/proc/并且不涉及读取它的物理IO)。

而且,在堆栈中还是在堆中是指针的定义不明确的属性(换句话说,堆栈是一个比您想象的要复杂得多的概念)。你需要更准确地了解你真正想做的事情。

Alterrnatively,重新定义你自己的mallocfree等等,让你的malloc管理一些存储器映射。

  • 相反,阅读 `/proc/self/maps` 是最可靠的程序化解决方案。 (4认同)