单步调试指针需用step而非next才能捕获赋值时机,print需手动刷新且要区分ptr、*ptr、&ptr;指针异常先查释放、越界或竞态;watch比display更可靠地监控指针变更。

用 next 和 step 单步时,指针值不会自动刷新
很多人以为单步执行后 print ptr 就能立刻看到指针变化,结果发现值没变——其实不是没变,是没重新读取。GDB 不会自动跟踪变量,每次想看最新值都得手动 print 一次。
更关键的是:next 遇到函数调用(比如 malloc、strdup)会跳过整个调用,你根本看不到返回值赋给指针那一步;而 step 才会停在函数返回后、赋值完成的那一刻,这才是观察指针更新的合理时机。
-
step更适合查看指针被赋值、重定向、释放后的状态 -
next容易漏掉指针变化的关键节点,尤其在封装了内存操作的函数里 - 如果函数没有调试信息(没加
-g编译),step会直接运行完函数,无法停在返回点
打印指针本身、指向内容、地址三者要分清
调试指针最常犯的错,是把 print ptr、print *ptr、print &ptr 混为一谈。它们分别表示:
-
print ptr:输出指针变量存储的地址值(比如0x55555556b2a0) -
print *ptr:解引用,输出该地址上存的数据(比如一个int值或字符串首字符) -
print &ptr:输出指针变量自身的地址(即“指针的指针”所在位置)
例如,有 char *p = malloc(4); p[0] = 'a';,单步到赋值后执行:
print p → 0x55555556b2a0<br>print *p → 97<br>print &p → 0x7fffffffe1a8
少打一个 * 或多打一个 &,看到的就是完全不同的东西。
指针被修改但 print 显示不变?检查是否野指针或已释放
单步过程中突然发现 print ptr 输出 0x0 或乱码地址(如 0xffffffffdeadbeef),别急着怀疑 GDB,先确认这几件事:
- 是否刚调用了
free(ptr)?释放后指针未置NULL,值可能残留但已不可访问 - 是否越界写入破坏了栈上指针变量自身(比如缓冲区溢出覆盖了邻近的
char *变量) - 是否在多线程环境里,另一个线程并发修改了该指针,而你没加
watch监视 - 用
x/1gx ptr看一眼该地址是否可读,若报Cannot access memory,说明指针已失效
想自动盯住指针变化?用 display 或 watch
display 是懒人方案:它会在每次停顿时自动执行一次表达式并输出,比如:
display ptr<br>display *ptr<br>display (int)strlen(ptr)
但注意:display 不触发中断,只刷新显示;而 watch ptr 是真监视——只要指针变量自身值改变(比如 ptr = NULL),GDB 就立即中断,比手动单步+print 靠谱得多。
不过 watch 有代价:它依赖硬件断点或单步陷阱,在优化编译(-O2)下可能失效;且对局部指针监视效果不稳定,优先用于全局或静态指针。
真正难啃的指针问题,往往卡在“不知道哪行代码悄悄改了它”,这时候与其反复 next,不如直接 watch ptr 然后 continue——GDB 会替你抓住那只手。


















