我有这个函数我编码的目的是打印它所调用的函数的整个堆栈帧:
#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);
}
}
我正在使用此代码来调用它:
#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();
}
然而,当我运行代码时,这就是我最终获得的输出:
[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
我理解后两个值是什么,当转换为十六进制时,倒数第二个稍微先于堆栈帧的地址,最后一个是调用者帧的地址。但是,我在这里可以看到一些问题。
具有5个变量的方法最终在LAST变量之后有一个额外的条目,它与它相同。具有7个变量的方法最终在最后一个变量之后有一个附加条目,但这次该条目与该函数的地址相同。
据我所知,堆栈框架如下所示: [变量] [函数地址] 但对于具有5和7变量的方法,它看起来像这样: [变量] [最后一个变量] [地址] [变量] [功能地址] [地址]。
我做了很多关于堆栈框架如何在C中工作的研究,但我不知道发生了什么。我也不知道汇编,所以我不能真正地拆解这段代码并知道它是如何工作的。
有人能告诉我为什么所有这些异常都会发生,以及如何避免它们?