Сводка после принятия ответа: Проблема заключалась в использовании указателя на переменную стека, которая вышла из области видимости. Это не имеет ничего общего с оптимизацией. Жаль, что valgrind не может найти ошибки стека ...
У меня есть segfault, который появляется только при включении оптимизации уровня -O1 в gcc 4.4.4 (CentOS 5.5). Все остальные уровни оптимизации (0,2,3, с) в порядке. Мне еще не удалось создать сокращенный тестовый пример для него, но, похоже, это связано с вычислением смещения массива, которое приводит к перезаписи стека.
Если я включаю -O1 и отключаю все оптимизации, которые имеют флаг (http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html), ошибка все равно возникает.
Если я использую -O2 (или любой другой уровень), проблем не будет. Если я использую O2 и отключаю строгое-алиасинг с помощью -fno-strict-aliasing
, то возвращается segfault.
Редактировать: Если я добавлю -fstack-protector-all
к флагам сборки (либо O1
, либо O2 -fno-strict-aliasing
), ошибка сегмента исчезнет.
Таким образом, это, кажется, вызвано оптимизацией, которая происходит по умолчанию в O1, которая отключена строгим псевдонимом.
Я подозреваю, что это ошибка компилятора (но без сокращенного теста я не могу это доказать). Это рабочий сервер, который нужно быстро развернуть. Обычный уровень оптимизации - O1, и я не хочу просто менять его на O2, так как кажется, что исправление может быть более опасным, чем исходная проблема.
Буду очень признателен за некоторые предложения. В настоящее время я пытаюсь скомпилировать gcc 4.4.6 и посмотреть, исправит ли это. Однако, не зная наверняка, что является причиной проблемы, немного беспокоит.
Редактировать: сервер скомпилирован с -Wall -Werror
(и некоторыми другими). Он работает без ошибок в valgrind (valgrind проверяет доступ к куче, и это похоже на ошибку стека).