ここから本文です

Linuxでのセグメンテーションエラーについて

onownbefbさん

2011/8/319:05:07

Linuxでのセグメンテーションエラーについて

プログラムのデバッグ作業をしていたのですが、セグメンテーションエラーで詰まってしまいました。
OSはWindows、開発環境はVC++です。
windowsの場合だと、確保していない領域に書き込んでも、エラーを出してくれなかったりするのでデバッグが難しいです。

しかしここで、Linuxならばセグメンテーションエラーに対しては必ずエラーを出してくれるという情報を聞きました。
そこで、開発環境をLinuxに移すことにしました。ところが、明らかにセグメンテーションエラーであるのに、エラーを一切吐き出してくれません。
今のLinuxはセグメンテーションエラーに必ずエラーを出してくれるというわけではないのでしょうか?
ちなみにLinixでの開発環境は以下の通りです。

OS: Ubuntu10.04(server版)
コンパイラー g++, icc

一応以下の簡単なコードでもテストしました。

#include<stdio.h>

int mani(){
int a[3];

a[10]=99;
printf("%d\n",a[10]);
return 0;
}

実行結果
99

a[10]は確保されていないのでエラーが出てほしいのですが・・・

閲覧数:
8,270
回答数:
4
お礼:
100枚

違反報告

ベストアンサーに選ばれた回答

編集あり2011/8/400:19:20

> windowsの場合だと、確保していない領域に書き込んでも、エラーを出してくれなかったりするのでデバッグが難しいです。
Linuxでも同じですよ。プロセスが確保していない領域に書き込んだら多くの場合エラーを出してくれるでしょうけど、あなたがC言語で配列を確保していないことはプロセスがメモリを確保していないことを意味しないし、そもそもC言語はもとより添え字の範囲を静的にも動的にもチェックしない言語です。しかたないから、静的/動的なチェッカを使うのですよ。

gcc は mudflap という動的チェック機構を内蔵しています。内蔵してるんだけど、ディストリビューションによってはそのコンパイル/実行に必要な補助ライブラリが別パッケージになってるだろうから、必要に応じて libmudflap-dev とかをインストールして使ってくださいな。

$ gcc a.c -Wall -fmudflap -lmudflap
$ ./a.out
*******
mudflap violation 1 (check/write): time=1312375766.383213 ptr=0x7fffd83b31e0 size=44
pc=0x7f71ecfb7cc1 location=`a.c:6:1 (main)'
/usr/lib/libmudflap.so.0(__mf_check+0x41) [0x7f71ecfb7cc1]
./a.out(main+0x90) [0x400a74]
/lib/libc.so.6(__libc_start_main+0xfd) [0x7f71ecc6bc4d]
Nearby object 1: checked region begins 0B into and ends 32B after
mudflap object 0xb50560: name=`a.c:4:5 (main) a'
bounds=[0x7fffd83b31e0,0x7fffd83b31eb] size=12 area=stack check=0r/3w liveness=3
alloc time=1312375766.383198 pc=0x7f71ecfb7431
number of nearby objects: 1
*******
mudflap violation 2 (check/read): time=1312375766.383972 ptr=0x7fffd83b31e0 size=44
pc=0x7f71ecfb7cc1 location=`a.c:7:1 (main)'
セグメンテーション違反です

ちゃんと、4行めのオブジェクト a に関する違反を二つ、6行め(a[10]=99)と 7行目(a[10]) で指摘してセグメンテーションフォールトでおちます。

メモリ関係なら伝統的な efence とか varglind とかのもっと大きなシステムもありますから、必要に応じて検討してみてくださいな。

質問した人からのコメント

2011/8/5 16:13:33

ご丁寧にありがとうごうざいました。ほかの方々の意見も大変勉強になりました。

ベストアンサー以外の回答

1〜3件/3件中

並び替え:回答日時の
新しい順
|古い順

ycos001さん

2011/8/423:24:07

質問の真意が分かりませんが、文面から察するとセグメンテーションエラーそのものではなく、メモリーリーク等の設計上の問題があり、それを特定するために環境を変えたという事でしょうか?
既にセグメンテーションエラーや各種コンパイル方法については、回答がいくつか投稿されているので上記の前提で投稿します。

単純な配列についてのチェックは難しいです。やはりコンパイルオプションの調整や efence などのツールが必要でしょう。
過去のプロジェクトでよくやった方法はとしては、malloc/free 相当の関数を作成しその中で上下限のチェック、初期化、解放の有無等をチェックしていました。動作が安定してくれば、オリジナルの malloc/free に定義しなおし、パフォーマンスに対応していました。
ありがちな手法ですが、ご参考まで。

参考URL
http://msdn.microsoft.com/ja-jp/library/dd313966.aspx

2011/8/415:13:39

linuxでも適切に設定を行わないとコアを出力しません。
以下の方法で確認してみてください。

# ulimit -a

core file sizeの欄が0になっていませんか?

# ulimit -c 1000000000(←許可するコアファイルのサイズ)

とするとコアを出力するようになります。
なお、記載されているコードではおそらくコア出力されません。
a[N]のNをもっと大きな値にしないと難しいでしょうね。

2011/8/400:30:48

関数内で定義された変数は、オート変数とか自動変数とか呼びますが、
スタック・セグメント上に、領域が、確保される変数です。

スタック・セグメントは、プログラムの起動時に、
システム所定の大きさだけ確保されますから、
その範囲内であれば、セグメンテーション・エラーにはなりません。

ただし、スタックに書き込むことは、
スタックに保存されている、情報が、破壊されることが、あるため、
プログラムの誤動作を招き、main () を呼んでいる、
さらに、上位の処理系の情報が、破壊されかねません。


10 ではなく、もっと、大きな数字にすれば、
重要な領域を破壊することも無く、
所望のエラーが、発生するはずです。

少しずつ大きくしていけば、セグメントの最終が、分かります。

あわせて知りたい

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問や知恵ノートは選択されたID/ニックネームのMy知恵袋で確認できます。