I have this function I coded who's purpose is to print the entire stack frame of the function it is called in:
#include <stdio.h>
#define FRAME_TYPE_SIZE sizeof(void *)
void view_stack_frame(){
void *start = __builtin_frame_address(1);
void *stop = __builtin_frame_address(0);
printf("\n[View Stack Frame] %p\n", &view_stack_frame);
printf("Address of stack frame: %p\n",stop);
printf("Address of caller's frame: %p\n",start);
printf("\nADDRESS\t\t\tVALUE\n");
while(start>stop){
start -= FRAME_TYPE_SIZE;
long *p = (long *) start;
printf("[%p] \t%ld\n",start,*p);
}
}
And I am using this code to call it:
#include "stackBACKUP.h"
void caller3(){
FTYPE var1 = 1000;
FTYPE var2 = 2000;
FTYPE var3 = 3000;
FTYPE var4 = 4000;
FTYPE var5 = 5000;
FTYPE var6 = 6000;
FTYPE var7 = 7000;
view_stack_frame();
}
void caller2(){
FTYPE var1 = 1000;
FTYPE var2 = 2000;
FTYPE var3 = 3000;
FTYPE var4 = 4000;
FTYPE var5 = 5000;
view_stack_frame();
}
void caller(){
FTYPE var1 = 1000;
FTYPE var2 = 2000;
FTYPE var3 = 3000;
FTYPE var4 = 4000;
FTYPE var5 = 5000;
FTYPE var6 = 6000;
view_stack_frame();
}
int main(void){
caller();
caller2();
caller3();
}
However, when I run the code, this is what I end up getting as output:
[View Stack Frame] 0x55fd8fb3267a
Address of stack frame: 0x7ffd03486770
Address of caller's frame: 0x7ffd034867b0
ADDRESS VALUE
[0x7ffd034867a8] 6000
[0x7ffd034867a0] 5000
[0x7ffd03486798] 4000
[0x7ffd03486790] 3000
[0x7ffd03486788] 2000
[0x7ffd03486780] 1000
[0x7ffd03486778] 94547525969897
[0x7ffd03486770] 140724658530224
[View Stack Frame] 0x55fd8fb3267a
Address of stack frame: 0x7ffd03486770
Address of caller's frame: 0x7ffd034867b0
ADDRESS VALUE
[0x7ffd034867a8] 5000
[0x7ffd034867a0] 4000
[0x7ffd03486798] 3000
[0x7ffd03486790] 2000
[0x7ffd03486788] 1000
[0x7ffd03486780] 1000
[0x7ffd03486778] 94547525969828
[0x7ffd03486770] 140724658530224
[View Stack Frame] 0x55fd8fb3267a
Address of stack frame: 0x7ffd03486760
Address of caller's frame: 0x7ffd034867b0
ADDRESS VALUE
[0x7ffd034867a8] 7000
[0x7ffd034867a0] 6000
[0x7ffd03486798] 5000
[0x7ffd03486790] 4000
[0x7ffd03486788] 3000
[0x7ffd03486780] 2000
[0x7ffd03486778] 1000
[0x7ffd03486770] 140724658530224
[0x7ffd03486768] 94547525969767
[0x7ffd03486760] 140724658530224
I understand what the last 2 values are, when converted to hex, the second to last is slightly before the address of the stack frame, and the last one is the address of the caller's frame. However,I can see some problems here.
The method with 5 variables ends up having an additional entry right after the LAST variable, which is the same as it. The method with 7 variables ends up having an additional entry after the last variable, but this time that entry is the same as the ADDRESS OF THE FUNCTION.
From what I can tell, the stack frame looks like this: [ variables ] [ addresses of functions ] But for the method with 5 and 7 variables, it looks like this: [ variables ] [ last variable ] [ addresses ] [ variables ] [ address of function ] [ addresses ].
I did a lot of research about how stack frames work in C, but I don't know what is going on. I also don't know assembly, so I cannot really dissassemble this code and know how it works.
Can someone tell me why all these anomalys happen, and how to avoid them?