0

昨日、C で簡単なコードを実行すると、CVI がバッファ オーバーフローを検出できることがわかりました。

void main(void)
{
int a[10];
int buf[10];    
int test[10];
int *p = &buf[10];
*p = 1;
while(1);
}

このプログラムを実行できると、エラーが発生します。メッセージは「配列の末尾から 1 バイト (1 要素) 先の境界外ポインターの逆参照です」(画像の投稿を許可されていないため、申し訳ありません)

C/C++には組み込みの配列境界がないことを知っているので、実装方法が非常に混乱しています。VC++6.0 や Linux などの他のプラットフォームでも試してみましたが、誰もオーバーフローを検出できません。ありがとうございます。

4

1 に答える 1

-1

私は LabWindows/CVI を使用したことはありませんが、それについての簡単な議論から、コンパイル時ではなく、実行時にこの範囲外の逆参照を検出したと推測しています。静的コード分析 (ソフトウェアを実行せずにコンパイル時に実行できる正確性チェック) は、キャッチできるエラーの種類が限られています。あなたの単純な例では、コンパイラはおそらくこのエラーをキャッチできますが、大規模なプログラムに入る可能性のある入力のすべての組み合わせのデータフローをトレースすることは、最も強力なプログラムであっても扱いにくい問題になるため、一般的なケースではこのようなエラーをキャッチできません。たとえ何百年もの間、問題を噛み砕くために放置されていたとしても。

一般的なケースでこの種の問題を検出できる唯一の方法は、動的プログラム分析によるものです。ランタイム境界チェックでコード自体を自動的に計測するか、すべてのメモリ割り当ての境界を追跡して検証するシミュレーターを介してコードを実行します。それらの境界に対するすべてのアクセス。前者の戦略の実装例は Ada プログラミング言語で、ミッション クリティカルな安全性がパフォーマンスよりもはるかに重要であると考えられています。しかし、Ada の場合、言語はそのようなチェックを許可するように設計されています。C または C++ 言語の実装は、おそらく同様のことを行うことができますが、言語に生のポインターが存在すると、それがより困難になり、実行時間が非常に高くなる可能性があります。

C および C++ で、この種のランタイム境界チェック (テストのみ) が必要な場合は、Valgrind を調べることができます。境界外アクセスの捕捉において、これほど徹底したツールを他に知りません。ただし、プログラムの実行が非常に遅くなることに備えてください。おそらく LabWindows/CVI は Valgrind に似ていますか?

いずれにせよ、使用する検証ツールに関係なく、実行時の境界チェックでバグのあるコードをキャッチする唯一の方法は、境界外の動作を引き起こすプログラムに入力を与えることであることに注意する必要があります。どの検証ツールからでも境界チェックの失敗がないことは、プログラムにそのようなバグがないという決定的な指標ではありません。

于 2013-08-24T05:16:04.977 に答える