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

我有一个要求,find一个给定的地址是在堆或堆栈。 有没有一种可靠的方法来在Linux中做到这一点?

我曾经想过下面的方法,假设堆栈会向下增长,堆堆栈会长大。 这个解决scheme有多可靠? 我们不使用gcc split-stack

 is_stack (void *addr) { int a; if( &a < addr) return stack; else return heap } 

[编辑 – 我看到了一个类似的问题,但更多的是理论]

首先,你可能在你的进程中有多个堆栈,特别是如果它是多线程的(有些库可以在你没有请求的情况下启动线程)。 而且你的进程的虚拟地址空间可能比堆栈更多

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

你的进程的地址映射可以通过调用mmap(2) , munmapexecvemprotect和一些其他的系统调用来改变(参见syscalls(2)以得到它们的列表)。 使用strace(1)来了解哪些系统调用已经完成。 任何对malloc调用(内部被许多函数调用,包括fopen …)或者free (以及对dlopen等等等) 都可能 (但不会总是)使用它们,所以缓存解析/proc/self/maps的结果/proc/self/maps不是一个可靠的选项。

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

正如很多人所评论的,由于ASLR ,即使只有一个堆栈,您也不知道堆栈和堆的相对位置。 一个可能的技巧可能是在某些全局void*stackbottom;放入一些局部变量的地址(甚至是mainargc第一个参数或者argv[0] )的地址来启动main void*stackbottom; ,稍后再比较一下你的地址,那就是测试if( &a < addr && &a > stackbottom) 。 注意到Boehm的垃圾回收器正在做类似的事情。

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

而且,堆栈或堆中的指针是一个不明确的属性(换句话说, 堆栈是一个比你想象的复杂得多的概念)。 你需要更精确地知道你真正想做什么。

另外,重新定义你自己的mallocfree等,并让你的malloc管理一些内存映射。

C标准没有的概念,所以语言本身不能告诉你。

但是你提到了Linux,所有的都不会丢失 – 你可以用一点点工作来实现。

如果将定义为由malloc分配的malloc ,则可以考虑构建自己的内存分配系统。 许多C编译器允许您在链接到您的程序的所有库中链接一个不同的malloc ,因此这种方法是非常可行的。 (请参见LD_PRELOAD)。 当然,您的替换malloc的主要内容将简单地调用标准函数。 但另一部分将维护一个分配内存的表。 您可以在测试函数中使用您需要编写的信息。

你需要为callocfree和&c做同样的事情。