GDB自定义DISPLAY命令失效:如何一键追踪函数所有变量?
问题描述
我希望通过一条命令显示并逐步追踪指定C函数的所有变量,GDB没有内置此类命令。我用ChatGPT生成了一段Python脚本,实现名为DISPLAY的自定义命令,但执行后无任何输出,无法正常工作。
原脚本如下:
class DisplayCommand(gdb.Command): def __init__(self): super(DisplayCommand, self).__init__("DISPLAY", gdb.COMMAND_USER) def invoke(self, arg, from_tty): frame = gdb.selected_frame() block = frame.block() while block: for sym in block: if (sym.is_argument or sym.is_variable) and not sym.is_function and not sym.is_constant: try: gdb.execute("display " + sym.name) except gdb.error: pass block = block.superblock DisplayCommand()
GDB版本及配置信息:
fedor@fedor-Latitude-E7250:~/c$ gdb --version GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. fedor@fedor-Latitude-E7250:~/c$ gdb --configuration This GDB was configured as follows: configure --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-auto-load-dir=$debugdir:$datadir/auto-load --with-auto-load-safe-path=$debugdir:$datadir/auto-load --with-expat --with-gdb-datadir=/usr/share/gdb (relocatable) --with-jit-reader-dir=/usr/lib/gdb (relocatable) --without-libunwind-ia64 --with-lzma --with-babeltrace --without-intel-pt --with-mpfr --without-xxhash --with-python=/usr (relocatable) --without-guile --disable-source-highlight --with-separate-debug-dir=/usr/lib/debug (relocatable) --with-system-gdbinit=/etc/gdb/gdbinit ("Relocatable" means the directory can be moved with the GDB installation tree, and GDB will still find it.)
解决方案
一、修复原Python脚本
原脚本存在几个核心问题:未支持指定目标函数、会误加载全局/上层函数变量、无操作反馈、未处理重复追踪。修复后的脚本如下:
class DisplayCommand(gdb.Command): def __init__(self): super(DisplayCommand, self).__init__("DISPLAY", gdb.COMMAND_USER, gdb.COMPLETE_FUNCTION) def invoke(self, arg, from_tty): target_func = arg.strip() if not target_func: print("请指定要追踪的函数名,例如:DISPLAY my_function") return # 清除已有追踪项,避免重复 gdb.execute("undisplay", to_string=True) try: # 定位目标函数的代码块 func_block = gdb.lookup_symbol(target_func)[0].block except gdb.error: print(f"无法找到函数 {target_func}") return added_vars = [] # 遍历并添加函数的参数和局部变量 for sym in func_block: if (sym.is_argument or sym.is_variable) and not sym.is_function and not sym.is_constant: try: gdb.execute(f"display {sym.name}", to_string=True) added_vars.append(sym.name) except gdb.error as e: print(f"无法追踪变量 {sym.name}: {str(e)}") if added_vars: print(f"已添加以下变量到追踪列表:") for var in added_vars: print(f" - {var}") else: print(f"函数 {target_func} 中没有可追踪的变量") DisplayCommand()
修改要点:
- 支持通过命令参数指定目标函数,不再局限于当前栈帧
- 增加函数符号查找逻辑,精准定位目标函数的变量范围
- 自动清除旧追踪项,避免重复显示
- 增加操作反馈,明确显示成功/失败的变量
- 配置函数名补全,输入时按Tab可自动补全函数名
二、脚本使用步骤
- 将修复后的脚本保存为
display_func_vars.py - 在GDB中加载脚本:
source display_func_vars.py - 执行命令:
DISPLAY 目标函数名,例如DISPLAY main
三、替代方案(无需脚本)
如果不想使用Python脚本,可通过GDB内置命令组合实现:
- 给目标函数加断点:
break 目标函数名 - 运行程序触发断点:
run - 批量添加变量追踪:
# 追踪局部变量 info locals | grep -E '^[a-zA-Z0-9_]+' | awk '{print "display " $1}' | gdb -x - # 追踪函数参数 info args | grep -E '^[a-zA-Z0-9_]+' | awk '{print "display " $1}' | gdb -x -
内容的提问来源于stack exchange,提问作者Fyodor
相关产品推荐
相关产品推荐

