2011-01-04 9 views
15

大規模なプロジェクトに取り組んでいますが、一般的にうまく動作しますが、入力データサイズが制限を超えると深刻な問題が発生します。Cプログラムで(すべての)整数オーバーフローを見つける方法は?

これらの問題であるが、(疑われる)のみによる符号付き整数にこのようなオーバーフロー:

明らか
int a, o; 
// Initialize a and o 
int x = (a+o) >> 1); 

、およびOオーバーフロー(2^31-1より大きくなる)の和と、Xはノーaとoの平均を長くします。

実行中のプログラムでこれらの整数オーバーフローをすべて見つける一般的な方法はありますか?

私はValgrindやGDB拡張のようなツールを考えていますが、すべての整数算術命令でブレークし、パラメータをとり、正しい結果(より大きいサイズのデータ​​型または任意精度の算術で計算されたもの)を実際の結果と比較します。結果が異なる場合は、警告を出力するか、デバッグブレークをトリガするか、このようなものを出力する必要があります。

私は、オーバーフローのための単一の算術命令をチェックする方法を知っています(例えば、加算の符号をチェックするなど)。しかし、膨大な量のコードのために、プロジェクト全体をチェックし、コードを手でどこにでも置くことができます。

答えて

3

Coverityが良いですツール。私はそれがall整数オーバーフローを検出するかどうかはわかりませんが、試してみる価値があります。

2

すべてのコードを実行し、ユーザー入力の制限と入力を検証する必要があります。また、オーバーフローの問題を減らすためにいくつかのアルゴリズムを書き直す必要があるかもしれません。

あなたが指定した例は負の値では機能しませんが、とにかくunsigned intを使用する必要があります。

編集: gccが-ftrapvオプションがありますが、このは通常、実際には何ものみ-O0で動作を行いません。オーバーフローが発生したときにトラップする方法を取っている場合は、コードを完全にテストするためにコードの知識が必要です。

+0

私はおおまかに言えば、ユーザーの入力にはどのような制限がありますか。コードを処理する際の問題は、プロジェクトには200k行(私が書いたものではない199k)があり、オーバーフローする可能性のあるコードを手動でチェックすることはかなり恐れていることです。 – ChrisM

+0

@ChrisM - 誰かが書いたコードを信頼できない立場にいるなら、おそらくそれを使うべきではないでしょう。このような事柄(レビュー、テストなど)に対処するためのビジネス慣行が取られるべきである。このコードを使用しているだけで、周囲に誰もいない場合は、とにかくそれを読み終えるのに少し時間を費やす必要があります。 – OrangeDog

+0

さて、それは残念です。私は、問題のあるセクションをコード内で(おそらく十数個、あるいはそれ以上)見つけることができればと期待しています。 – ChrisM

0

どのようにコードを経由して置き換えるスクリプトに関するすべての "A + B" DEBUGADDと(a、b)は - あなたが行うことができる場所:大規模なコードベースの場合

#ifdef DEBUG 
int addFn(int a, int b) { 
    long long m; 
    int n; 
    m = (long long)a + (long long)b; 
    n = a + b; 
    if (m != (long long)n) 
    printf("PANIC!\n"); 
    return n; 
} 
#define DEBUGADD(a,b) addFn(a,b) 
#else 
#define DEBUGADD(a,b) ((a)+(b)) 
#endif 
+3

あなたのスクリプトが空白、キャスト、操作の順序、および戻り値の型を正しく処理していることを確認してください:) – Karmastan

+0

「assert((a <= 0)||(b <= INT_MAX -a))&&同様の式が 'long'と' long long'でも有効なので、a> = 0)||(b> = INT_MIN-a))) ') – caf

関連する問題