Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Linux中获得分配给当前进程的堆栈区域?_Linux_Assembly_Stack - Fatal编程技术网

如何在Linux中获得分配给当前进程的堆栈区域?

如何在Linux中获得分配给当前进程的堆栈区域?,linux,assembly,stack,Linux,Assembly,Stack,对于Windows操作系统,线程信息块(TIB)包含有关当前正在执行的线程的信息,包括堆栈底部和顶部的地址。但是在Linux中,如何获得类似的信息?线程特定数据(TSD)有帮助吗?程序可以通过读取名为/proc/self/maps的文件来找到专用于堆栈的内存映射区域的边界。使用proc的手册页查看如何最好地读取地图文件。除此之外,它还提供每个内存区域的开始地址、结束地址、权限和大小 您可以搜索包含已知位于堆栈上的地址的区域。一个区域将被标记为[stack],但我认为它只代表主线程。当前线程知道它

对于Windows操作系统,线程信息块(TIB)包含有关当前正在执行的线程的信息,包括堆栈底部和顶部的地址。但是在Linux中,如何获得类似的信息?线程特定数据(TSD)有帮助吗?

程序可以通过读取名为
/proc/self/maps
的文件来找到专用于堆栈的内存映射区域的边界。使用
proc
的手册页查看如何最好地读取
地图
文件。除此之外,它还提供每个内存区域的开始地址、结束地址、权限和大小


您可以搜索包含已知位于堆栈上的地址的区域。一个区域将被标记为
[stack]
,但我认为它只代表主线程。

当前线程知道它自己的堆栈指针,因此它可以检查哪些映射包含它自己的堆栈指针。在不使用任何asm的情况下,获取堆栈地址的最简单方法可能是获取伪局部变量的地址。但是是的,查看
/proc/self/maps
也是我的想法。实际上,对于多线程进程,堆栈映射被标记为
[stack:2681]
。因此,线程只需在
/proc/self/maps
中查找自己的PID堆栈,而无需执行范围检查。我正在检测一个程序,希望检查堆栈区域。它最好以汇编的形式实施。我知道通过读取/proc/pid/stat可以得到startstack地址,通过读取/proc/pid/status可以得到堆栈段的大小。或者,我也可以通过调用getrlimit()获得进程堆栈的最大大小。尽管如此,我仍然不知道如何在汇编中编写@彼得Cordes@Matthewxie:您可以编写一个函数来打开/读取/解析
/proc/self/maps
或其他任何内容,并使用编译器来实现asm。这将使太多的代码无法在各地复制,但您可以在各地调用它。或者缓存该信息,因为在检测时添加大量系统调用根本不理想。信息可能已经缓存在线程本地数据中,但我从未对线程本地数据做过任何处理,只是知道x86-64使用段寄存器重写来访问它。@Matthewxie可能会编写一些C代码,在程序启动后不久运行,这将获得堆栈的边界(开始/停止)使用此处讨论的方法从
/proc
。然后将边界存储在两个全局变量中。然后,您的汇编代码只需要将
$esp
与这些全局变量进行比较。这有点像您在
mov$eax,0x1000000
中提到的解决方案,但您不必硬编码地址,您可以使用符号。如果您是汇编新手,请先用C编写代码,然后使用
gcc-S
将其转换为汇编。您的标题是“当前进程”。如果你的意思是“当前线程”,那么你应该重命名。要简化,目前我只考虑当前进程。当前进程包括当前进程的所有线程…你的意思是通过假设一个单线程进程来简化吗?是的。我想检查esp寄存器中的值是否超出堆栈,比如指向堆或数据段。在编译器生成的代码中,这种情况永远不会发生,除非
-fno省略帧指针
函数(例如使用可变长度数组的函数)损坏了保存的
rbp
值。然后,当调用方的尾声运行时,
rsp
将包含一条指令的垃圾,然后
ret
通过加载假返回地址导致segfault。在手工编写的asm中,可以将
esp
存储在某个地方(例如MMX寄存器中),并将其用作循环中的第八个通用寄存器,该循环不需要堆栈,也不能被信号处理程序中断。但也不能保证它是一个指针。