a.out ファイルを実行しています。実行後、プログラムはしばらく実行され、次のメッセージとともに終了します。
**** stack smashing detected ***: ./a.out terminated*
*======= Backtrace: =========*
*/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)Aborted*
これにはどのような理由が考えられますか? また、どうすれば修正できますか?
ベストアンサー1
ここでのスタック スマッシングは、実際には gcc がバッファ オーバーフロー エラーを検出するために使用する保護メカニズムによって発生します。たとえば、次のスニペットでは次のようになります。
#include <stdio.h>
void func()
{
char array[10];
gets(array);
}
int main(int argc, char **argv)
{
func();
}
コンパイラ (この場合は gcc) は、既知の値を持つ保護変数 (カナリアと呼ばれる) を追加します。入力文字列のサイズが 10 を超えると、この変数が破損し、SIGABRT によってプログラムが終了します。
洞察を得るには、 -fno-stack-protector
コンパイル時にオプションを使用して gcc のこの保護を無効にしてみてください。その場合、不正なメモリ位置にアクセスしようとしているため、おそらくセグメンテーション違反などの別のエラーが発生します。-fstack-protector
これはセキュリティ機能であるため、リリース ビルドでは常にオンにする必要があります。
デバッガーを使用してプログラムを実行すると、オーバーフローのポイントに関する情報を取得できます。Valgrind はスタック関連のエラーには対応していませんが、デバッガーと同様に、クラッシュの場所と原因を特定するのに役立つ場合があります。