Is there a way I can measure how much stack memory a function uses?
This question isn't specific to recursive functions; however I was interested to know how much stack memory a function called recursively would take.
I was interested to optimize the function for stack memory usage; however, without knowing what optimizations the compiler is already making, it's just guess-work if this is making real improvements or not.
To be clear, this is not a question about how to optimize for better stack usage
So is there some reliable way to find out how much stack memory a function uses in C?
Note: Assuming it's not using alloca or variable-length arrays,
it should be possible to find this at compile time.
Using warnings
This is GCC specific (tested with gcc 4.9):
Add this above the function:
#pragma GCC diagnostic error "-Wframe-larger-than="
Which reports errors such as:
error: the frame size of 272 bytes is larger than 1 bytes [-Werror=frame-larger-than=]
While a slightly odd way method, you can at least do this quickly while editing the file.
Using CFLAGS
You can add -fstack-usage to your CFLAGS, which then writes out text files along side the object files.
See: https://gcc.gnu.org/onlinedocs/gnat_ugn/Static-Stack-Usage-Analysis.html
While this works very well, its may be a little inconvenient depending on your buildsystem/configuration - to build a single file with a different CFLAG, though this can of course be automated.
– (thanks to #nos's comment)
Note,
It seems most/all of the compiler natural methods rely on guessing - which isn't 100% sure to remain accurate after optimizations, so this at least gives a definitive answer using a free compiler.
You can very easily find out how much stack space is taken by a call to a function which has just one word of local variables in the following way:
static byte* p1;
static byte* p2;
void f1()
{
byte b;
p1 = &b;
f2();
}
void f2()
{
byte b;
p2 = &b;
}
void calculate()
{
f1();
int stack_space_used = (int)(p2 - p1);
}
(Note: the function declares a local variable which is only a byte, but the compiler will generally allocate an entire machine word for it on the stack.)
So, this will tell you how much stack space is taken by a function call. The more local variables you add to a function, the more stack space it will take. Variables defined in different scopes within the function usually don't complicate things, as the compiler will generally allocate a distinct area on the stack for every local variable without any attempt to optimize based on the fact that some of these variables might never coexist.
To calculate the stack usage for the current function you can do something like this:
void MyFunc( void );
void *pFnBottom = (void *)MyFunc;
void *pFnTop;
unsigned int uiStackUsage;
void MyFunc( void )
{
__asm__ ( mov pFnTop, esp );
uiStackUsage = (unsigned int)(pFnTop - pFnBottom);
}
Related
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?
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).
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.
How does a compiler know if something is allocated on the heap or stack, for instance if I made a variable in a function and returned the address of the variable, the compiler warns me that "function returns address of a local variable":
#include <stdio.h>
int* something() {
int z = 21;
return &z;
}
int main() {
int *d = something();
return 0;
}
I understand why this is a warning because when the function exits, the stack frame is no more and if you have a pointer to that memory and you change it's value you will cause a segmentation fault. What I wonder is how the compiler will know if that variable is allocating memory via. malloc, or how it can tell if it's a local variable on the stack?
A compiler builds a syntax tree from which it is able to analyze each part of the source code.
It builds a symbol table which associates to each symbol defined some information. This is required for many aspects:
finding undeclared identifiers
checking that types are convertible
so on
Once you have this symbol table it is quite easy to know if you are trying to return the address of a local variable since you end up having a structure like
ReturnStatement
+ UnaryOperator (&)
+ Identifier (z)
So the compiler can easily check if the identifier is a local stack variable or not.
Mind that this information could in theory propagate along assignments but in practice I don't think many compilers do it, for example if you do
int* something() {
int z = 21;
int* pz = &z;
return pz;
}
The warning goes away. With static code flow analysis you could be able to prove that pz could only refer to a local variable but in practice that doesn't happen.
The example in your question is really easy to figure out.
int* something() {
int z = 21;
return &z;
}
Look at the expression in the return statement. It takes the address of the identifier z.
Find out where z is declared. Oh, it is a local variable.
Not all cases will be as easy as this one and it's likely that you can trick the compiler into giving false positives or negatives if you write sufficiently weird code.
If you're interested in this kind of stuff, you might enjoy watching some of the talks given at CppCon'15 where static analysis of C++ code was a big deal. Some remarkable talks:
Bjarne Stroustrup: “Writing Good C++14”
Herb Sutter: “Writing Good C++14… By Default”
Neil MacIntosh: “Static Analysis and C++: More Than Lint”
The compiler knows what chunk of memory is holding the current stack. Every time a function is called it creates a new stack and moves the previous frame and stack pointers appropriately which effectively give it a beginning and endpoint for the current stack in memory. Checking to see if you're trying to return a pointer to memory that's about to get freed is relatively simple given that setup.
What I wonder is how the compiler will know if that variable is
allocating memory via. malloc, or how it can tell if it's a local
variable on the stack?
The compiler has to analyse all the code and generate machine code from it.
When functions need to be called, the compiler has to push the parameters on the stack (or reserve registers for them), update the stack pointer, look if there are local variables, initialize those on the stack too and update the stack pointer again.
So obviously the compiler knows about local variables being pushed on the stack.
A colleague is doing some code review, and he is seeing many static variable declarations similar to the following:
void someFunc(){
static int foo;
static int bar;
static int baz;
foo = 0;
bar = 0;
baz = 0;
/*
rest of the function code goes here
*/
}
Our question is,
Are the programmers who wrote this code simply unclear on the concept of a static variable,
or is there some clever reason to do this on purpose?
If it makes any difference, the environment is an embedded microcontroller and the compiler is GCC.
If it were not an embedded system, you would probably be correct: I would bet that the programmers were unclear on the concept of the static, and must have meant to write this:
static int foo = 0;
static int bar = 0;
static int baz = 0;
However, in an embedded system they could have used static to avoid allocating the variables in the automatic storage (i.e. on the stack). This could save a few CPU cycles, because the address of the static variable would be "baked into" the binary code of the compiled method.
In this context the static memory is allocated only once. The problem with this code is the initialization. If it's being reset at every execution, these variables should exist on the stack.
Implementing the function as it is, undermines the static benefits. The main 2 reasons for using static are:
Having a variable that maintains it's value between calls to the same function
Avoid allocating memory on the stack
#dasblinkenlight answer's pertains to the 2nd option, however there is nobody in embedded programming who would waste unrecoverable memory in order to save 24 bytes (assuming that int is 32 bytes on your architecture) on the stack. The reason is that the compiler is going to manipulate the stack pointer coming in to the function regardless, and therefore there is nothing to be save (in terms of cycles) from not having it push the SP another 24 bytes.
Keeping that in mind, we are left with the option that the user wanted to maintain some information regarding foo, bar and baz between calls. If this is also not the case, what you are looking at is bad programming.
static benefits. are:
Having a variable that maintains it's value between calls to the same function
Avoid allocating memory on the stack
I am learning function pointers,I understand that we can point to functions using function pointers.Then I assume that they stay in memory.Do they stay in stack or heap?Can we calculate the size of them?
The space for code is statically allocated by the linker when you build the code. In the case where your code is loaded by an operating system, the OS loader requests that memory from the OS and the code is loaded into it. Similarly static data as its name suggests is allocated at this time, as is an initial stack (though further stacks may be created if additional threads are created).
With respect to determining the size of a function, this information is known to the linker, and in most tool-chains the linker can create a map file that includes the size and location of all static memory objects (i.e. those not instantiated at run-time on the stack or heap).
There is no guaranteed way of determining the size of a function at run-time (and little reason to do so) however if you assume that the linker located functions that are adjacent in the source code sequentially in memory, then the following may give an indication of the size of a function:
int first_function()
{
...
}
void second_function( int arg )
{
...
}
int main( void )
{
int first_function_length = (int)second_function - (int)first_function ;
int second_function_length = (int)main - (int)second_function ;
}
However YMMV; I tried this in VC++ and it only gave valid results in a "Release" build; the results for a "Debug" build made no real sense. I suggest that the exercise is for interest only and has no practical use.
Another way of observing the size of your code of course is to look at the disassembly of the code in your debugger for example.
Functions are part of text segment (which may or may not be 'heap') or its equivalent for the architecture you use. There's no data past compilation regarding their size, at most you can get their entry point from symbol table (which doesn't have to be available). So you can't calculate their size in practice on most C environments you'll encounter.
They're (normally) separate from either the stack or heap.
There are ways to find their size, but none of them is even close to portable. If you think you need/want to know the size, chances are pretty good that you're doing something you probably ought to avoid.
There's an interesting way to discover the size of the function.
#define RETN_empty 0xc3
#define RETN_var 0xc2
typedef unsigned char BYTE;
size_t FunctionSize(void* Func_addr) {
BYTE* Addr = (BYTE*)Func_addr;
size_t function_sz = 0;
size_t instructions_qt = 0;
while(*Addr != (BYTE)RETN_empty && *Addr != (BYTE)RETN_var) {
size_t inst_sz = InstructionLength((BYTE*)Addr);
function_sz += inst_sz;
Addr += inst_sz;
++instructions_qt;
}
return function_sz + 1;
}
But you need a function that returns the size of the instruction. You can find a function that finds the Instruction Length here: Get size of assembly instructions.
This function basically keeps checking the instructions of the function until it finds the instruction to return (RETN)[ 0xc3, 0xc2], and returns the size of the function.
To make it simple, functions usually don't go into the stack or the heap because they are meant to be read-only data, whereas stack and heap are read-write memories.
Do you really need to know its size at runtime? If no, you can get it by a simple objdump -t -i .text a.out where a.out is the name of your binary. The .text is where the linker puts the code, and the loader could choose to make this memory read-only (or even just execute-only). If yes, as it has been replied in previous posts, there are ways to do it, but it's tricky and non-portable... Clifford gave the most straightforward solution, but the linker rarely puts function in such a sequential manner into the final binary. Another solution is to define sections in your linker script with pragmas, and reserve a storage for a global variable which will be filled by the linker with the SIZEOF(...) section containing your function. It's linker dependent and not all linkers provide this function.
As has been said above, function sizes are generated by the compiler at compile time, and all sizes are known to the linker at link time. If you absolutely have to, you can make the linker kick out a map file containing the starting address, the size, and of course the name. You can then parse this at runtime in your code. But I don't think there's a portable, reliable way to calculate them at runtime without overstepping the bounds of C.
The linux kernel makes similar use of this for run-time profiling.
C has no garbage collector. Having a pointer to something doesn't make it stay in memory.
Functions are always in memory, whether or not you use them, whether or not you keep a pointer to them.
Dynamically allocated memory can be freed, but it has nothing to do with keeping a pointer to it. You shouldn't keep pointer to memory you have freed, and you should free it before losing the pointer to it, but the language doesn't do it automatically.
If there is anything like the size of the function it should be its STACK FRAME SIZE. Or better still please try to contemplate what exactly, according to you, should be the size of a function? Do you mean its static size, that is the size of all its opcode when it is loaded into memory?If that is what you mean, then I dont see their is any language provided feature to find that out.May be you look for some hack.There can be plenty.But I haven't tried that.
#include<stdio.h>
int main(){
void demo();
int demo2();
void (*fun)();
fun = demo;
fun();
printf("\n%lu", sizeof(demo));
printf("\n%lu", sizeof(*fun));
printf("\n%lu", sizeof(fun));
printf("\n%lu", sizeof(demo2));
return 0;
}
void demo(){
printf("tired");
}
int demo2(){
printf("int type funciton\n");
return 1;
}
hope you will get your answer, all function stored somewhere
Here the output of the code
About "static" in C, how is it implemented by the compiler ?
This is a Bloomberg interview question. Any thoughts ?
[[I'm assuming we're talking about static in the context of variables here, because static functions are simply a compile/link-time thing, with no run-time implications.]]
In short, it's implementation-specific. The compiler is free to do anything it chooses.
Typically (but by no means exclusively), statics are stored in the .bss or .data sections of the executable image at fixed locations. This has performance advantages, as they can be accessed with literal addresses, rather than pointer dereferences (as would be the case for stack-based variables). As this is part of the binary, this also means that the initial values are automatically mapped into memory when the executable is first loaded; no intialisation routines are required.
static global variables will generally be allocated a fixed address at compile time. Many OS provide memory regions that are 0-initialised, others that map part of the executable image with preinitialised data, as well as totally uninitialised areas. Depending on whether the compiler can work out the correct initial content of the static variable at compile time, it may select the most appropriate of these memory regions, calling any run-time initialisation later if required. For example:
static int x; // needs to be 0 before main() runs
// best way: 0-initialised memory area
static int y = 3; // best way: map/copy area of executable already containing "3"
static int z = time(NULL); // initial value unimportant
// best way: uninitialised memory area
// pre-main() init code
Notes: putting e.g. z in 0-initialised memory then clobbering it is not significantly wasteful - just not strictly necessary. Some OS may have separate areas for read-only/const values.
static local variables with compile-time known initial values may be created as per globals. For run-time initialised values (only legal in C++) compilers tend to (must?) initialise them when the scope is first entered. This is typically coordinated by having an implicit supporting boolean value per scope containing static local variables: each time the scope is entered the boolean is consulted to see whether the statics need to be initialised. On some compilers, this may actually be done in a less efficient but thread-safe fashion, such that static locals can be used for singleton instances.
EDIT: Given Lundin's comment (correctly) asserting all C statics must be initialised before main(), I wrote some code to explore this:
#include <stdio.h>
#include <time.h>
void f()
{
static int i = time(NULL);
printf("%d\n", i);
}
int main()
{
int i = time(NULL);
printf("%d\n", i);
sleep(2);
f();
}
With GCC's C compiler, I get a fatal compilation error about the local static i requiring initialisation at run-time. Compiled as C++ (my main language), this is perfectly legal and initialised at run-time and after entering main() - showing that that part of my explanation above is only relevant to C++.
static functions are simply marked in the generated object such that the linker won't consider them when matching unresolved calls from other objects.