Is there a way to measure how much memory a specific c++ function consumes from the program stack from the time it's called until it returns?
-
Related? http://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-run-time-in-c – Fantastic Mr Fox Oct 16 '15 at 16:04
-
@Ben: Why don't you check it yourself? – Karoly Horvath Oct 16 '15 at 16:06
-
@KarolyHorvath I did ... it is .... – Fantastic Mr Fox Oct 16 '15 at 16:07
-
Is this for a PC or embedded/microcontroller environment? – TeasingDart Oct 16 '15 at 16:08
-
For a PC Windows or Linux – WhatIf Oct 16 '15 at 16:13
-
If you just want to know once as opposed to at runtime, you can use `info frame` in `gdb`. – Mike Precup Oct 16 '15 at 16:24
-
Do you want to know the stack used just for that function, or including all the functions it calls? – TeasingDart Oct 16 '15 at 16:53
-
the stack space used by each function – WhatIf Oct 16 '15 at 16:58
-
No evidence of any research at all here. – Lightness Races in Orbit Oct 16 '15 at 17:56
3 Answers
Suppose there's a function "testfunc", and we wish to find how much stackspace this fuction uses.....
#include <stdio.h>
#include <stddef.h>
ptrdiff_t testfunc (int arg1, int arg2, char *stackbase);
int main()
{
char *stackbase;
printf("\nThe amount of stack space used by \"testfunc\" is : %ul bytes\n",testfunc(10, 5, stackbase));
return 0;
}
ptrdiff_t testfunc (int arg1, int arg2, char *stackbase)
{
//.
//all function processing goes here
//.
//.
char temp;
return stackbase - &temp;
}
see here http://cboard.cprogramming.com/c-programming/90572-determine-functions-stack-size.html

- 3,454
- 1
- 19
- 28
-
I read the forum post you provided the link to and some one mentioned that " There is no relationship between the order in which you declare local variables, and the relative positions of them on the stack." – WhatIf Oct 16 '15 at 16:29
-
You can try `gcc-S` to compile you code and then look for the size adjustment for `%esp` as mentioned in the link. – wrangler Oct 16 '15 at 16:37
-
Clearly there is no portable way because compiler is allowed to do a lot with functions: from inlining to tail-call optimizing.
But strictly speaking there is nothing to measure as compiler knows this number exactly. Well, except when you're using stack arrays with non-constant sized (in C99 it's allowed, but not in C++).
One dumb way to find out is to look at the assembly code:
For example, this function:
int f(int x, int y)
{
int z = x + y;
int h = z - 2;
return h;
}
is compiled on amd64 to:
f:
.LFB0:
.cfi_startproc
pushq %rbp ; save the pointer to the caller's frame
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp ; new frame starts from %rsp (current stack ptr)
; starting from this place look how %rbp is used
; the maximum offset is what you're looking for
.cfi_def_cfa_register 6
movl %edi, -20(%rbp)
movl %esi, -24(%rbp)
movl -20(%rbp), %edx
movl -24(%rbp), %eax
addl %edx, %eax
movl %eax, -8(%rbp)
movl -8(%rbp), %eax
subl $2, %eax
movl %eax, -4(%rbp)
movl -4(%rbp), %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
So, in this example function f pushes to the stack 8-byte %rbp (old frame pointer), then it uses memory at %rbp-20, %rbp-24, %rbp-8 and %rbp-4. The max offset is -24. Total number of bytes used is 24 bytes plus 8 bytes for %rbp and 8 bytes that are not visible here for the return pointer, 40 bytes in total if I didn't forget anything.
I'm not sure if this is what you asked though.

- 136
- 6
The first thing to look at is the assembly output from the C compiler for the function and count up all the calls, pushes, and stack frames. Then you need to repeat for all the functions in the call tree, find the longest path, and the sum for it.
If you can run the function in a debugger, just note the value of the stack pointer before the function is called, step down into the function until you are at the deepest point and note the value of the stack pointer. This gives you a real-world number.
If you can recompile the entire function tree, add a simple prologue and epilogue macro that records the low-water mark for the stack pointer in a global variable. Recompile the entire project and run it. This gives you a real-world number for many iterations.
The problem becomes trickier if your function calls into third-party code into which you have no visibility. For this you can simply memset the stack memory beginning 40 (or so) bytes below the current stack point, call the function, then look for memory that has been untouched since the memset.
Something like (untested!):
EDIT: Ooops, forgot that the stack grows down...
int StackTest() {
//marker is on the stack.
//"volatile" prevents it from optimized into a register.
volatile unsigned int marker= 0xDEADBEEF;
//The current stack pointer should be just below marker.
//I add 10*4 to move well below the current stack frame.
//If the program crashes at this point, try increasing
//the size of the buffer zone.
char *pStack= (char*)&marker[-10];
//I zap the unused stack space to a recognizable value.
//The fill bytes will be overwritten as the stack is used.
//The 4096 number may need to be adjusted; it needs to be
//larger than the stack bytes used but less than the total
//stack space remaining.
memset(pStack-4096,0xCD,4096);
//Now I call my target function.
function();
//Now I search for the first 8 fill bytes in a row.
//This number may need to be increased to rule out
//false positives, such as buffers (arrays) allocated
//on the stack but not completely filled, which leaves
//fill bytes untouched inside the buffer.
for(n1=0,matchCt=0;n1<4096 && matchCt<8;n1++) {
if(*(pStack-n1)==0xCD)
matchCt++;
else
matchCt= 0;
}
int stackUsed= n1-matchCt;
printf("Stack used: %d bytes.\n",stackUsed);
return(stackUsed);
}
Keep in mind that hardware interrupts can also consume stack at random times. EDIT: This may not be a concern for user processes.

- 371
- 1
- 6
-
I don't think any OS you're likely to use consumes user stack on a hardware interrupt. General purpose OSes don't for two reasons: 1) If the user stack doesn't have enough room, terrible things would happen. 2) Unless the interrupt code sterilizes the stack, which is tricky and expensive, sensitive information would be available to the process that was interrupted. – David Schwartz Oct 16 '15 at 17:34
-