C - 在C中显示堆栈帧显示其他行

时间:2017-11-20 17:33:28

标签: c stackframe

我有这个函数我编码的目的是打印它所调用的函数的整个堆栈帧:

#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中工作的研究,但我不知道发生了什么。我也不知道汇编,所以我不能真正地拆解这段代码并知道它是如何工作的。

有人能告诉我为什么所有这些异常都会发生,以及如何避免它们?

0 个答案:

没有答案