GDB中针对数组内uint16_t值设置的观察点未触发,如何解决?
问题根源与解决方法
1. 核心问题:全局数组初始值不符合预期
你代码中的heap是全局char数组,C语言里全局变量默认会被初始化为0,而非你假设的9999。所以*(uint16_t*)&heap[2]的初始值是0,在proc0断点执行减1操作后,会变成0xFFFF(即uint16_t类型的65535),完全达不到9998的触发条件,观察点自然不会执行。
2. 修复步骤
步骤1:初始化目标值(二选一即可)
方法A:修改C代码初始化
在main函数里给heap[2]对应的16位值设置初始值9999:
#include <stdint.h> #include <stdlib.h> #define HEAP_SIZE 65536 char heap[HEAP_SIZE]; void proc0(); void proc1(); void proc0() { } void proc1() { } void main() { *(uint16_t *) &heap[0] = (uint16_t) 4; // 初始化heap[2]对应的16位值为9999 *(uint16_t *) &heap[2] = (uint16_t) 9999; proc0(); exit(0); }
方法B:在GDB中初始化
如果不想修改C代码,可在GDB命令文件的run前添加初始化命令:
set *(uint16_t*) &heap[2] = 9999
步骤2:优化GDB命令(可选简化)
可以直接把条件合并到watch命令中,省去单独的cond指令:
# 直接设置带条件的观察点 watch *(uint16_t*) &heap[2] == 9998 commands set *(uint16_t*) &heap[0] = 50 p *(uint16_t*) &heap[0] continue end break proc0 commands set *(uint16_t*) &heap[2] = (*(uint16_t*) &heap[2]) - 1 c end # 若用方法B初始化,在此处添加set命令 # set *(uint16_t*) &heap[2] = 9999 run q
3. 验证效果
重新编译程序:gcc -g -o mainh test.c,再执行gdb -q -x commandsh.txt mainh,此时:
- 程序触发
proc0断点,将heap[2]的16位值从9999减为9998 - 观察点检测到值符合条件,自动执行命令:把
heap[0]的16位值设为50,打印该值后继续执行 - 最终会看到GDB输出
$1 = 50,符合预期
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

