2015-02-24 1 views
2

Я работаю над шахматным движком и имею много предварительно вычисленных значений, хранящихся в справочных таблицах. Я помещал эти значения в (очень большой) файл magic_numbers.c (из алгоритма с именем magic bitboards) и объявлял их как глобальную память const. Эти значения никогда не изменяются во время выполнения программы.C const global memory seg fault (по адресу, который существует)

Я недавно столкнулся с сегом. что было довольно странно. (Во-первых, это было странно, потому что он повесил мой весь компьютер!) Но что более важно, адрес был полностью доступен (обратите внимание на вывод GDB ниже).

 

    Program received signal SIGSEGV, Segmentation fault. 
    [Switching to Thread 0x7ffe8dd77700 (LWP 9001)] 
    0x000000000040c9b9 in magic_get_king_moves (occ=0, square=28 '\034') at /home/jordan/Projects/thekingsmen/magic.h:107 
    107  return magic_king_moves[square]; 
    (gdb) p magic_king_moves[28] 
    $1 = 241461362688 
    (gdb) p bitboard_print(magic_king_moves[28]) 
    Bitboard 
    . . . . . . . . 
    . . . . . . . . 
    . . . . . . . . 
    . . . 1 1 1 . . 
    . . . 1 1 1 . . 
    . . . 1 1 1 . . 
    . . . . . . . . 
    . . . . . . . . 
    $2 = void 
    (gdb) bt 
    #0 0x000000000040c9b9 in magic_get_king_moves (occ=0, square=28 '\034') 
     at /home/jordan/Projects/thekingsmen/magic.h:107 
    #1 pawn_eval_init (board=0x7ffe8dd76e20, pe=0x7ffe8dd70fc0) at /home/jordan/Projects/thekingsmen/pawn.c:41 
    #2 pawn_eval_probe ([email protected]=0x7ffe780008d0, [email protected]=0x7ffe8dd76e20) 
     at /home/jordan/Projects/thekingsmen/pawn.c:12 
    #3 0x000000000040ab6b in evaluate (board=0x7ffe8dd76e20, search=0x7ffe780008c0) 
     at /home/jordan/Projects/thekingsmen/evaluate.c:384 
    #4 0x00000000004063ef in qsearch (alpha=-1000000000, beta=293, depth=-2, checks_depth=12583424, 
     search=0x7ffe780008c0) at /home/jordan/Projects/thekingsmen/search.c:63 
    #5 0x0000000000406576 in qsearch (alpha=-293, beta=1000000000, depth=3868, checks_depth=12583424, 
     search=0x7ffe780008c0) at /home/jordan/Projects/thekingsmen/search.c:148 
    #6 0x0000000000406576 in qsearch (alpha=-1000000000, beta=1000000000, depth=2349, checks_depth=12583424, 
     [email protected]=0, search=0x7ffe780008c0) at /home/jordan/Projects/thekingsmen/search.c:148 
    #7 0x0000000000404e57 in do_evaluation_thread (params=0x7fffffffdd68) 
     at /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 

Это происходит, когда я также выключаю резьбу.

Я запускаю программу через memcheck valgrind, и она не сообщает ничего подозрительного.

Сегмент. ошибка исчезает, когда я отключу оптимизацию, поэтому я склонен думать, что это неопределенное поведение где-то, но я до сих пор не понимаю, почему он не сможет получить доступ к памяти, к которой я могу получить доступ из GDB.

EDIT: Память объявлена ​​в файле "magic_numbers.c", как:

 

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

С bitboard_t будучи typedef'd uint64_t.

Этот код генерируется автоматически с помощью отдельного инструмента, над которым я работал.

Спасибо,

Jordan

+2

Обратите внимание на '\ 034' (что символ' "'). Вы уверены, что квадрат точно '28' как целое, и вы не получил некоторые «за пределами» исключения? – kiwixz

+0

Да, я уверен. Квадратное число находится между 0 и 63 (включительно), поэтому возможен король на квадрате 28. (Теперь, почему король задумался, это еще один вопрос .) – Jordan

ответ

2

Я не нашел ошибку еще раз, но это довольно ясно, что происходит с выхода GDB выше. Параметр «глубина» в кадре стека # 6 безумный, как и «checks_depth». Что-то переписывает значения в стеке (кажется, в произвольных точках), что заставило его перезаписать обратный адрес.

Не удалось получить отказ в доступе к памяти, но при попытке вернуться к точке, где она была.

Смешные говорить о переполнении стека на переполнение стека :)