Отладка segfault без видимой причины в GDB?

GDB сообщал, что мой код C сбой где-то в malloc()Поэтому я связал свой код с Electric Fence, чтобы точно определить источник ошибки памяти. Теперь мой код сегрегируется намного раньше, но вывод GDB еще более запутан:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x30026b00 (LWP 4003)]
0x10007c30 in simulated_status (axis=1, F=0x300e7fa8, B=0x1003a520, A=0x3013b000, p=0x1003b258, XS=0x3013b000)
    at ccp_gch.c:799

РЕДАКТИРОВАТЬ: полная обратная трассировка:

(gdb) bt
#0  0x10007c30 in simulated_status (axis=1, F=0x300e7fa8, B=0x1003a520, A=0x3013b000, p=0x1003b258, XS=0x3013b000)
    at ccp_gch.c:799
#1  0x10007df8 in execute_QUERY (F=0x300e7fa8, B=0x1003a520, iData=0x7fb615c0) at ccp_gch.c:836
#2  0x10009680 in execute_DATA_cmd (P=0x300e7fa8, B=0x7fb615cc, R_type=0x7fb615d0, iData=0x7fb615c0)
    at ccp_gch.c:1581
#3  0x10015bd8 in do_volley (client=13) at session.c:76
#4  0x10015ef4 in do_dialogue (v=12, port=2007) at session.c:149
#5  0x10016350 in do_session (starting_port=2007, ports=1) at session.c:245
#6  0x100056e4 in main (argc=2, argv=0x7fb618f4) at main.c:271

Соответствующий код (слегка измененный по причинам):

796  static uint32_t simulated_status(
797      unsigned axis, struct foo *F, struct bar *B, struct Axis *A, BAZ *p, uint64_t *XS)
798  {
799      uint32_t result = A->status;
800      *XS = get_status(axis);
801      if (!some_function(p)) {
802          ...

Очевидная вещь, чтобы проверить, будет ли A->status Действительная память, но это так. Удаление назначения переводит segfault в строку 800, а удаление этого назначения вызывает некоторое другое назначение в блоке if для segfault. Похоже, что либо обращение к аргументу, переданному в функцию, либо запись в локальную переменную - вот что вызывает segfault, но все указывает на правильную память в соответствии с gdb.

Как мне это интерпретировать? Я никогда не видел ничего подобного раньше, поэтому любые предложения / указатели в правильном направлении будут оценены. Я использую GNU GDB 6.8-Debian, Electric Fence 2.1 и работаю на PowerPC 405 (отчеты uname Linux powerpmac 2.6.30.3 #24 [...] ppc GNU/Linux).

1 ответ

Я предполагаю, но ваши симптомы похожи на то, что может произойти в ситуации переполнения стека. -fstack-protector предложение в комментариях находится на правильном пути здесь. Я бы также рекомендовал добавить опцию -fstack-check.

Если SEGV происходит из-за записи на защитную страницу, защищающую стек, а затем info registers а также info frame в GDB поможет подтвердить, если это так.

Другие вопросы по тегам