C const 全局内存段错误(在存在的地址上)

C const global memory seg fault (on address which exists)

我正在研究国际象棋引擎,并且在查找表中存储了很多预先计算的值。我将这些值放入一个(非常大的)'magic_numbers.c' 文件(来自名为 magic bitboards 的算法),并将它们声明为全局常量内存。这些值在程序执行期间永远不会改变。

我最近 运行 进入了一个赛段。这是相当奇怪的错误。 (首先,这很奇怪,因为它挂了我的整个计算机!)但更重要的是,该地址是完全可访问的(请注意下面的 GDB 输出)。


    程序收到信号 SIGSEGV,分段错误。
    [切换到线程 0x7ffe8dd77700 (LWP 9001)]
    0x000000000040c9b9 in magic_get_king_moves (occ=0, square=28 '\034') 在 /home/jordan/Projects/thekingsmen/magic.h:107
    107returnmagic_king_moves[正方形];
    (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
    #4 qsearch 中的 0x00000000004063ef(alpha=-1000000000,beta=293,深度=-2,checks_depth=12583424,
        搜索=0x7ffe780008c0) 在 /home/jordan/Projects/thekingsmen/search.c:63
    #5 qsearch 中的 0x0000000000406576(alpha=-293,beta=1000000000,深度=3868,checks_depth=12583424,
        搜索=0x7ffe780008c0) 在 /home/jordan/Projects/thekingsmen/search.c:148
    #6 qsearch 中的 0x0000000000406576(alpha=-1000000000,beta=1000000000,深度=2349,checks_depth=12583424,
        checks_depth@entry=0,搜索=0x7ffe780008c0) 在 /home/jordan/Projects/thekingsmen/search.c:148
    #7 do_evaluation_thread 中的 0x0000000000404e57(参数=0x7fffffffdd68)
        在 /home/jordan/Projects/thekingsmen/tweaker.c:299
    #8 0x00007ffff78c0374 在 start_thread () 来自 /usr/lib/libpthread.so.0
    #9 0x00007ffff6d9027d in clone () from /usr/lib/libc.so.6

当我关闭线程时也会发生这种情况。

我已经 运行 通过 valgrind 的内存检查程序,它没有报告任何可疑的东西。

段。当我关闭优化时故障确实消失了,所以我倾向于认为它是某处未定义的行为,但我仍然不明白为什么它无法访问我可以从 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' 一样疯狂。某些东西正在覆盖堆栈上的值(似乎是在任意点),这导致它覆盖了 return 地址。

段错误不是在访问内存时发生的,而是在尝试return到它所在的位置时发生的。

在堆栈溢出时谈论堆栈溢出很有趣 :)