如何调试函数是否修改了指针参数本身而非指向内存?
如何在调试器中监视指针参数本身的修改(而非指向的内存)
当然可以实现!你需要的是监视指针参数变量自身的存储位置——也就是函数栈上argA、argB这些变量所在的内存单元,看它们存储的地址值是否被修改,而非跟踪它们指向的内存内容。主流调试器都支持这个操作,下面分常用工具详细说明:
GDB (GNU Debugger)
- 先在目标函数的入口处设置断点,比如:
b function_name - 运行程序触发断点后,确认参数已经在栈上分配完成
- 直接监视指针变量本身的值变化:
- 输入
watch argA,这个命令会监视argA变量的内容(也就是指针存储的地址),一旦argA被赋值为新的地址,调试器就会触发中断 - 如果需要更精确,也可以先获取
argA的内存地址:print &argA,得到类似0x7fffffffeabc的地址,然后用watch *0x7fffffffeabc(效果和watch argA一致)
- 输入
- 继续运行程序:
c,当argA的指针值被修改时,调试器会自动停住并提示变化
Visual Studio 调试器
- 在目标函数入口处设置断点,程序停住后找到
argA、argB变量 - 右键
argA变量,选择**"设置数据断点"**,这会自动创建一个监视argA所在内存单元的断点 - 或者手动打开"监视"窗口,输入
&argA获取变量的内存地址,然后右键该地址条目,选择**"数据断点"** - 继续调试,当
argA的指针值被修改时,调试器会立即中断并显示修改前后的值
LLDB (Xcode/Clang 调试器)
- 在函数入口设置断点:
breakpoint set --name function_name - 程序停住后,设置监视点跟踪指针变量本身:
- 输入
watchpoint set variable argA,这个命令专门监视argA变量的内容变化(即指针存储的地址) - 如果要监视指针指向的内存才用
watchpoint set expression *argA
- 输入
- 继续运行:
continue,指针值被修改时会触发中断
关键注意事项
- 硬件监视点限制:大多数CPU只支持2-4个硬件监视点,所以不要同时设置过多这类断点
- 关闭编译优化:如果代码开启了编译优化(比如
-O2),编译器可能会把参数放到寄存器中而非栈上,导致监视栈地址失效。建议用-O0编译调试版本 - 时机重要:必须在进入目标函数后再设置监视点,因为函数参数是在调用时才被压入栈中的,未进入函数前参数的内存地址不存在
内容的提问来源于stack exchange,提问作者nyumerics
相关产品推荐
相关产品推荐

