每天学点GDB(七)

    xiaoxiao2026-02-08  0

    近两周在做一个trouble shooting,需要对函数调用栈进行分析以找出入参和局部变量。因为在编译生成可执行程序的时候,用gcc进行了O2的优化,许多假设的函数调用栈模型都不成立了。花了一番周折,终于正确的翻译出入参和局部变量,此一旅程中的一些经验还是值得记录下来。

    在32位x86系统上,函数调用栈的布局如下图所示。

    栈底在高地址段,栈顶在低地址段。

    从栈底到栈顶的内容分别为:

    函数入参返回地址保存的寄存器值被调用函数的局部变量

    如果带有调试信息,则要获取上述4个部分的值很容易,对应的指令分别如下。

    info argsinfo frameinfo registersinfo locals

    如果没有调试信息,则可以根据这一模型并结合反汇编的结果来算出入参与局部变量的存储位置。针对32位的具体例子比较容易找到。

    现在专门提一提在x86 64位下的不同,在x86 64下,因为寄存器数量增多,为了提高效率,入参基本上都是通过寄存器来传递。示例程序如下:

    #include <stdlib.h> #include <stdio.h> #include <unistd.h> int demo_func(char* msg, int a, int b); int main(int argc, char** argv) { char* info = "just a demo"; int a,b; a = 320; b = 100; demo_func(info, a, b); return 0; } int demo_func(char* msg, int a, int b) { int sum; sum = a + b; return sum; }

    main函数反汇编结果如下:

    Dump of assembler code for function main: 0x00000000004004b0 <+0>: push %rbp 0x00000000004004b1 <+1>: mov %rsp,%rbp 0x00000000004004b4 <+4>: sub $0x20,%rsp 0x00000000004004b8 <+8>: mov
    转载请注明原文地址: https://yun.8miu.com/read-144904.html
    最新回复(0)