• 一种简单通用的获取函数栈空间大小的方法


    有些时候我们需要评估某个函数所使用的栈空间大小,比如创建线程的时候,我们需要估算该线程函数所需的栈空间,分配合适的线程栈。

    本文介绍一种简单的方法,来获取某个函数所占用的栈空间大小。

    原理:

    针对递减栈内存模型,调用函数时,栈指针会往下移动,移动的距离取决于该函数的局部变量和调用子函数,也就是该函数所使用的栈空间,在函数返回时,栈指针又会恢复到调用前的位置。

    根据这一特性,我们可以在调用函数前把栈底部的内存用一个特定值来填充,调用结束后检查栈底部的值是否发生变化,搜索到最后1个发生变化的地址就是该函数所使用的栈底。用当前栈指针减去栈底指针就能算出该函数实际使用的栈空间大小。

    实施:

    废话不多说,直接上测试代码:

    1. //用0xAA填充栈底512字节
    2. void stack_test_begin(void)
    3. {
    4. register int i;
    5. unsigned char mem[512];
    6. for(i = 0; i < 512; i++)
    7. {
    8. mem[i] = 0xAA;
    9. }
    10. }
    11. //检查栈底,返回栈大小
    12. int stack_test_end(void)
    13. {
    14. register int i;
    15. unsigned char mem[512];
    16. for(i = 0; i < 512; i++)
    17. {
    18. if(mem[i] != 0xAA)
    19. {
    20. return 512 - i;
    21. }
    22. }
    23. return 0;
    24. }
    25. //被测试函数, 此函数理论占用栈空间为128字节
    26. void stack_use_128(void)
    27. {
    28. register int i;
    29. char mem[128];
    30. for(i=0; i<128; i++)
    31. {
    32. mem[i] = 0;
    33. }
    34. }
    35. //测试
    36. void main(void)
    37. {
    38. int stack_size;
    39. stack_test_begin();
    40. stack_use_128();
    41. stack_size = stack_test_end();
    42. printf("stack: %d\n", stack_size);
    43. }

    代码解读:

    为方便分析,假设main函数的初始栈指针为SP=0x00001000。
    1. 调用stack_test_begin() ,这个函数局部变量mem占用512字节,这512字节用0xAA填充,实际就会导致0x00000E00 - 0x00001000被填充为0xAA。这就完成了我们栈底填充特定值步骤。
    2. 调用stack_use_128(),这个函数是我们想要获取栈空间的目标函数,这个函数对局部变量的操作,会导致我们填充的0xAA变为其它值。
    3.调用stack_test_end(),这个函数同样使用512字节的局部变量,我们搜索这512字节空间,从前往后找,找到不是0xAA的值,就表示此处是被stack_use_128()函数使用的栈边界。此边界之前是未用到的栈内存,因此用512减去此边界值就是该函数实际使用的栈空间大小。
    4.如果被测函数栈空间超过512,则需要把512改为更大的值,增加更多的填充深度。

    总结:

    此方法在ARM和x86平台上测试能正常工作。不依赖系统调用,通用性较强。
    但填充内存和搜索内存会消耗CPU资源,影响整体性能,因此只适合在代码调试阶段使用。


  • 相关阅读:
    SaaSBase:什么是Thoughts?
    从统计语言模型到预训练语言模型---预训练语言模型(Transformer)
    3D点云深度学习处理的基本概念
    MySQL read 查询语句7 复制 去重 外连接
    (十) ES6 新特性 —— class类
    编译着色器并在屏幕上绘图
    LeetCode-81. 搜索旋转排序数组 II-Java-medium
    数据分析——A/B测试二:优惠券AB测试项目
    FITC-Dextran荧光素标记葡聚糖-星戈瑞
    53.最大子数组和
  • 原文地址:https://blog.csdn.net/qq446252221/article/details/126012389