对于不同二进制文件的分析,我需要测量峰值实际堆栈内存使用量(不仅仅是保留的堆栈页面,而是实际使用的内存)。我正在尝试以下gdb
watch $sp
commands
silent
if $sp < $spnow
set $spnow=$sp
set $pcnow=$pc
print $spnow
print $pcnow
end
c
这似乎是&#34;工作&#34;当应用于ls
,除时,即使对于作为ls
的短期运行程序,它实际上似乎没有进展,但它仍然存在来自/usr/lib/libc.so.6"的strcoll_l()中的&#34;等函数。这种方法可能只是太慢了。
我也查看了valgrind massif
工具。它可以描述堆栈使用情况,但遗憾的是,似乎无法报告遇到峰值使用情况的程序的哪个部分。
答案 0 :(得分:2)
对于不同二进制文件的分析,我需要测量峰值实际堆栈内存使用量
您的GDB方法
watch $sp
命令强制GDB单步执行您的程序。)如果您只关心页面粒度的堆栈使用情况(我认为您应该 - 无论程序是否使用1024或2000字节的堆栈,真的重要吗?),那么更快的方法是在循环中运行程序,在程序成功运行时减少其ulimit -s
(您也可以进行二进制搜索,例如以默认的8MB开始,然后尝试4,2,1,51K等,直到失败,然后增加堆栈限制以找到确切的值。)
/bin/ls
:
bash -c 'x=4096; while /bin/ls > /dev/null; do
echo $x; x=$(($x/2)); ulimit -s $x || break; done'
4096
2048
1024
512
256
128
64
32
bash: line 1: 109951 Segmentation fault (core dumped) /bin/ls > /dev/null
然后,您可以通过查看$PC
转储来找到core
。
我需要精确的限制,因为我想弄清楚什么编译器优化会导致微更改堆栈使用(即使在字节范围内。还有.data和.text大小)。
我认为尝试这样做是个傻瓜。
根据我的经验,堆栈使用受编译器内联决策的影响最大。这些反过来受到精确的编译器版本和调整,运行时信息的存在(用于配置文件引导的优化)以及正在优化的程序的精确源的影响。
对内联决策的是/否更改可以在递归程序中将堆栈使用量增加100个KB,并且对上述任何因素的微小更改都可以改变该决策。