我正在使用国际象棋引擎,并且在查找表中存储了许多预先计算的值。我将这些值放入(非常大的)“magic_numbers.c”文件中(来自名为魔术位板的算法),并将它们声明为全局const内存。这些值在程序执行期间永远不会更改。
我最近遇到了段。错误,这很奇怪。 (首先,这很奇怪,因为它卡在我的整个计算机上!)但是更重要的是,该地址是完全可访问的(请注意下面的GDB输出)。
程序收到信号SIGSEGV,分段故障。
[切换到线程0x7ffe8dd77700(LWP 9001)]
/home/jordan/Projects/thekingsmen/magic.h:107中的magic_get_king_moves(occ = 0,square = 28'\034')中的0x000000000040c9b9
107 return magic_king_moves [square];
(gdb)p magic_king_moves [28]
$ 1 = 241461362688
(gdb)p bitboard_print(magic_king_moves [28])
位板
。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。
。 。 。 1 1 1。 。
。 。 。 1 1 1。 。
。 。 。 1 1 1。 。
。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。
$ 2 =无效
(gdb)bt
#0 0x000000000040c9b9 in magic_get_king_moves(occ = 0,square = 28'\034')
在/home/jordan/Projects/thekingsmen/magic.h:107
#1 pawn_eval_init(board = 0x7ffe8dd76e20,pe = 0x7ffe8dd70fc0)在/home/jordan/Projects/thekingsmen/pawn.c:41
#2 pawn_eval_probe(ptt = ptt @ entry = 0x7ffe780008d0,board = board @ entry = 0x7ffe8dd76e20)
在/home/jordan/Projects/thekingsmen/pawn.c:12
#3 0x000000000040ab6b评估(板= 0x7ffe8dd76e20,搜索= 0x7ffe780008c0)
在/home/jordan/Projects/thekingsmen/evaluate.c:384
qsearch中的#4 0x00000000004063ef(alpha = -1000000000,beta = 293,depth = -2,checks_depth = 12583424,
搜索= 0x7ffe780008c0)在/home/jordan/Projects/thekingsmen/search.c:63
qsearch中的#5 0x0000000000406576(alpha = -293,beta = 1000000000,深度= 3868,checks_depth = 12583424,
搜索= 0x7ffe780008c0)在/home/jordan/Projects/thekingsmen/search.c:148
qsearch中的#6 0x0000000000406576(alpha = -1000000000,beta = 1000000000,depth = 2349,checks_depth = 12583424,
在/home/jordan/Projects/thekingsmen/search.c上,checks_depth @ entry = 0,搜索= 0x7ffe780008c0)
#7 0x0000000000404e57在do_evaluation_thread(params = 0x7fffffffdd68)中
在/home/jordan/Projects/thekingsmen/tweaker.c:299
/usr/lib/libpthread.so.0中start_thread()中的#8 0x00007ffff78c0374
#9 0x00007ffff6d9027d在/usr/lib/libc.so.6的clone()中
当我也关闭线程时,也会发生这种情况。
我已经通过valgrind的memcheck运行了该程序,它没有报告任何可疑的事件。
段。当我关闭优化后,故障确实消失了,所以我倾向于认为这是某个地方的未定义行为,但是我仍然不明白为什么它无法访问我可以从GDB内部访问的内存。
编辑:内存在文件“magic_numbers.c”中声明为:
const bitboard_t magic_king_moves [0x40] = {
0x303,
0x707,
0xe0e,
0x1c1c,
0x3838,
0x7070,
0xe0e0,
...
使用bitboard_t作为类型定义的uint64_t。
这段代码是由我一直在使用的单独工具自动生成的。
谢谢,
约旦
最佳答案
我还没有完全找到该错误,但是很明显,上面的GDB输出中发生了什么。堆栈帧6处的“depth”参数非常疯狂,“checks_depth”也是如此。某种情况是覆盖堆栈上的值(似乎在任意点),这导致它覆盖了返回地址。
段错误不是在访问内存时发生的,而是在尝试返回到该错误时发生的。
有趣的是谈论堆栈溢出:)