全体として、KLEE は学術研究用の非常に優れたシンボリック実行エンジンになるはずです。実際に使用する場合、次の側面によって制限される可能性があります。
[1] KLEE の LLVM IR インタープリターが使用するメモリ モデルは、メモリと時間を消費します。実行パスごとに、KLEE はプライベートな「アドレス空間」を維持します。アドレス空間は、ローカル変数の「スタック」と、グローバル変数および動的に割り当てられた変数の「ヒープ」を維持します。ただし、各変数 (ローカルまたはグローバル) は、MemoryObject オブジェクトにラップされます (MemoryObject は、開始アドレス、サイズ、割り当て情報など、この変数に関連するメタデータを保持します)。各変数に使用されるメモリのサイズは、元の変数のサイズに MemoryObject オブジェクトのサイズを加えたものになります。変数にアクセスする場合、KLEE はまず「アドレス空間」を検索して、対応する MemoryObject を見つけます。KLEE は MemoryObject をチェックし、アクセスが正当かどうかを確認します。もしそうなら、アクセスが完了し、MemoryObject の状態が更新されます。このようなメモリ アクセスは、明らかに RAM よりも低速です。このような設計は、シンボリック値の伝播を容易にサポートできます。ただし、このモデルは、テイント分析 (変数の記号状態のラベル付け) から学習することで単純化できます。
[2] KLEE にはシステム環境のモデルがありません。KLEE でモデル化された唯一のシステム コンポーネントは、単純なファイル システムです。ソケットやマルチスレッドなど、その他のものはサポートされていません。プログラムがこれらのモデル化されていないコンポーネントへのシステム呼び出しを呼び出すと、KLEE は (1) 実行を終了してアラートを生成するか、(2) 呼び出しを基盤となる OS にリダイレクトします (問題: シンボリック値を具体化する必要があり、一部のパスは異なる実行パスからのシステム コールが互いに干渉する可能性があります)。これが、前述の「スレッドを知らない」理由だと思います。
[3] KLEE はバイナリに対して直接作業することはできません。KLEE には、テストするプログラムの LLVM IR が必要です。一方、BitBlaze プロジェクトの S2E や VINE などの他のシンボリック実行ツールはバイナリで動作します。興味深いことに、S2E プロジェクトは、シンボリック実行エンジンとして KLEE に依存しています。
上記の回答に関して、私は個人的にさまざまな意見を持っています。まず、KLEE が大規模なプログラムを完全に処理できないのは事実ですが、どのシンボリック実行ツールが可能でしょうか? 経路の爆発は、技術的な問題というよりも、理論的な未解決の問題です。第 2 に、前述したように、KLEE はそのメモリ モデルが原因で実行が遅くなる可能性があります。ただし、KLEE は実行を無駄に遅くするわけではありません。保守的にメモリの破損 (バッファ オーバーフローなど) をチェックし、実行されたパスごとに一連の有用な情報をログに記録します (パスをたどる入力の制約など)。さらに、超高速で実行できる他のシンボリック実行ツールを知りませんでした。第三に、「浮動小数点、longjmp/setjmp、スレッド、asm; 可変サイズのメモリ オブジェクト」は単なるエンジニアリング作業です。例えば、http://srg.doc.ic.ac.uk/files/papers/kleefp-eurosys-11.pdf )。第 3 に、KLEE では、シンボリック変数にラベルを付けるために、プログラム上でインストルメンテーションを必ずしも必要としません。前述のように、シンボリック値はコマンド ライン経由でプログラムに入力できます。実際、ユーザーはファイルをシンボリックに指定することもできます。必要に応じて、ユーザーは単純にライブラリ関数をインストルメント化して入力をシンボリックにすることができます (一度だけ)。