Windows环境下分析截断Linux core dump 提取象棋引擎Board对象信息
调试前环境准备
你本地持有的是Linux平台的可执行文件和core dump,Windows原生gdb无法直接解析,需要先安装WSL(Windows Subsystem for Linux),推荐选Ubuntu 22.04发行版,将可执行文件、core dump文件都放入WSL的文件系统中,确保可执行文件和编译出赛版的文件完全一致,不要重新编译,否则符号会不匹配。
加载core dump到gdb
在WSL终端中执行命令:
gdb ./Koivisto_4.44-x64-linux-native.exe <你的core dump文件名>
进入gdb交互界面后先执行bt命令,确认栈回溯结果和TCEC管理员提供的一致,保证加载的core文件有效。
定位到getWDL函数上下文
从栈回溯可以看到getWDL在第3号栈帧,执行命令切换到该帧:
frame 3
此时gdb的上下文就处于getWDL函数调用时的运行状态。
提取Board对象内容
- 先获取
board指针的地址,执行:
会输出类似p board(Board *) 0xXXXXXXX的结果,这就是Board对象在内存中的起始地址。 - 打印完整Board对象内容:
- 如果你编译时没有strip掉符号,直接执行
p *board就能输出Board类所有成员变量的值,包括各个位棋盘、50步规则计数、王车易位权限、过路兵位置、行棋方等所有你传入tb_probe_wdl的参数。 - 如果开了O3、LTO后符号被优化掉,gdb无法识别Board类结构,你可以根据自己定义的Board类成员顺序和每个成员的大小,手动偏移读取内存。比如第一个成员是8字节的白方位棋盘,就执行
x/8xb 0xXXXXXXX(替换成你拿到的board指针地址)读取对应内容,依次偏移即可读出所有成员的值。
- 如果你编译时没有strip掉符号,直接执行
排查入参错误点
对照getWDL的传参逻辑,逐一校验参数合法性:
- 首先校验总棋子数:计算
bitCount(*board->getOccupiedBB())是否大于TB_LARGEST(也就是7),如果棋子数超过7,syzygy库计算索引时会直接越界访问,是最高概率的崩溃原因。 - 校验位棋盘合法性:检查是否存在同位置多棋子、王的位棋盘不为1位、棋子位棋盘和队伍位棋盘不匹配等非法状态。
- 校验辅助参数合法性:50步计数是否在0100范围内、王车易位权限是否只有低4位有值、过路兵位置是否在063范围内、行棋方是否为合法的0/1值。
补充:你提供的崩溃指令是
movbe (%r10),%rsi,当前r10寄存器的值为0x7fa7a81ee580,该地址属于非法地址,刚好对应syzygy库根据非法入参计算出错误的表项索引,访问了非法内存的情况,符合你对入参错误的判断。
特殊情况处理
如果你的core dump不完整,读取board指针时提示内存不可访问,可以联系TCEC管理员调整core生成规则,过滤掉100GB的哈希表内存,只保留栈和Board相关的堆内存,即可拿到完整的Board对象内容。
内容的提问来源于stack exchange,提问作者Finn Eggers
相关产品推荐
相关产品推荐

