如何从提供给您的API确定函数调用的堆栈使用情况?您不知道该函数是什么样的,并且您只能访问API。例如,
int main() {
// call some API function
some_func_called();
// rest of your main
}
我唯一能想到的是在调用函数之前用已知模式填充堆栈内存,然后检查堆栈以查看函数返回后已知模式的字节数已更改。还有其他想法吗? (这是一个面试问题)
答案 0 :(得分:2)
这样的事情,未经过全面测试,可能会遇到限制问题。只有当堆栈指针因PUSHING而减少时才有效,所以这不能在所有硬件上移植......
#include <stdlib.h>
#include <string.h>
#define STK_CNT 65536
size_t STK_fill()
{
volatile size_t i, cnt = 0;
volatile u_int32_t fill[STK_CNT];
for(i = 0; i < STK_CNT; i++)
{
fill[i] = 0xDEADBEEFUL;
}
return cnt;
}
size_t STK_find()
{
volatile size_t i, cnt = 0;
volatile u_int32_t fill[STK_CNT];
for(i = 0; i < STK_CNT; i++)
{
if(fill[i] == 0xDEADBEEFUL)
{
cnt++;
}else{
break;
}
}
return ((STK_CNT - cnt) * 4);
}
void victim(char *po_str, const char *pi_str)
{
char str[1024];
strcpy(str, "stk_TEST_");
strcat(str, pi_str);
strcat(str, "_stk_TEST");
strcpy(po_str, str);
}
int main()
{
int temp;
int used;
char str[4096] = {0};
temp = (int)STK_fill();
victim(str, "STK_tst_STK_tst_STK_tst_STK_tst_STK_tst_STK_tst_STK_tst_STK");
used = (int)STK_find();
printf("VICTIM function used %d bytes of stack\n", used);
return 0;
}
答案 1 :(得分:0)
我认为你的方法是最可靠的方法。
另一种选择可能是使用现代操作系统倾向于根据需要增加堆栈(即向其提交内存)这一事实。请参阅Will the stack of a C program ever shrink?也许,调用此函数后,您可以询问操作系统有关提交给堆栈的内存量。当然,这是特定于操作系统的,可能是特定于体系结构的,总的来说可能比第一种方法更加繁琐。