回答後の承認の概要: 問題は、スコープ外になったスタック変数へのポインターの使用でした。最適化とは何の関係もありませんでした。valgrind がスタックエラーを見つけられないのは残念です...
gcc 4.4.4 (CentOS 5.5) で -O1 レベルの最適化を有効にした場合にのみ表示される segfault があります。他のすべての最適化レベル (0、2、3、s) は問題ありません。縮小したテスト ケースはまだ作成できていませんが、スタックが上書きされる原因となる配列オフセット計算に関連しているようです。
-O1 を有効にして、フラグ ( http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html )を持つすべての最適化を無効にしても、バグは引き続き発生します。
-O2 (またはその他のレベル) を使用しても問題はありません。O2 を使用して厳密なエイリアスを無効にすると-fno-strict-aliasing
、segfault が返されます。
編集:-fstack-protector-all
ビルドフラグ(またはのいずれO1
か)に追加するとO2 -fno-strict-aliasing
、segfaultが消えます。
そのため、厳密なエイリアスによって無効にされている O1 でデフォルトで発生する最適化が原因であると思われます。
これはコンパイラのバグだと思います (しかし、縮小されたテストケースがなければ、それを証明することはできません)。これは、迅速なターンアラウンドが必要な本番サーバーです。通常の最適化レベルは O1 ですが、O2 に変更するのは気が進まないのです。なぜなら、この修正は元の問題よりも危険であると思われるからです。
いくつかの提案をいただければ幸いです。現在、gcc 4.4.6 をコンパイルして、それが修正されるかどうかを確認しようと考えています。しかし、何が問題を引き起こしているのかわからないということは、少し心配です。
編集:サーバーは-Wall -Werror
(およびその他のいくつか)でコンパイルされます。valgrind ではエラーなしで実行されます (valgrind はヒープ アクセスをチェックしますが、これはスタック関連のエラーのようです)。