mercury0114
mercury0114

Reputation: 1449

How to measure the amount of stack an arbitrary function call uses in C?

Our company bought a proprietary C function: we have a compiled library ProcessData.a and an interface file to call it:

# ProcessData.h
void ProcessData(char* pointer_to_data, int data_len);

We want to use this function on an ARM embedded CPU and we want to know how much stack space it might use.

Question: how to measure the stack usage of an arbitrary function?

What I tried so far is to implement the following helper functions:

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));
}

And then use them just before and after the function call:

StartStackMeasurement();
ProcessData(array, sizeof(array));
FinishStackMeasurement();

But this seems like a dangerous hack - especially the part where I am subtracting 4 from the stackPointerBeforeCall and overwriting everything below. Is there a better way?

Upvotes: 0

Views: 661

Answers (2)

Erik Eidt
Erik Eidt

Reputation: 26646

Compile the program and analyze the assembly or machine code for the function in question.  Many functions use the stack in a static manner, and this static size can be reasoned by analysis of the compiled code.  Some functions dynamically allocate stack space based on some computation, usually associated with some input parameter.  In those cases, you'll see different instructions being used to allocate stack space, and will have to work back to reason how the dynamic stack size might be derived.

Of course, this analysis would have to be redone with updates to the function (library).

Upvotes: 5

kaios
kaios

Reputation: 422

You can use getrusage which is a function that gets you the resource usage of your software, in particular ru_isrss which is

An integral value expressed the same way, which is the amount of unshared memory used for stack space

(source)

You can then compare it to the stack usage of your program with a mocked call to the library.

However, this will only work if your system has implemented ru_isrss (unlike linux), otherwise the field will be set to 0.

Upvotes: 0

Related Questions