c - 如何测量 C 中任意函数调用使用的堆栈数量?
问题描述
我们公司购买了一个专有的 C 函数:我们有一个编译库ProcessData.a
和一个接口文件来调用它:
# ProcessData.h
void ProcessData(char* pointer_to_data, int data_len);
我们想在ARM
嵌入式 CPU 上使用这个函数,并且想知道它可能使用多少堆栈空间。
问题:如何测量任意函数的堆栈使用情况?
到目前为止,我尝试的是实现以下辅助函数:
static int* stackPointerBeforeCall;
void StartStackMeasurement(void) {
asm ("mov %0, sp" : "=r"(stackPointerBeforeCall));
// For some reason I can't overwrite values immediately below the
// stack pointer. I suspect a return address is placed there.
static int* pointer;
pointer = stackPointerBeforeCall - 4;
// Filling all unused stack space with a fixed constant
while (pointer != &_sstack) {
*pointer = 0xEEEEEEEE;
pointer--;
}
*pointer = 0xEEEEEEEE;
}
void FinishStackMeasurement(void) {
int* lastUnusedAddress = &_sstack;
while (*lastUnusedAddress == 0xEEEEEEEE) {
lastUnusedAddress++;
}
// Printing how many stack bytes a function has used
printf("STACK: %d\n", (stackPointerBeforeCall-lastUnusedAddress)*sizeof(int));
}
然后在函数调用之前和之后使用它们:
StartStackMeasurement();
ProcessData(array, sizeof(array));
FinishStackMeasurement();
但这似乎是一个危险的黑客攻击——尤其是我4
从stackPointerBeforeCall
下面减去并覆盖所有内容的部分。有没有更好的办法?
解决方案
编译程序并分析相关函数的汇编或机器代码。许多函数以静态方式使用堆栈,而这种静态大小可以通过分析编译代码来推断。一些函数基于一些计算动态分配堆栈空间,通常与一些输入参数相关联。在这些情况下,您将看到用于分配堆栈空间的不同指令,并且必须回过头来推理如何得出动态堆栈大小。
当然,必须通过更新函数(库)来重做这种分析。
推荐阅读
- html - 通过 WebView 中的外部网页加载本地文件
- intellij-idea - 结构搜索并用新变量替换
- asp.net - 如何在 gridview 中添加按钮以链接到网页?
- database - 数据库设计考勤管理系统
- vue.js - 如何测试在悬停/鼠标悬停时调用了 Vue 指令?
- php - 如果选项 id 在刀片视图的数组列表中,Laravel 将选项设置为选中
- grid - 我需要显示 4 列,但在移动设备上显示 2
- python - 规范化数据框的列
- asp.net - EF6 不断迁移 __MigrationHistory 表
- ansible - Ansible/Jinja 中表达式中的引用变量