You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在LLDB或GDB中查看完整函数栈帧?求操作示例及输出解析

在GDB/LLDB中查看完整栈帧信息

下面分别介绍GDB和LLDB中查看函数参数、旧ebp、返回地址、局部变量的具体操作和示例。


GDB 操作指南

核心命令

  • bt:打印所有栈帧的概览,快速定位目标栈帧
  • frame <帧编号>:切换到指定栈帧(例如frame 0是当前正在执行的栈帧)
  • info frame:显示当前栈帧的详细元数据,包含栈帧起止地址、返回地址、参数列表位置
  • info args:列出当前栈帧的所有函数参数及对应值
  • info locals:列出当前栈帧的所有局部变量及对应值
  • x/[数量][格式] $ebp:手动查看ebp附近的栈内存,直接读取旧ebp、返回地址、参数等原始数据

实操示例

先准备一个测试C程序:

#include <stdio.h>

int add(int a, int b) {
    int c = a + b;
    return c;
}

int main() {
    int x = 5, y = 7;
    int result = add(x, y);
    printf("Result: %d\n", result);
    return 0;
}

编译时带上调试信息:gcc -g test.c -o test

  1. 启动GDB并运行程序:

    gdb ./test
    break add  # 在add函数入口设断点
    run        # 启动程序,触发断点
    
  2. 查看当前栈帧元数据:

    info frame
    

    输出示例:

    Stack level 0, frame at 0x7fffffffdd90:
    rip = 0x555555555149 in add (test.c:4); saved rip = 0x555555555176
    called by frame at 0x7fffffffddb0
    source language c.
    Arglist at 0x7fffffffdd80, args: a=5, b=7
    Locals at 0x7fffffffdd80, Previous frame's sp is 0x7fffffffdd90
    Saved registers:
    rbp at 0x7fffffffdd80, rip at 0x7fffffffdd88
    这里的saved rip就是返回地址,rbp at 0x7fffffffdd80是当前栈帧的ebp值。

  3. 查看旧ebp(调用者的ebp):
    当前ebp指向的内存值就是旧ebp,执行:

    x/x $rbp
    

    输出示例:0x7fffffffdd80: 0x00007fffffffddb0,这个值就是main函数栈帧的ebp。

  4. 查看参数和局部变量:

    info args   # 查看参数
    info locals # 查看局部变量
    

    输出示例:

    a = 5
    b = 7
    c = 0

  5. 手动查看栈内存(验证结构):

    x/8x $ebp
    

    输出示例:

    0x7fffffffdd80: 0x00007fffffffddb0 0x0000555555555176 0x0000000000000005 0x0000000000000007
    0x7fffffffdd90: 0x0000000000000000 0x00007fffffffde38 0x0000555555555150 0x00007fffffffddb0
    从左到右依次是:旧ebp、返回地址、参数a、参数b。


LLDB 操作指南

核心命令

  • bt:打印所有栈帧概览
  • frame select <帧编号>:切换到指定栈帧(例如frame select 0)
  • frame info:显示当前栈帧的基础信息,包含函数参数值
  • frame variable:同时列出当前栈帧的参数和局部变量
  • register read rbp:查看当前rbp(对应x86的ebp)的值
  • x/[数量][格式] $rbp:手动查看rbp附近的栈内存,读取旧ebp、返回地址等数据

实操示例

使用同样的测试程序,编译后启动LLDB:

lldb ./test
breakpoint set -n add  # 在add函数入口设断点
run                    # 启动程序,触发断点
  1. 查看当前栈帧基础信息:

    frame info
    

    输出示例:

    frame #0: 0x0000000100003f49 test`add(a=5, b=7) at test.c:4:9
    1 #include <stdio.h>
    2
    3 int add(int a, int b) {
    -> 4 int c = a + b;
    5 return c;
    6 }
    这里直接显示了参数a和b的值。

  2. 查看寄存器(获取rbp和当前指令地址):

    register read rbp rip
    

    输出示例:

    rbp = 0x00007ff7bfeff580
    rip = 0x0000000100003f49 test`add(a=5, b=7) at test.c:4:9

  3. 查看返回地址和旧ebp:

    • 返回地址存储在$rbp + 8的位置:x/x $rbp+8,输出示例:0x7ff7bfeff588: 0x0000000100003f76
    • 旧ebp是$rbp指向的内存值:x/x $rbp,输出示例:0x7ff7bfeff580: 0x00007ff7bfeff5a0
  4. 查看参数和局部变量:

    frame variable
    

    输出示例:

    (int) a = 5
    (int) b = 7
    (int) c = 0


关于你提到的命令说明

  • finish:这个命令是执行完当前函数并返回调用者,不是用来查看当前栈帧细节的,执行后栈帧会自动切换到上一级。
  • frame info:GDB中它只显示栈帧的元数据(地址、返回地址等),需要结合info args/info locals查看变量;LLDB中它会直接显示参数,但要获取旧ebp、返回地址还需要结合寄存器和内存查看命令。

内容的提问来源于stack exchange,提问作者Kato Megumi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:54:51