【问题标题】:C const global memory seg fault (on address which exists)C const 全局内存段错误(在存在的地址上)
【发布时间】:2015-02-24 04:12:43
【问题描述】:

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

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

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

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

我已经通过 valgrind 的 memcheck 运行了这个程序,它没有报告任何可疑的东西。

段。当我关闭优化时,错误确实消失了,所以我倾向于认为这是某处未定义的行为,但我仍然不明白为什么它无法访问我可以从 GDB 中访问的内存。

编辑:内存在文件“magic_numbers.c”中声明为:

常量 bitboard_t magic_king_moves[0x40] = { 0x303, 0x707, 0xe0e, 0x1c1c, 0x3838, 0x7070, 0xe0e0, ...

bitboard_t 是一个 typedef 的 uint64_t。

此代码由我一直在使用的单独工具自动生成。

谢谢,

约旦

【问题讨论】:

  • 注意\034(即字符")。你确定 square 完全是一个整数 28 并且你没有遇到一些“越界”异常吗?
  • 是的,我很肯定。平方数介于 0 和 63(含)之间,因此在 28 号方位出现国王是可能的。 (现在,为什么国王会想知道那么远是另一个问题。)

标签: c linux segmentation-fault


【解决方案1】:

我还没有完全找到这个错误,但是从上面的 GDB 输出中可以清楚地看出发生了什么。堆栈帧#6 的“深度”参数和“checks_depth”一样疯狂。有些东西正在覆盖堆栈上的值(似乎是在任意点),这导致它覆盖了返回地址。

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

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

【讨论】:

    猜你喜欢
    • 2019-01-06
    • 1970-01-01
    • 2012-06-11
    • 2014-06-05
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 2021-05-23
    • 2017-08-28
    相关资源
    最近更新 更多