0

我们公司购买了一个专有的 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();

但这似乎是一个危险的黑客攻击——尤其是我4stackPointerBeforeCall下面减去并覆盖所有内容的部分。有没有更好的办法?

4

2 回答 2

5

编译程序并分析相关函数的汇编或机器代码。许多函数以静态方式使用堆栈,而这种静态大小可以通过分析编译代码来推断。一些函数基于一些计算动态分配堆栈空间,通常与一些输入参数相关联。在这些情况下,您将看到用于分配堆栈空间的不同指令,并且必须回过头来推理如何得出动态堆栈大小。

当然,必须通过更新函数(库)来重做这种分析。

于 2020-11-18T15:08:26.823 回答
0

您可以使用getrusage,它是一个可以让您了解软件资源使用情况的功能,特别ru_isrss

一个整数值以同样的方式表示,它是用于堆栈空间的非共享内存量

(资源)

然后,您可以通过对库的模拟调用将其与程序的堆栈使用情况进行比较。

但是,这仅在您的系统已实现ru_isrss(与 linux 不同)时才有效,否则该字段将设置为 0。

于 2020-11-18T14:36:31.523 回答